前言:
近期看了一下metasploit生成的reverse_tcp shellcode源码,突发奇想使用python3来编写一个自己的加载器,以便绕过杀毒获取一个metereter
一. Meterpreter 加载过程分析
meterpreter使用ReflectiveDllLoader技术,使其功能代码在内存中执行,不在硬盘留下文件。loader就是msf生成的shellcode,其作用是与控制端建立连接,并获取下一阶段所需的功能代码。由于功能代码采用了DLL反射加载技术,可以规避大多数杀毒软件。但是我们使用的loader很容易被查杀。因此我们可以用python编写一个免杀的加载器,来连接msf并加载功能dll。
打开metsrv的源码,在metsrv.c中可以看到
初始化需要一个socket的file descriptor,这里的fd参数就是负责反射加载这个dll的shellcode中传进去的。
查询资料得知,msf生成的reverse_tcp shellcode所使用的脚本路径在:
metasploit-framework/lib/msf/core/payload/windows/x64/reverse_tcp.rb
metasploit-framework/lib/msf/core/payload/windows/x64/block_api.rb
在reverse_tcp.rb中储存了生成reverse_tcp shellcode的ASM代码,如下图
如图,gennerate_reverse_tcp 用于生成shellcode,从这里可以得知,shellcode大致的三个主要功能:
1.#{asm_block_api} 通过hash获得api地址
2.#{asm_reverse_tcp(opts)} 与控制端建立连接
3.#{asm_block_recv(opts)} 接收控制端发来的数据信息
首先,查看asm_reverse_tcp 部分,发现它和msf控制端使用socket建立了连接
上图红框中的mov edi,rax,其作用是将socket描述符保存到rdi中,方便接下来的第二阶段代码使用。
如上图,在asm_block_recv中,先接收了一个由控制端发来的length,这个数值就是第二阶段接收的反射dll的大小,并使用该参数分配内存空间。
如上图,使用VirtualAlloc分配了一个内存空间,并将权限设置为PAGE_EXECUTE_READWRITE,确保接收到的反射dll能正常执行。
分配完成后,使用socket recv接收stage2到分配的空间中
接收完毕后,跳转到stage2执行,这时候我们就可以获得一个完整的meterpreter了。
二. 使用python3编写自己的加载器
我们分析了原版加载meterpreter的过程,接下来我们可以使用python实现这个过程,编写一个自己的加载器,来绕过杀毒的查杀。
1.在python中,我们需要使用ctypes库来调用windows API
kernel32 = ctypes.cdll.LoadLibrary("kernel32.dll")
kernel32.VirtualAlloc.restype = ctypes.c_uint64
2.在上文中,我们知道需要将socket描述符保存到rdi中。python中我们直接用硬编码实现该功能。mov rdi,立即数 对应的编码为 0x48 0xBF。
通过使用struct.pack,把python中的socket描述符转为一个QWORD数值,与0x48 0xBF组合,执行后就会将该socket描述符保存至rdi寄存器中。
3.接下来循环接收控制端发来的数据
4.复制到新分配的空间,并且创建新线程以执行
至此,我们可以获得一个完整的meterpreter会话
5.可以与pyinstaller配合使用,打包运行。
完整代码在附件喵
(运行环境win x64 python3)