春秋杯冬季赛day2 easy_http复现
字数 1640 2025-08-22 12:23:30
Easy_HTTP漏洞分析与利用教学文档
1. 题目概述
这是一个来自春秋杯冬季赛Day2的题目"easy_http",主要特点包括:
- 没有使用标准libc,所有libc函数都被重写且符号表被抹除
- 采用多进程架构,调试较为复杂
- 漏洞点本身简单但逆向难度大
- IDA反编译结果不准确,增加了分析难度
2. 题目功能分析
2.1 HTTP请求处理
程序实现了一个简单的HTTP服务器,主要处理流程:
-
请求解析:通过
getmessagefromheader函数解析HTTP请求头- 查找"POST"、"GET"、"HTTP/1.1"等关键字
- 提取Host、Content、Content-Length字段并存入全局变量
-
请求格式要求:
POST / HTTP/1.1 Host: example.com Content-Length: 100 Content: AAAAA... (实际内容)
2.2 关键函数分析
getmessagefromheader函数
- 通过字符串匹配查找关键字段
- 返回是否成功找到Host、Content、Content-Length
响应生成函数
- 生成HTTP响应头
- 包含一个会导致进程退出的函数调用
3. 漏洞分析
3.1 漏洞位置
漏洞存在于一个关键检查函数中,涉及以下变量:
v10[0]: 存储从Content-Length头获取的长度值v10[1]: 标志位,表示Host长度是否<=0x2fv12: 通过strlen获取的实际Content长度
3.2 漏洞成因
检查逻辑错误地使用了"||"运算符:
if (v10[0] <= 0xF0 || v10[1])
本意可能是:
if (v10[0] <= 0xF0 && v10[1])
这使得攻击者可以:
- 伪造Content-Length头使其大于0xF0
- 同时保持Host长度合规(v10[1]=1)
- 绕过长度检查导致栈溢出
3.3 溢出机制
后续的memcpy类函数将Content内容复制到栈缓冲区:
- 源缓冲区:Content内容
- 目标缓冲区:栈上的v13/v14
- 由于长度检查被绕过,可以写入超长数据导致栈溢出
4. 漏洞利用
4.1 信息泄露
利用show功能泄露canary:
- 发送精心构造的Content,覆盖canary最低字节的\x00
- 通过show功能读取被修改的canary
栈布局:
+-----------------+
| ... |
+-----------------+
| canary | <-- 可以被覆盖
+-----------------+
| ... |
+-----------------+
| v14 (content) | <-- show读取的位置
+-----------------+
4.2 ROP链构造
由于没有标准libc,需要直接使用syscall:
- 在.bss段写入"/bin/sh"
- 构造execve系统调用:
- rax=59 (execve)
- rdi="/bin/sh"地址
- rsi=0
- rdx=0
4.3 利用注意事项
-
路径匹配问题:
- 栈上某些地址被ROP覆盖会影响路径匹配
- 解决方法:使用较长的pop链保持栈平衡
-
请求格式:
- 必须以
\r\n结尾 - 否则会导致程序异常
- 必须以
5. 调试技巧
5.1 多进程调试
由于set follow-fork-mode parent无效,采用以下方法:
- 使用
ps -ax | grep attachment获取子进程PID - 附加到子进程进行调试
5.2 IDA反编译问题处理
- 对可疑函数进行动态调试确认功能
- 结合上下文和寄存器变化推断函数用途
- 重命名函数使其意义明确
6. 完整利用步骤
-
泄露canary:
- 发送精心构造的请求覆盖canary最低字节
- 通过show功能读取canary
-
构造ROP链:
- 计算必要gadget地址
- 布置execve参数
-
触发漏洞:
- 发送超长Content触发栈溢出
- 覆盖返回地址指向ROP链
-
获取shell:
- ROP链执行execve("/bin/sh", 0, 0)
- 获取交互式shell
7. 防御建议
-
修复漏洞:
- 将"||"改为"&&"进行严格检查
- 使用strlen获取的实际长度进行验证
-
增强防护:
- 启用栈保护(虽然本题已使用canary)
- 限制单个请求的最大长度
-
代码审计:
- 对关键安全检查进行重点审计
- 确保长度验证逻辑正确
8. 总结
本题展示了以下安全知识点:
- HTTP协议实现中的安全问题
- 长度验证不严谨导致的栈溢出
- 无libc环境下的ROP利用技巧
- 多进程应用的调试方法
- 对抗反编译不准确的逆向技巧