栈溢出从复现到挖掘-CVE-2018-16333漏洞复现详解
字数 1882 2025-08-29 22:41:24
CVE-2018-16333漏洞分析与利用教程
1. 漏洞概述
CVE-2018-16333是一个基于栈溢出的漏洞,存在于某IoT设备的web服务中。漏洞成因是web服务在处理POST请求时,对ssid参数直接复制到栈上的局部变量中,且没有进行长度限制,导致栈溢出。
2. 漏洞定位
漏洞位于form_fast_setting_wifi_set函数中,关键问题点:
- 程序获取ssid参数后,未经检查直接使用
strcpy函数复制到栈变量 - 存在两个连续的
strcpy操作,增加了利用复杂度
3. 漏洞分析
3.1 漏洞代码分析
IDA反汇编显示的关键伪代码:
char s[64]; // [sp+200h] [bp-7Ch] BYREF
char dest[64]; // [sp+1C0h] [bp-BCh] BYREF
char *src; // [sp+260h] [bp-1Ch]
3.2 栈布局分析
通过pwndbg调试获取的栈结构:
char s偏移量:0x7C (从栈帧基址FP向低地址方向偏移124字节)src指针偏移量:0x1C (从栈帧基址FP向低地址方向偏移28字节)dest偏移量:0xBC (从栈帧基址FP向低地址方向偏移188字节)
3.3 关键偏移量计算
src距离返回地址:0x20 (32字节)char s到src的偏移量:0x60 (96字节)dest到返回地址的距离:0xC0 (192字节)
4. 利用难点
由于存在两个strcpy操作:
- 第一次
strcpy(s, src)会覆盖src指针 - 第二次
strcpy(dest, src)使用被覆盖的src指针
因此需要精心构造payload,确保:
- 第一次溢出后
src指向一个可读地址 - 第二次
strcpy不会导致程序崩溃 - 最终能控制程序执行流
5. 利用过程
5.1 利用链设计
-
第一次strcpy(s, src):
- 目标:覆盖
src指针,使其指向可控地址 - 填充长度:96字节(
char s到src的距离) - 最后4字节:写入一个可读地址
- 目标:覆盖
-
第二次strcpy(dest, src):
- 通过被篡改的
src指针,向dest写入ROP链 - 需要覆盖返回地址,距离为32字节
- 实际填充:24字节(32-4-4,减去可读地址和返回地址本身)
- 通过被篡改的
5.2 关键地址获取
-
libc基址计算:
- 通过内存映射获取libc基址:0x3fdd1cd4
- 使用IDA打开libc.so.0,计算函数偏移量
-
关键函数地址:
system函数偏移量:0x5A270puts函数偏移量:0x35CD4
-
Gadget查找:
- gadget1:
pop {r3, pc}(地址: 0x00018298)- 功能:从栈顶弹出两个值,分别存入r3和pc
- 用途:控制r3寄存器的值并跳转
- gadget2:
mov r0, sp ; blx r3(地址: 0x00040cb8)- 功能:将栈指针sp的值赋给r0,然后跳转到r3
- 用途:传递参数并触发system()
- gadget1:
5.3 ARM调用约定
- 第一个参数通过r0传递
- 函数地址通常通过
blx r3跳转(r3存储目标地址) - 关键寄存器:
- r0:传递函数第一个参数
- r3:暂存函数地址
- pc:程序计数器,控制执行流
5.4 Payload构造
完整payload结构:
- 前96字节:填充数据
- 可读地址(4字节)
- 24字节填充("bbbb")
- ROP链:
- pop_r3地址(libc_base + 0x18298)
- system函数地址(libc_base + 0x5A270)
- mov_r0_ret_r3地址(libc_base + 0x40cb8)
- 要执行的命令字符串
6. 调试验证
调试关键点:
- 在第一个
strcpy函数前打断点(0x67070) - 在第二个
strcpy函数前打断点(0x67080) - 观察寄存器状态:
- R0:函数第一个参数
- R11(FP):当前栈帧基址
- SP:当前栈顶
- PC:下一条指令地址
验证栈空间:
- 从R0(0x408001e8)到0x40800248应被"aaaa"覆盖
- 0x40800248地址应指向libc可读地址
- ROP链应正确布置在栈帧基址开始的位置
7. 利用脚本注意事项
- 请求需要重复发送两次(程序可能不稳定)
response = requests.post(url, cookies=cookie, data=data) response = requests.post(url, cookies=cookie, data=data) - ARM架构为小端序,注意字节顺序
- 每个寄存器占用4字节,注意对齐
8. 总结
本漏洞利用的关键技术点:
- 精确计算栈偏移量
- 处理两次
strcpy的相互影响 - ARM架构下的ROP链构造
- 寄存器控制和参数传递
- 利用
strcpy实现内存写操作
通过精心构造的payload,最终可以实现任意命令执行,完成RCE(远程代码执行)。