<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>

    前塵—數據連接池下的至暗之處

    VSole2023-03-30 09:44:17

    前言

    這是分析Java反序列化系列的第四篇文章,內容的填充度已經過半。此系列的每一篇文章 都會對漏洞產生的原因進行剖析,理解事物的原理往往在攻擊時發揮奇效。

    C3P0是一個開源的JDBC連接池,它實現了數據源和JNDI綁定,支持JDBC3規范和JDBC2的標準擴展。目前使用它的開源項目有Hibernate、Spring等。

    序列化與反序列化

    既然是反序列化漏洞必然要提起的就是序列化與反序列化,如果還有讀者對這個概念不清楚請參考文章《前塵——與君再憶CC鏈》,在Java反序列化漏洞中,序列化和反序列化是理解這些漏洞的基本條件。

    導入Maven依賴

    <dependencies>
            <dependency>
                <groupId>com.mchangegroupId>
                <artifactId>c3p0artifactId>
                <version>0.9.5.5version>
            dependency>
        dependencies>
    

    此依賴為c3p0最新版本依賴,更新于2019年12月

    最新版本沒有修復此問題

    漏洞跟蹤

    直接進入網上公開的鏈條類打開就是一頓分析com/mchange/v2/c3p0/impl/PoolBackedDataSourceBase

    分析了這么多的漏洞鏈條,其實道理很簡單。將網上紕漏的漏洞類打開直接往下翻往下翻找到readObject()方法對其內容進行跟進就可以,三板斧直接一頓懟。

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
            short version = ois.readShort();
            switch(version) {
            case 1:
                Object o = ois.readObject();
                if (o instanceof IndirectlySerialized) {
                    o = ((IndirectlySerialized)o).getObject();
                }
                this.connectionPoolDataSource = (ConnectionPoolDataSource)o;
                this.dataSourceName = (String)ois.readObject();
                o = ois.readObject();
                if (o instanceof IndirectlySerialized) {
                    o = ((IndirectlySerialized)o).getObject();
                }
                this.extensions = (Map)o;
                this.factoryClassLocation = (String)ois.readObject();
                this.identityToken = (String)ois.readObject();
                this.numHelperThreads = ois.readInt();
                this.pcs = new PropertyChangeSupport(this);
                this.vcs = new VetoableChangeSupport(this);
                return;
            default:
                throw new IOException("Unsupported Serialized Version: " + version);
            }
        }
    

    獲取版本,使用switch case關鍵字做分支處理。這里拿到的version是1,所有走case1.

    Object o = ois.readObject();

    此語句反序列化出一個referenceSerialized對象,instanceof關鍵字用來測試一個對象是否為一個類的實例。com.mchange.v2.naming.ReferenceIndirector類中存在內部類ReferenceSerialized實現了IndirectlySerialized接口,所以類型比對通過。

    然后調用IndirectlySerialized類的getObject方法,但是ReferenceSerialized實現了IndirectlySerialized接口。所以實際使用多態的方式調用的是ReferenceSerialized的getObject方法

    ReferenceSerialized( Reference   reference,
                     Name        name,
                     Name        contextName,
                     Hashtable   env )
        {
            this.reference = reference;
            this.name = name;
            this.contextName = contextName;
            this.env = env;
        }
    

    在ReferenceSerialized構造函數中傳入四個值進行賦值

    public Object getObject() throws ClassNotFoundException, IOException
    {
            try
            {
                Context initialContext;
                if ( env == null )
                initialContext = new InitialContext();
                else
                initialContext = new InitialContext( env );
                Context nameContext = null;
                if ( contextName != null )
                nameContext = (Context) initialContext.lookup( contextName );
                return ReferenceableUtils.referenceToObject方法將( reference, name, nameContext, env ); 
            }
            catch (NamingException e)
            {
                //e.printStackTrace();
                if ( logger.isLoggable( MLevel.WARNING ) )
                logger.log( MLevel.WARNING, "Failed to acquire the Context necessary to lookup an Object.", e );
                throw new InvalidObjectException( "Failed to acquire the Context necessary to lookup an Object: " + e.toString() );
            }
        }
    

    如果contextName不為空則使用lookup,進行rmi觸發遠程調用,但是這里的contextName為空只能向下分析

    return中調用了ReferenceableUtils類的referenceToObject方法將構造函數中傳入的四個值當作參數傳入繼續跟進。

    reFerenceToObject根據Reference對象來獲取工廠類的名字,以及工廠類的地址,接著拿到類加載器,拿到appClassLoader(一般程序中類加載都用這個,它的上面還有jre核心類運行的加載(rt.jar)bootstrap classloader和擴展類加載ext classloader)

    接著就判斷工廠類地址是否為空,不為空則去遠程地址加載工廠類,這里用到了urlclassLoader,然后通過class.forname生成一個class 類型的實例,就加載到了工廠類,即我們的惡意字節碼類

    總結

    個人認為此個序列化漏洞大致了解即可,因為此依賴新的架構項目已經不被廣泛使用了,并且maven可以的看到最后一次更新在2019年。

    Java反序列化一直是一個老生常談的問題,理解這些原理性的知識可以更好的幫助我們找到執行鏈,你我終有一天也會發現理解事物的本質是如此重要。

    序列化連接池
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    C3P0是一個開源的JDBC連接池,它實現了數據源和JNDI綁定,支持JDBC3規范和JDBC2的標準擴展。
    Xray撿洞中的高頻漏洞
    2021-12-28 04:33:22
    用 X-Ray 刷洞發現一些出現頻率高的漏洞,把漏洞原理和利用方式稍作整理,按照危害排名,低危漏洞可以收集一些信息然后深度利用變高危。
    Set第三個參數過期時間單位是秒。然后這個Set中存在的就是網點還沒有攬收的件,這時候通過Count就會知道這個網點今天還有多少件沒有攬收。如果get,set兩次以上,建議用getall,setall。
    目前,多數項目會有多數據源的要求,或者是主從部署的要求,所以我們還需要引入mybatis-plus關于多數據源的依賴:。#設置默認的數據源或者數據源組,默認值即為master. true未匹配到指定數據源時拋異常,false使用默認數據源。表名注解,用于標識實體類對應的表。其說明如下,關于這些書寫,常規情況基本很少用到,不做多余解釋了:@Documented
    假設Mysql中canal_test庫下有一張表policy_cred,需要統計實時統計policy_status狀態為1的mor_rate的的變化趨勢,并標注比率的風險預警等級。?本次安裝的canal版本為1.1.2,Canal版本最后在1.1.1之后。server端采用MQ模式,MQ選用Kafka。服務器系統為Centos
    如果指定了一個類為final,則該類所有的方法都是final的。此舉能夠使性能平均提高50% 。因為對這些大對象的操作會造成系統大的開銷,稍有不慎,將會導致嚴重的后果。
    一般有運行nginx服務器的用戶組,nginx進程pid存放路徑,日志存放路徑,配置文件引入,允許生成worker process數等。#user administrator administrators; #配置用戶或者組,默認為nobody nobody。keepalive_requests 120;#單連接請求上限次數。
    神器 Nginx 的學習手冊
    2022-02-23 07:35:52
    Nginx 是一個高性能的 HTTP 和反向代理服務器,特點是占用內存少,并發能力強,事實上 Nginx 的并發能力確實在同類型的網頁服務器中表現較好。 Nginx 專為性能優化而開發,性能是其最重要的要求,十分注重效率,有報告 Nginx 能支持高達 50000 個并發連接數。 01 Nginx 知識網結構圖 Nginx 的知識網結構圖如下:
    是個抓取網絡數據包的庫,這么說可能還有點抽象,但是抓包工具大家可能都使用過。場景1:網絡流量分析對網絡設備流量進行實時采集以及數據包分析。場景2:偽造數據包不少網絡安全工具,需要偽造網絡數據包,填充上必要的協議字段后發送給對端設備,從而達到一些目的。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类