今天我们将看看以编程的方式把shellcode注入到磁盘上的PE可执行文件中,请注意我们仅仅只是在谈论exe文件,PE文件格式包括许多其他扩展(dll,ocx,sys,cpl,fon,…)。手动执行此操作非常简单,关键点在于需要确保PE的功能没有改变,以免引起怀疑。但手动注入往往不实用,你需要先复制一份PE,在你自己主机上更改它,然后替换目标机器中的该文件。为了简化这个过程,我创建了一个Subvert-PE程序,这个程序可以自动化重写一个PE可执行文件(x86&x64)。修补入口点的偏移,注入shellcode并将执行流返回到合法代码中。我喜欢把工具给一些有机会理解它如何工作的人使用。这篇文章比较侧重于审查PE格式的相关部分,在了解PE结构后,用Powershell修改它就只是小儿科了。
此帖子可能包含Microsoft官方文档中的信息/摘录/图像,这些信息在DMCA合理使用政策下提供。如果有人对此有任何问题,请给我发电子邮件。
链接:
[Microsoft Official PE-COFF Documentation (MSDN)]
[Portable Executable (Corkami)]
工具:
PE 头
学习新知识的最好的方式是有一个具体的例子。为了在实践中奠定基础,我们将一步步地完成32位notepad++的PE头。PE头通常包括以下组件:MS-DOS头,富签名,PE头,可选头和表分区。
我不会为每个section高亮所有有意义的WORD/DWORD/QWORD,因为这是一个粗略的概述。
MS-DOS头:
在这个例子中,DOS 头从映像的底部(0×00)一直延伸到0x7F(127字节)。
在这里需要记住的重要东西是,在偏移位置0x3C(60字节)处,是一个提供实际PE头偏移位置的DWORD。PE头的偏移位置不是固定不变的,它会随着二进制程序的变化而变化。当然,对那些感兴趣的人,静态”MZ”标识符对应于MS-DOS开发人员之一Mark Zbikowski(首字母)。
富签名(Rich Signature):
在这里提到富签名主要是由于好奇。尽管PE格式已经有很久的历史(window3.1 – 1993),这一部分已经被微软取消文档记录(停止支持)。简而言之,它存储有关PE编译的数据。有关深入概述,可以在[NTCORE](http://www.ntcore.com/files/richsign.htm)阅读Daniel Pistelli的分析.
PE头:
PE头由ASCII签名和标准COFF文件头组成,应该注意到在富签名和PE头之间存在空字节填充。对于Notepad++而言,填充的大小为0x0F(15字节),但是大小因PE而的不同而改变。
下面提供了更完整的图片,你可以找到所有有关”机器类型(Machine Type)”和”特征(Characteristics)”的可能的值。这些都来自微软的官方文档。
可选标头:
可选标头向加载程序提供一些加载信息,这一部分仅是可选的,通常它不存在于对象文件中。可选标头的大小是会变化的,在上方PE头中由可选标头大小表示。
许多部分没有高亮,如果想要了解更完整的概述请参阅微软官方文档和[Corkami的分析]下方的图片展示了所有可能的”Subsystem Type”(子系统值)字段值。