Fork me on GitHub

ShellCode分析


知识点

位置无关代码:PIC指不用硬编码地址来寻址指令或数据得代码,shellcode编写者应该使用位置无关代码来提高代码的兼容性。

识别执行位置:Shellcode再以位置无关方式访问数据时需要引用一个基质指针,用这个基址指针加上或减去偏移值,将使它安全访问shellcode中包含的数据,因此一个通用寄存器应该首先载入当前EIP值,作为基址指针来使用,但是指令指针不能之别被软件访问,无法汇编mov eax, eip指令,但是可以使用call/pop指令和fnstenv指令。

使用call/pop指令:当一个call指令被执行使,处理器将call后面的指令地址压倒栈上,然后请求转到被请求的位置执行,这个函数执行完成后会执行一个ret指令,将返回地址弹出到栈的顶部,并将它载入EIP寄存器中,这样的结果使执行刚好返回到call后面的指令。因此shellcode可以通过call后面紧跟一个pop的方法来得到call后指令指针的方法。

使用fnstenv指令:x87浮点单元(FPU)再普通的x86架构中提供给了一个隔离的执行环境,它包含一个单独的专用寄存器集合,当一个进程正在使用FPU指令浮点运算时,这些寄存器需要由操作系统再上下文切换时保存,fnstenv使用一个28字节的结构体存储FPU状态到内存中,有一处字符偏移量为12fpu_instruction_pointer会保存FPU使用的最后一条的CPU指令的地址,并为一场处理器标识哪条FPU指令可能导致错误上下文信息,需要这个域是因为FPU是与CPU并行运行的,如果FPU产生了一个异常,一场处理器不能简单地通过参照中断返回地址来标识这个错误的指令。

手动符号解析:shellcode 不能使用Windows加载器来确保所有的库加载并可用,它必须自己解决外部符号依赖,因此它经常使用LoadLibrarayA和GetProcAddress函数。因此shellcode需要完成

  • 在内存中找到kernel32.dll
  • 解析kernel32.dll文件,并搜索以上两个导出函数。

在内存中找到kernel32.dll:

一旦找到了上图中kernel32.dll的基地址DllBase,通过跟踪内存中的几个结构体来解析kernel32.dll的符号。当定义一个文件内的位置时,PE文件使用RVA,导出数据被保存在IMAGE_EXPORT_DIRECTORY中,一个相对于IMAGE_EXPORT_DIRECTORY的RVA被保存在IMAGE_OPTIONAL_HEADER末尾部分的IMAGE_DATA_DIRECTORY结构体数组中。IMAGE_DATA_DIRECTORY数组的具体位置取决于这个PE文件是32位还是64位的。假设shellcode运行在32位平台上,所以在编译时从PE特征值域到IMAGE_DATA_DIRECTORY正确偏移的计算方式如下:

1
sizeof(PE_Signature)+sizeof(IMAGE_FILE_HEADER)+sizeof(IMAGE_OPTIONAL_HEADER)=120字节

下图是IMAGE_EXPORT_DIRCTORY结构体中的相对域,AddressOfFunctions是一个RVA的数组,指向实际导出的函数。

按照如下步骤可以找到一个符号的导出地址:

  • 迭代AddressOfNames数组查看每一个char *项,然后和需要的符执行一个字符串比较,直到找到一个匹配的项,我们将这个AddressOfNames的索引称为AddressOfName iName
  • AddressOfNameOrdinals数组中使用iName的索引,获取的值就是iOrdinal值。
  • 使用iOrdinal索引到Address OfFunctions数组,获取到的值是被导出符号的RVA,最后将这个值返回给请求者。

使用散列过的导出符号名:当使用对每一个导出函数进行strcmp对比直到找出正确的函数名不适用shellcode大小受限的情况,shellcode大小受限时可以使用散列过的导出函数名来缩小shellcode大小。

空指令雪橇:nop指令0x90,但是有的编写者为了避免检测也会使用0x40~0x4f之间的值作为空指令。

shellcode编码:有的程序可能会对shellcode的编码有一定的需求,不能出现坏字符如在字符串中出现0x00,或者要求所有字符都是可打印的(小于0x80)等,要绕过这些限制首先需要对shellcode进行编码,然后再shellcode中插入一个解码器,要保证解码器本身也能通过限制。下面时常用的编码技术:

  • 用常量字节掩码来XOR所有的载荷字节。
  • 使用字母变换将一个字节分割成4个比特然后域一个可打印的ASCII字符相加等。

课后练习

Lab19-1

使用shellcode_launcher.exe,分析文件。

问题

1.这段shellcode时如何编码的?

2.这段shellcode手动导入了哪个函数?

3.这段shellcode和哪个网络主机通信?

4.这段shellcode再文件系统上留下了什么迹象?

5.这段shellcode做了什么?

Lab19-2

文件Lab19-02.exe中包含一段shellcode,这个shellcode会被注入到另外一个进程并运行,请分析这个文件

问题

1.这段shellcode被注入到什么进程中?

2.这段shellcode位于哪里?

3.这段shellcode时如何被编码的?

4.这段shellcode手动导入了哪个函数?

5.这段shellcode和什么网络主机进行通信?

6.这段shellcode做了什么?

Lab19-3

问题

1.这个PDF中使用了什么漏洞?

2.这段shellcode是如何编码的?

3.这段shellcode手动导入了哪个函数?

4.这段shellcode再文件系统上留下了什么迹象?

5.这段shellcode做了什么?


本章结束🎊

您的支持是我最大的动力🍉