| 关键词: 内存 调用 dll 使用 shellcode 注入 NULL 函数 我们 写入 |
引言本文主要介绍“反射型dll注入”及“柔性加载”技术。 反射型dll注入为什么需要反射型dll注入常规的dll注入代码如下: 主要做了几件事情:
这样的操作模式有几个很高危的点。首先,从磁盘读取dll需要考虑dll的静态免杀,对此我们可以直接写在装载器中并加密。 其次,在目标内存中找到LoadLibraryW函数,需要GetProcAddress LoadLibraryW,这种调用属于很有特征的调用模式,容易被AV/EDR归类。对此我们的解决措施就是接下来要提及的反射型dll注入技术。 最后,CreateRemoteThread进行远程线程注入 行为本身就很高危,同时参数是LoadLibraryW的地址,一眼malware。 对此我们优化调用,不再使用CreateRemoteThread进而使用创建新进程的方式结合反射型dll注入技术改变dll注入技术的调用模式。 实现思路早期的dll注入实现原理: 上图比较清楚的写了反射型dll注入的原理,1,2,3步由A向B线程写入dll。第四步调用B线程中的embedded bootstrapper code。最后通过bootstrapper shellcode调用dll的导出函数reflective loader。 reflective loader实际上是一个自己实现的LoadLibraryW函数,从内存中找到我们写入的dll并修复使其成为可以被正常使用的pe文件,最后调用DLLmain实现我们的恶意功能。 我们的具体实现和上面早期的思路有所区别,首先我们不使用远程进程/线程注入的方式,其次我们不需要bootstrapper shellcode这个部分,我们可以直接在加载器部分算出reflective loader在内存中的地址,直接调用即可。
具体实现加载器部分首先shellcode使用AES解密,这部分添加了一些c的代码加密 后来发现原本项目的release目录下有python的加密脚本: 解密载入内存后,使用GetReflectiveLoaderOffset计算出ReflectLoader函数的偏移: 最后创建线程调用ReflectLoader函数。 dll部分ReflectiveLoader一共做了5件事: 一、 解析加载DLL所需kernel32.dll WINAPI的地址(例如VirtualAlloc, LoadLibraryA等), 遍历内存进行搜索: 二、 将DLL及其相应的节写入内存中: 三、 建立DLL导入表,以便DLL可以调用ntdll.dll和kernel32.dll WINAPI 四、 修复重定位表: 五、 调用DLL的入口点: 最终我们的恶意代码位于dllmain中,项目还是采用加载shellcode的方式上线cs。 柔性加载限制使用具有RWX标记的内存,cs在4+可以直接进行相关配置。 推荐配置: 牛刀小试360使用base64+xor混淆shellcode: 成功bypass: 火绒和上述方法相同: definder加强shellcode的混淆: 依旧报毒,但是类型发生改变了,说明静态的混淆有效果: |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|