首页
社区
课程
招聘
[原创]PE2Shellcode
发表于: 2017-3-2 14:32 6658

[原创]PE2Shellcode

2017-3-2 14:32
6658


解决什么问题:

解决功能性shellcode开发中的某些限制:不能使用静态变量,不能使用全局变量,不能使用字符串,不能使用虚类。

PE2Shellcode解决方案可以缓解shellcode开发中的这些限制,让shellcode开发能够更为快速方便。

 

不能解决什么问题:

PE文件中导入表未被处理,使用者要么进行二次开发,在shellcode前处理导入函数,要么在开发前消除PE文件的导入表。

CRTC runtime)函数系列.大量的C语言标准库函数都会在其内部分配和释放内存,这会破坏shellcode的内存环境,所有的CRT函数要么自行重写,要么不再使用。

 

原理:

shellcode开发中不能使用静态变量,全局变量和字符串等等限制的原因,是这些代码在生成机器码的过程中,没有值写入,只有地址写入。在PE文件加载的时候,WindowsPE加载器再重新对这些数据地址进行重写。

这个小工具的原理就是在提取PEshellcode基础上,再对shellcode进行重定位处理。

 

说明:

仅适用于32位程序。

没有测试过图像界面,不确定资源段内容是否能够被释放。

代码中的静态变量、全局变量、字符串地址在下面的文档中都被称为全局变量——从shellcode的视角来看,他们都是同一类代码。

 

基础:

PE文件结构。

《加密解密》

http://drops.wooyun.org/tips/8361

python基础

pefile

 

0步:PE文件的要求

 

  • 重载全局的newdelete操作符,使用HeapAlloc函数替换
  • 不能使用异常,包括c++异常和WindowsSEH.
  • 不能使用运行时分配内存的全局变量。所有的全局变量都要在编译时确定值。
  • 不能包含自定义区段
  • 编译选项:
    • /GS- 禁止栈保护
    • no c++ exception,关闭C++异常
    • /Gy,函数级链接
    • /Oi,意义不明
    • /O1,最小化代码
    • /MT,运行时库
    • /arch:IA32 仅使用I686指令集
  • 链接选项:
    • No Debug Info
    • /SAFESEH:NO
    • Function       Order:order.txt  链接时要求将入口函数放在.text段的开始部分
    • /MAP:map.txt map文件用于查看二进制文件的地址和符号表
    • /OPT:REF
    • /OPT:ICF 以上两项原理不明

 

 

第一步:处理PE(SECTION)表(sections_list函数)

PE重定位表指向的数据可能在PE的任何一个段上,因此第一步就是要处理段表。

将所有的段表放入all_sections中,保存了段表的以下信息:数据,磁盘文件长度,内存长度。

PE段表信息中的内存长度比较特殊,它是一个被我们计算出来的值。指该段在Shellcode内存中的长度。

段表长度会和未初始化的全局变量和静态变量相关,因此需要手动确认长度。

段表的section.SizeOfRawData指明了磁盘文件长度对齐内存后的长度。section.VirtualAddress则指明了该段未对齐内存时的长度。我们取两者较大的值作为该段在Shellcode的长度。

 

第二步:将段表合成一个段数列(sections_list),并记录其在段数列的偏移(sections_list函数)

.text段放在最前面,保证shellcode在运行是能够运行到我们的目标代码,然后依次将其他段放在后面。

每个段在sections_list的长度是按照其['mem_size']来确定的。对于长度不够的情况,在后面添加\x00.如前所述,这是为了保证未初始化的全局变量也在内存中有一席之地。

 

 第三步:重写将PE的导入函数地址

在实际的应用中,建议在生成PE文件前,在代码中消除导入表。使用汇编动态加载导入表比较困难。

 

第四步:获得重定位表信息(reloc_process函数)

这是整个工具核心的一部。首先看看PE的重定位信息是如何工作的:

 

 

图中.RELOC段有两个项目,第一个项目062h表示重定位项目在文件偏移。它指向的位置是一个4字节的地址,

0x402002。这个地址表示PE使用基地址加载的情况下,需要重定位数据的内存地址。所有的重定位信息都只有地址没有长度,重定位的长度都是8字节(DWORD)。

如果PE没有在基地址加载,这个地址就要减去基地址得到rva,然后加上目前的基地址,获得运行时的新地址。

pefile库已经帮我们把.RELOC的项目地址转为了rva地址,可以直接读取而不需要额外的转换。

我们的目标是将reloc信息转为下面类似的形式:

 

 

 

这样就很明确了,这个函数需要把reloc段中的信息转为sections_list的偏移量,并把重定位的数据地址减去IMAGE_BASE.

首先是获得重定位项在Sections_list的偏移量:将reloc指向的va减去IMAGEBASE得到rva.找到该rva属于哪个区段,然后rva-区段start+区段在sections_list的起始偏移。

另一个需要获得的是重定位项所指的内存在sections_list的偏移量。重定位项目一定指示了内存中的某些东西,可能是值,可能是字符串。在PE结构被重新组织到sections_list的时候,这个地址在sections_list的偏移量也需要重写。获得地址的方式同上。

 

 

第五部:根据重定位表信息生成shellcode

生成shellcode需要几部分内容:sections_list,重定位项目在sections_list的偏移,重定位项指示的位置在sections_list的新位置。

sections_list中,将重定位项目指示的位置的数据逐个写到对应的位置。

 

shellcode的前面是一串loader

shellcode loader

 

    code = [

        0xE8, 0x00, 0x00, 0x00, 0x00,               #   CALL here

                                                    # here:

        0x5E,                                       #   POP ESI

        0x8B, 0xFE,                                 #   MOV EDI, ESI

        0x81, 0xC6, reloc_start_offset[0], reloc_start_offset[1], reloc_start_offset[2], reloc_start_offset[3],         #   ADD ESI, shellcode_start + len(shellcode) - here

        0xB9, reloc_size[0], reloc_size[1], reloc_size[2], reloc_size[3],               #   MOV ECX, len(relocs)

        0xFC,                                       #   CLD

                                                    # again:

        0xAD,                                       #   LODSD

        0x01, 0x3C, 0x07,                           #   ADD [EDI+EAX], EDI

        0xE2, 0xFA                                  #   LOOP again

                                                    # shellcode_start:

    ];

 

shellcode loadershellcode运行前的一段代码,负责从Shellcode尾部的重定位列表中,逐项将shellcode的重定位数据重写。

shellcode的尾部是重定位项目的偏移量。

 整个shellcode看起来是这样的:

|--loader--|----target code---|---reloc item list from begin--|

使用shellcode测试程序可以尝试运行该shellcode.


https://github.com/after1990s/pe2shellcode


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (6)
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
学习! 感谢楼主分享!
2017-3-2 14:35
0
雪    币: 1305
活跃值: (213)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
3
用起来。难度有点大,要求有点多。如果能像这个工具一样就好了http://bbs.pediy.com/thread-141055.htm
2017-3-2 16:05
0
雪    币: 144
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这个东西类似于壳
2017-3-2 16:51
0
雪    币: 37
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错不错
2017-3-3 13:15
0
雪    币: 45
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

感谢分享


最后于 2018-8-7 15:14 被zyla编辑 ,原因:
2017-3-12 21:17
0
雪    币: 45
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享!
最后于 2018-8-7 15:14 被zyla编辑 ,原因:
2017-3-12 21:54
0
游客
登录 | 注册 方可回帖
返回
//