很酷吧?现在在Shellcode代码起始处设下断点。转向“injectAllTheThings”调试进程,并运行程序。我们的断点被成功断下,如下图所示;现在我们可以步过代码,并分析这段代码的功能。
当我们调用“LoadLibrary()”函数时,我们的DLL文件成功加载,如下图所示。
太棒了~
我们的Shellcode代码将返回到之前保存的RIP地址处,“notepad.exe”进程将恢复执行。
完整代码请参阅源文件“t_suspendInjectResume.cpp”。
(7)反射DLL注入
我将StepheFewer(这项技术的先驱)的代码也整合到了这个“injectAllTheThings”工程中,同时还构建了一个反射DLL文件用于这项技术。注意,我们要注入的DLL文件必须使用适当的包含和选项来进行编译,这样它才能与反射DLL注入技术相匹配。
反射DLL注入技术通过将整个DLL文件复制到内存中的方式来生效,因此它避免了向进程注册DLL模块这一行为。所有的繁琐工作都已完成。要在DLL模块加载到内存时获取其入口点,我们只需要使用Stephen
Fewer的代码;他的工程中所包含的“LoadRemoteLibrary()”函数为我们完成这项工作。我们使用“GetReflectLoaderOffset()”函数来确定在我们进程内存中的偏移,然后我们将偏移加上目标/远程进程(即我们写入DLL模块的进程)的内存基址,将该结果作为执行起始点。
太复杂?好吧,可能有点儿;以下是实现上述过程的4个主要步骤。
1.将DLL文件头部写入内存
2.将每个区块写入内存(通过解析区块表)
3.检查输入表,并加载任何引用的DLL文件
4.调用DLLMain函数的入口点
相比于其他方法,这种技术有很好的隐蔽性,主要被用于Metasploit平台。
如果你想要了解更多,请前往官方GitHub库;还想要阅读Stephen http://www.harmonysecurity.com/files/HS-P005_ReflectiveDllInjection.pdf
还可以参阅“MemoryModule”项目的作者Joachim Bauch所写的“从内存中加载DLL文件”,以及一篇好文章“不调用LoadLibrary()函数‘手动’加载32位/64位DLL文件”。
代码
还有一些模糊复杂的注入方法,因此我未来将对“injectAllTheThings”工程进行更新。其中某些最有趣的技术包括:
•“双脉冲星”工具所用到的技术
•网友@zerosum0x0所编写的工具,使用SetThreadContext()和NtContinue()实现的反射DLL注入,详细描述参见网址:https://zerosum0x0.blogspot.co.uk/2017/07/threadcontinue-reflective-injection.html,可用代码详见网址:https://github.com/zerosum0x0/ThreadContinue。
以上我所描述的所有技术,都在一个单独的工程中实现了,我将其放在GitHub库中;其中还包括每种技术所需的DLL文件。为了便于理解,下表简单介绍了所实现的方法和具体用法。
需要说明的是,从安全角度出发,应该坚持使用injectAllTheThings_32.exe注入32位进程,或者injectAllTheThings_64.exe来注入64位进程;尽管你也可以使用injectAllTheThings_64.exe来注入32位进程。而实际上我并没有这样实现,但可能之后我会尝试一下,具体请参考以下网址:http://blog.rewolf.pl/blog/?p=102。参考网址中的技术基本上就是Metasploit平台上“smart_migrate”工具所用到的,详见网址:https://github.com/rapid7/meterpreter/blob/5e24206d510a48db284d5f399a6951cd1b4c754b/source/common/arch/win/i386/base_inject.c。
整个工程的代码(包括DLL文件)都在GitHub库中。代码以32位/64位环境编译,包含或不包含调试信息都可以。
参考
本文由 看雪翻译小组 木无聊偶 编译 转载请注明来自看雪社区