• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      基于混合分析的Java反序列化利用鏈挖掘方法

      2022-04-18 01:23:42武永興陳力波姜開達
      關(guān)鍵詞:污點序列化信息流

      武永興,陳力波,姜開達

      (上海交通大學(xué)網(wǎng)絡(luò)空間安全學(xué)院,上海 200240)

      0 引言

      2015年,Lawrence和Frohoff首先提出了Java反序列化漏洞。隨后,Breenmachine利用Java反序列化漏洞成功攻擊WebLogic、WebSphere、JBoss、Jenkins、OpenNMS等Java應(yīng)用,并實現(xiàn)了遠程代碼執(zhí)行。Fastjson、Jackson、Hessian、XStream 等第三方反序列化庫被爆出存在反序列化漏洞,在反序列化攻擊者可控的數(shù)據(jù)時可能會執(zhí)行攻擊者構(gòu)造的惡意代碼。攻擊者通常需要通過組合應(yīng)用中存在的代碼片段,即gadgets,形成反序列化利用鏈,才能挾持反序列化器的執(zhí)行控制流,達到執(zhí)行對應(yīng)危險操作的目的。因此,反序列化利用鏈是Java反序列化漏洞利用的關(guān)鍵,研究如何自動化挖掘Java反序列化利用鏈至關(guān)重要。

      序列化是指將Java對象轉(zhuǎn)換成字節(jié)序列、JSON字符串、XML字符串等,用于存儲、網(wǎng)絡(luò)傳輸?shù)?。反序列化是序列化的逆過程,將字節(jié)序列、JSON字符串、XML字符串等,轉(zhuǎn)換成Java對象。Java反序列化漏洞常見于RPC調(diào)用過程中,客戶端將參數(shù)對象序列化成字節(jié)碼,通過網(wǎng)絡(luò)傳輸給服務(wù)端,服務(wù)端將收到的數(shù)據(jù)反序列化成參數(shù)對象,然后調(diào)用相應(yīng)的處理函數(shù)。另一種常見的場景是對HTTP請求的參數(shù)進行反序列化,將用戶傳遞的JSON/XML格式的數(shù)據(jù)轉(zhuǎn)換成Java對象。按照反序列化的機制,Java反序列化器可以分為兩類,一類是基于bean,通過調(diào)用setter方法對field進行賦值;另一類是基于field,通過反射直接對field進行賦值。常見的基于bean的反序列化器有:Fastjson和Jackson。常見的基于field的反序列化器包括:JND(java naive deserialization)、XStream、Hessian。攻擊者根據(jù)反序列化器的特點,在類路徑中搜索合適的gadget,將這些gadget組裝成反序列化利用鏈。通過反序列化利用鏈可以挾持程序的控制流,執(zhí)行危險的代碼片段,達到執(zhí)行任意代碼的目的。由于反序列化是一項正常的功能,修復(fù)時不能簡單地關(guān)閉反序列化功能。因此,針對反序列化漏洞,常見的修復(fù)手段是將已知的利用鏈加到黑名單中。換言之,如果攻擊者能夠找到新的利用鏈,那么就可以繼續(xù)利用反序列化漏洞進行攻擊。

      然而在反序列化漏洞利用鏈的搜索中面臨以下3個方面的困難。

      首先,在反序列化的過程中用戶可以控制生成對象的類型和屬性,field實際對應(yīng)的類型可能是聲明類型的任意子類,從而造成所調(diào)用的函數(shù)不確定,需要排查所有子類情況。在確定被調(diào)函數(shù)的時候,可能要排查N倍的具體函數(shù)(N為實現(xiàn)方法的數(shù)量)。隨著調(diào)用鏈長度的增長,要排查的函數(shù)數(shù)量將呈指數(shù)性增長,導(dǎo)致搜索空間爆炸。

      其次,Java多態(tài)特性導(dǎo)致調(diào)用方法不確定,需要通過指針分析計算其實際運行中對應(yīng)的類型。但是,指針分析需要消耗大量計算資源。

      最后,當前整個JDK的代碼量已然十分龐大,以Java(1.8.0_171)為例,共有38 466個類和32 4595個方法。龐大的代碼數(shù)量,給自動化分析帶來巨大挑戰(zhàn)。

      與Java反序列化漏洞相關(guān)的工具大多是payload生成工具,如Marshalsec和Ysoserial,這些工具將已知的利用鏈封裝成payload,但不具備挖掘未知利用鏈的能力;同時,有一部分工業(yè)界的工具,如GadgetInspector,提供了自動化搜索gadget的能力,但其沒有進行指針分析,導(dǎo)致誤報率和漏報率都很高。當前學(xué)術(shù)界大多數(shù)的工作是關(guān)于如何檢測注入類漏洞,對于自動化挖掘Java反序列化利用鏈沒有探索過。

      綜上所述,針對序列化利用鏈搜索的空間十分大,人工審計難以覆蓋的現(xiàn)狀,提出一種能夠協(xié)助安全研究人員自動化挖掘利用鏈的方法是相當有必要的。針對該問題,本文主要貢獻如下。

      1) 提出了基于混合分析的Java反序列化利用鏈挖掘方法,設(shè)計并實現(xiàn)了在字節(jié)碼級別進行自動化分析挖掘Java反序列化利用鏈工具——GadgetSearch。

      2) 實驗表明GadgetSearch的誤報率和漏報率遠小于現(xiàn)有的工具GadgetInspector,并且利用GadgetSearch挖掘出1條Jackson未公開利用鏈、4條XStream未公開的JDK利用鏈和1條Hessian未公開的JDK利用鏈,申請分配了5個CVE(CVE-2021-39141、CVE-2021-39144、 CVE-2021- 39146、CVE-2021-39153、CVE-2021-43297)和1個CNVD編號(CNVD-2021-44381)。

      1 相關(guān)工作

      指針分析(pointer analysis)[1-4]是計算程序變量在運行期間可能指向的對象集合。Java多態(tài)的性質(zhì),需要根據(jù)變量運行時指向?qū)ο蟮念愋徒馕霰徽{(diào)用函數(shù),所以指針分析是其他分析的基礎(chǔ)。Bravenboer[5]等提出了一種聲明式指針分析框架Doop,他們通過在Datalog中描述完整的端到端分析,并使用專門針對遞歸的Datalog程序進行優(yōu)化,推動了聲明式指針分析的發(fā)展。Antoniadis[6]等將Doop中的Datalog推理引擎從LogicBlox換成了Souffle ,Souffle支持通過共享內(nèi)存并行分析,切換推理引擎之后,Doop整體提速 4倍。

      污點分析(taint flow analysis)[7-11]是信息流分析(information flow analysis)的一種。Livshits[12]等探索使用Datalog進行污點分析,但沒有將該污點分析與指針分析統(tǒng)一起來。Tripp[13]等認為污點分析是一個需求驅(qū)動問題,不需要進行完整的全程序分析,他們提出了一套名為Andromeda的工具,利用數(shù)據(jù)流方程和污點集進行數(shù)據(jù)流分析。FlowDroid[14]是一種Android應(yīng)用污點分析框架,可以進行流敏感(flow-sensitive)的污點分析。FlowDroid對常見的Android特性(如回調(diào)等)進行了建模,并且手工篩選出了700多條Source、Sink以及轉(zhuǎn)移函數(shù)。這些轉(zhuǎn)移函數(shù)包含了常見數(shù)據(jù)結(jié)構(gòu)的操作。但是FlowDroid沒有將信息流分析和調(diào)用圖構(gòu)造統(tǒng)一起來。Pidgin[15]通過程序依賴圖(program dependence graph)的方式實現(xiàn)了信息流分析。程序依賴圖可以被用來模擬任何形式的數(shù)據(jù)以及指令之間的控制依賴。DroidInfer[16]使用約束流圖的可達性算法進行污點分析,它依靠WALA8在進行主要分析之前產(chǎn)生一個控制流圖。

      Grech等提出了P/Taint[17],將指針分析和污點分析結(jié)合起來,他們通過很小的改動把信息流分析整合到了Doop指針分析框架。通過擴充堆對象的定義域來實現(xiàn)這一目標,并增加污點分析的內(nèi)容。程序分析通常將污點分析和指針分析視為不同的過程,但該項工作表明,同樣的算法可以同時計算污點信息和指針信息這兩種相互關(guān)聯(lián)但獨立的信息。同時,由于反序列化漏洞的污點源不是來自Source函數(shù),而是來自隱式創(chuàng)建的對象,無法直接利用Doop的信息流分析功能來跟蹤反序列化的污點數(shù)據(jù)流。

      Dahse[18]等介紹了PHP反序列化漏洞,他們提出了一個過程間字段敏感和對象敏感的數(shù)據(jù)流分析方法,利用該方法自動化挖掘PHP反序列化利用鏈。Shcherbakov[19]等研究了.NET中的反序列化漏洞。他們先將.NET字節(jié)碼轉(zhuǎn)換成.NET通用的中間語言;然后實現(xiàn)了一個高效、可擴展的過程間污點分析;最后基于該方法實現(xiàn)了自動化挖掘.NET利用鏈工具SerialDetector。由于他們的方法只針對PHP和.NET這兩種特定語言,無法直接應(yīng)用到Java反序列化利用鏈的挖掘。

      JackOfMostTrades在BlackHat上介紹了一款挖掘利用鏈的工具 GadgetInspector[20]。GadgetInspector利用ASM庫解析字節(jié)碼,通過模擬操作棧實現(xiàn)污點分析,支持JND、XStream,Jackson這3種反序列化利用鏈的挖掘。杜笑宇等[21]將GadgetInspector中的廣度優(yōu)先搜索算法改造成了深度優(yōu)先算法,找到了一些新的利用鏈。Threedr3am對GadgetInspector進行了改造,增加了對 Fastjson和 Hessian的支持。但是GadgetInspector構(gòu)造調(diào)用圖時沒有進行指針分析,導(dǎo)致調(diào)用圖不準確,包含大量不存在的調(diào)用關(guān)系,誤報率和漏報率非常高。

      2 研究動機

      通過分析Java反序列化器的實現(xiàn)可知,Java反序列化漏洞能被利用的原因包含以下3點。反序列化的數(shù)據(jù)用戶可控,用戶能夠控制對象的類型以及其屬性值;反序列化器在反序列化的時候會自動調(diào)用入口函數(shù);類路徑(包括JDK和第三方庫)中存在合適的gadget,通過構(gòu)造將gadget串成一條鏈,從自動調(diào)用的入口函數(shù)開始鏈式調(diào)用到危險函數(shù)。

      從上述原因中,可以提取出反序列化漏洞利用環(huán)節(jié)的三要素。污染源:攻擊者可控的變量;入口函數(shù):反序列化時自動調(diào)用的接口函數(shù);危險函數(shù):能夠執(zhí)行命令的函數(shù)。

      因此,挖掘反序列化利用鏈首先需要根據(jù)反序列化器的實現(xiàn),分析出入口函數(shù)和污點源;然后從入口函數(shù)開始,根據(jù)聲明類型初始化污點源,跟蹤污點傳播。同時在追蹤的過程中,會遇到新的函數(shù)調(diào)用,這時通過指針分析,解析其真實的調(diào)用,進行過程間污點傳播分析,判斷污點數(shù)據(jù)能否傳播到危險函數(shù)。

      下面將根據(jù)圖1所示的反序列化利用的示例,解釋尋找Java反序列化利用鏈的詳細過程。

      圖1 反序列化利用鏈示例 Figure1 Example of a gadget chain

      其中,hashCode是常見的入口函數(shù),本文從類A的hashCode函數(shù)開始分析調(diào)用路徑。A#hashCode先調(diào)用A#getInterfaceC,然后調(diào)用InterfaceC#getHashCode。變量interfaceC聲明類型是InterfaceC接口類,但是由于Java多態(tài)的性質(zhì),根據(jù)聲明類型InterfaceC,無法判斷出interfaceC.getHashCode在運行時調(diào)用的是CImpl#getHashCode還是CImplOther# getHash-Code。因此,為了得到準確的調(diào)用圖,需要進行指針分析,計算變量interfaceC在實際運行過程中可能指向的對象類型,再根據(jù)指針信息解析實際調(diào)用。在圖1所示的例子中,通過指針分析,可以計算出變量interfaceC在運行過程中指向CImpl對象,因此interfaceC.getHashCode對應(yīng)的實際調(diào)用方法是 CImpl#getHashCode。在CImpl#getHashCode中調(diào)用了interB.get,由于變量interB也是接口類型,所以需要指針分析計算其運行時可能指向的對象類型。變量interB來自變量iobj,iobj為A的field。同時由于通過反序列化創(chuàng)建的A類型對象的iobj field不像變量interfaceC有顯式的創(chuàng)建對象代碼,所以無法通過常規(guī)的指針分析計算interB的指針信息。在反序列化的過程中能夠控制類型和屬性值,所以可以控制iobj為InterfaceB的所有實現(xiàn)類,即圖1示例中的BImpl或者BImplOther。因此,interB.get可能會調(diào)用BImpl#get或者BImplOther#get,需要遍歷追蹤這兩個接口,發(fā)現(xiàn)BImplOther#get不會調(diào)用危險函數(shù),但這個分支屬于不得不排查的無效分支;接下來,在BImpl#get分支中調(diào)用了method#invoke,其中clazz和methodName都是field,在反序列化時對應(yīng)的值是攻擊者可控的,因此變量method也是攻擊者可控的,所以該分支最終可以調(diào)用method.invoke危險函數(shù),而且變量method和obj都是攻擊者可控的。至此,本文找到了一條以A#hashCode為起點,Method#invoke為終點的反序列化利用鏈。完整的調(diào)用鏈如圖1中的紅色箭頭所示:A#hashFigure→ CImpl# getHashFigure→ BImpl#get → Method# invoke。

      過程間的污點傳播鏈為圖1中藍色箭頭所示:A#hashCode@iobj → CImpl#getHashCode@ interB → BImpl#get@this。

      從上面示例中可以看出,尋找利用鏈過程的本質(zhì)是污點分析:分析污點源能否從入口函數(shù)傳播到危險函數(shù)。同時,過程間的污點傳播需要準確的函數(shù)調(diào)用圖,但Java多態(tài)導(dǎo)致不能只根據(jù)聲明類型確定調(diào)用關(guān)系。所以需要根據(jù)指針分析的結(jié)果解析準確的函數(shù)調(diào)用。反序列化的過程中會隱式創(chuàng)建對象,而且創(chuàng)建的對象可能不唯一,可以是聲明類型的所有實現(xiàn)子類,導(dǎo)致傳統(tǒng)的指針分析無法直接應(yīng)用在這項任務(wù)中,需要進一步遍歷可能的所有接口。但是反序列化入口函數(shù)多,類路徑代碼量大,反序列化時創(chuàng)建的field可能是聲明類型所有子類對象,這些因素導(dǎo)致直接從所有入口函數(shù)進行指針分析,計算量非常大,在有限的時間和受限的內(nèi)存情況下無法得出指針分析的結(jié)果。

      另外,如果只通過聲明類型構(gòu)造簡單調(diào)用圖,然后在調(diào)用圖中尋找從入口函數(shù)到危險函數(shù)的調(diào)用鏈作為反序列化利用鏈。這種做法將存在大量的誤報:一是因為根據(jù)聲明類型構(gòu)造的調(diào)用圖不準確,調(diào)用關(guān)系在實際運行的過程中可能不存在;二是即使調(diào)用鏈存在,如果污點源無法傳播到危險函數(shù),調(diào)用鏈也將無法利用。

      綜上所述,雖然通過調(diào)用圖分析挖掘反序列化利用鏈的速度快,但調(diào)用圖不準確導(dǎo)致存在大量的誤報;同時為了構(gòu)造更準確的調(diào)用圖用于過程間信息流分析,需要進行指針分析。引入指針分析后,準確的調(diào)用圖讓污點傳播更準確,但指針分析計算復(fù)雜導(dǎo)致效率較低。

      因此,為了準確且高效地挖掘反序列化利用鏈,本文提出了一種基于混合分析的Java反序列化利用鏈挖掘方法。首先,通過調(diào)用圖分析找出可能到達危險函數(shù)的入口函數(shù);然后,利用篩選出的入口函數(shù)作為混合信息流分析的入口,構(gòu)建包含指針信息和污點信息流向的混合信息流圖;最后,基于混合信息流圖判斷從入口函數(shù)開始的污點是否能傳播到危險函數(shù),從而高效查找實際可行的反序列化利用鏈。

      3 方法設(shè)計

      3.1 面向危險函數(shù)的調(diào)用圖分析

      判斷一條利用鏈是否有效的充分必要條件是:攻擊者控制的污點輸入能否從利用鏈的入口函數(shù)傳播到利用鏈的敏感危險函數(shù)。如果利用鏈有效,一定存在從入口函數(shù)到危險函數(shù)的調(diào)用路徑。因此,有效的反序列化利用鏈一定在通過調(diào)用圖分析找到的調(diào)用路徑集合中,可以通過調(diào)用圖分析進行篩選,得到可能到達危險函數(shù)的入口點集合。

      進行調(diào)用圖分析首先需要構(gòu)造調(diào)用圖,調(diào)用圖中的節(jié)點是方法,邊為調(diào)用關(guān)系。Java中的函數(shù)調(diào)用分為3類:靜態(tài)方法調(diào)用、特殊方法調(diào)用、虛擬方法調(diào)用,其中特殊方法調(diào)用包括私有方法調(diào)用、超級方法調(diào)用和構(gòu)造方法調(diào)用。靜態(tài)方法調(diào)用和特殊方法調(diào)用,不需要根據(jù)指針信息進行解析,能夠根據(jù)聲明類型確定被調(diào)用函數(shù)。由于Java多態(tài)的特性,虛擬方法不能根據(jù)聲明類型確定被調(diào)函數(shù)。如何解析虛擬方法調(diào)用的被調(diào)函數(shù)是調(diào)用圖分析面臨的主要難題。為了防止調(diào)用圖不全導(dǎo)致的漏報,本文假設(shè)變量在實際運行時,指向聲明類型所有的子類。按照這種策略,在圖1所示的代碼中變量interfaceC可能指向CImpl或者CImplOther,調(diào)用interfaceC.getHashCode被解析成CImpl#getHashCode或者CImplOther# getHashCode;同理,調(diào)用interB.get被解析成BImpl#get或者BImplOther#get。最終調(diào)用圖如圖2所示,構(gòu)造好調(diào)用圖之后,根據(jù)調(diào)用圖從危險函數(shù)開始回溯,尋找能夠到達危險函數(shù)的入口函數(shù)。圖2中能夠到達危險函數(shù)的入口函數(shù)為A#hashCode,另外一個入口函數(shù)AOther# hash-Code無法到達危險函數(shù)。在后續(xù)污點分析時,將污點的入口函數(shù)設(shè)置為A#hashCode即可。入口函數(shù)到危險函數(shù)的調(diào)用路徑有兩條分別是:A#hashCode→ CImpl#getHashCode→ BImpl#get →Method#invoke 和 A#hashcode→ CImplOther#getHashCode→Method#invoke。第一條是有效的利用鏈,第二條是調(diào)用圖不準確導(dǎo)致的誤報,即圖2中紅色邊表示的調(diào)用圖中覆蓋但程序運行時不存在的調(diào)用。

      圖2 調(diào)用圖 Figure 2 Call graph

      需要指出的是,在實際的Java應(yīng)用分析中,由于代碼量過大,為了能在有限的時間內(nèi)得到簡單調(diào)用圖的分析結(jié)果,在構(gòu)造調(diào)用圖時增加了如下兩類約束:一是通過設(shè)置參數(shù)MAXSTEPS,限制從入口函數(shù)出發(fā)最大的調(diào)用長度,當達到最大的調(diào)用長度之后,就不再繼續(xù)解析新的調(diào)用;二是由于JDK中的java.util.*內(nèi)部調(diào)用相對復(fù)雜,而且對尋找利用鏈幫助不大,所以限制以java.util開頭的類的方法,不允許再調(diào)用其內(nèi)部函數(shù)。

      3.2 面向指針的信息流分析

      通過調(diào)用圖分析,能夠找到入口函數(shù)到達危險函數(shù)的路徑集合。但是調(diào)用關(guān)系在程序?qū)嶋H運行中是否真實存在,還需要指針分析進一步驗證。

      下面根據(jù)圖1的信息流分析示例介紹面向指針分析的信息流圖構(gòu)造。

      (1)指針信息初始化

      傳統(tǒng)指針分析中的指針信息初始化操作是new語句,如圖3中代碼第9行b3=new B(),通過new創(chuàng)建的對象為OB9,賦值操作將對象OB9的信息傳播到變量b3,信息流圖中OB9指向b3。

      圖3 信息流分析示例 Figure 3 Example code for information flow analysis

      而在反序列化的過程中,程序會隱式創(chuàng)建對象,需要在信息流圖中加上隱式對象流向邊。隱式創(chuàng)建的對象是聲明類型的所有實現(xiàn)子類。圖3中,反序列化時創(chuàng)建的隱式對象設(shè)為OA0,OA0被賦值給A#entry@this,在信息流圖中OA0指向A#entry@this。實際上反序列化時也會隱式對field創(chuàng)建對象,但靜態(tài)分析時沒有必要對所有field創(chuàng)建對象,可以在加載field時再實例化field對象,這樣就可以做到只對用到的field才實例化,而且利用該規(guī)則可以對field對象的field進行實例化。在第7和12行中,加載了OA0.fldb1,OA0.fldstr,此時才創(chuàng)建隱式對象OB0、OString0,并在信息流圖中將其指向OA0.fldb1、OA0.fldstr。

      (2)過程內(nèi)信息流圖構(gòu)造

      在Java中過程內(nèi)變量之間的信息傳播有Assign、Load、Store這3種語句。

      Assign表示賦值,如圖3中的第8行,變量b1包含的信息將傳播給變量b2,信息流圖中b1指向b2。

      Load表示獲取一個對象的filed值,如第7行,對象OA0流向變量A#entry@this,所以O(shè)A0.fldb1包含的信息傳播給 b1,OA0.fldb1指向b1。

      Store表示對一個對象的field進行賦值,第10行,對象OA0流向變量A#entry@this,所以是b3包含的信息傳播給OA0.fldb2,b3指向OA0.fldb2。

      (3)過程間信息流構(gòu)造

      Call表示函數(shù)調(diào)用,涉及過程間變量信息傳播。例如圖3中第11行,遇到函數(shù)調(diào)用時,需要根據(jù)變量指針信息解析真實的調(diào)用。因為信息流圖中對象OA0流向變量A#entry@this,因此變量A#entry@this運行中指向OA0對象,OA0類型為A,因此,this.func2實際調(diào)用的是A#func2。函數(shù)調(diào)用涉及3種變量傳播:實際參數(shù)向形式參數(shù)傳播,比如b1向paramb傳播;函數(shù)內(nèi)返回值向函數(shù)調(diào)用返回值傳播,如ret向b4傳播;對象向調(diào)用方法的this傳播,如A#entry@this向A#func2@this傳播。因此,在控制流圖中b1指向paramb,ret指向b4,A#entry@this指向A#func2@this。

      3.3 面向污點的信息流分析

      雖然通過指針分析能夠得到準確的調(diào)用圖,但準確的調(diào)用關(guān)系還不足以判斷一條調(diào)用鏈是否真實有效,還需要通過污點分析判斷外部污點數(shù)據(jù)能否傳播到危險函數(shù)。

      表面上,污點分析和指針分析傳播不同的信息:指針分析是在變量之間傳遞指針指向的對象集合;污點分析在變量傳遞內(nèi)容時根據(jù)污點傳播策略傳遞變量對應(yīng)的污點屬性。但是,污點分析和指針分析本質(zhì)上均為信息流分析,變量之間傳播的實際均為對象信息。可以根據(jù)指針變量指向的對象是不是污點,判斷當前指針是否需要標記污點屬性,從而將兩者合并成同一個過程。例如,在圖4中,對象OB0在信息流圖上能夠傳播到變量b1,所以b1指向?qū)ο驩B0。如果OB0含有污點標記,那么就可以認為指針變量b1是污點。

      基于污點分析等價于傳播帶污點標記的對象,本文提出了混合分析——即同時進行指針分析和污點分析。具體地說,在對象初始化時打上是否為污點的標記,即可在指針分析的同時進行污點分析。相較于傳統(tǒng)的指針分析,本文根據(jù)反序列應(yīng)用的場景,需要針對性地增加規(guī)則來完成混合分析,其主要包含污點源初始化、污點轉(zhuǎn)移規(guī)則。

      (1)污點源初始化

      污點信息的初始化是將反序列化時隱式創(chuàng)建的對象作為污點源,打上污點標記。OA0是污點源,將其標記為圖4中的紅框。

      (2)污點轉(zhuǎn)移規(guī)則

      污點轉(zhuǎn)移規(guī)則包含3種。第一種是當加載污點對象的field時,如z=x.f,如果x是污點,那么z也是污點。因為OA0是污點源,OB0和OString0是加載OA0field時隱式創(chuàng)建的對象,所以O(shè)B0和OString0也是污點源。第二種是當調(diào)用函數(shù)的對象是污點時,如z = x.func(),如果x是污點那么認為 z也是污點。在圖 3中有語句str2=str1.substring(1), 所以str1有條指向str2的污點轉(zhuǎn)移流向的邊。第三種是當調(diào)用函數(shù)的參數(shù)是污點時,如z=x.func(y),如果y是污點,那么z也是污點。在實際測試中發(fā)現(xiàn)第二種規(guī)則會帶來誤報,如this.getClass().getClassLoader()這種情況,由于this是污點數(shù)據(jù),getClass()返回的也是污點數(shù)據(jù),所以getClassLoader()返回的也是污點數(shù)據(jù),但實際情況下getClassLoader()返回值的攻擊者并不可控。類似還有this.set.Iterator(),this.map.keys()等的返回值攻擊者都不可控。本文通過限制返回值的類型,阻止這種傳播,減少誤報。

      因此,綜合利用污點分析和指針分析兩方面的信息流傳播規(guī)則,得到圖3對應(yīng)的混合信息流圖,如圖4所示。混合信息流圖節(jié)點中包括變量節(jié)點(藍框表示),隱式對象節(jié)點(紅框表示),顯式對象節(jié)點(黑框表示),對象field 節(jié)點(綠框表示)。信息流圖邊包括隱式對象流向、顯式對象流向、信息流向、污點轉(zhuǎn)移流向。

      車地無線通信采用成熟的LTE技術(shù)。該技術(shù)具備高可靠的抗干擾能力,可滿足互聯(lián)互通CBTC系統(tǒng)車地之間數(shù)據(jù)在高速移動環(huán)境下的穩(wěn)定傳輸[7]。同時,針對空口消息的偽裝風險,可采用安全加密技術(shù)防護,將其直接部署在TAU(車載終端)和BBU(軌旁基帶單元)上來實現(xiàn)鑒權(quán)和加密機制,保障車地無線通信的信息安全。安全加密技術(shù)采用滿足LTE國際加密標準的國密算法——祖沖之(ZUC)算法。

      圖4 混合信息流圖 Figure 4 Hybrid information flow graph

      根據(jù)指針分析,變量b1、b2、paramb、ret、b4指向?qū)ο驩B0,變量str1、str2指向?qū)ο驩String0。由于對象OB0和OString0都帶污點標記所以變量b1、b2、paramb、ret、b4、str1、str2都是污點。

      綜上所述,本文提出的混合分析方法先通過調(diào)用圖分析篩選出可能達到危險函數(shù)的入口函數(shù);然后,再以這些入口函數(shù)作為入口進行同時面向指針和污點變量的混合信息流分析,最后基于信息流分析找出從入口函數(shù)開始污點源流向危險函數(shù)的路徑。

      混合分析示意如圖5所示。其中A函數(shù)是調(diào)用圖分析提取的潛在利用鏈入口函數(shù)。將A函數(shù)作為混合信息流分析的起點,通過傳播污點標記的對象,進行指針分析和污點分析。

      圖5 混合分析示意 Figure 5 Hybrid analysis method diagram

      4 方法實現(xiàn)

      基于上述方法,本文實現(xiàn)了一套自動化挖掘Java反序列化利用鏈的原型系統(tǒng)——Gadget Search,GadgetSearch支持挖掘Jackson、Fastjson、XStream、JND、Hessian 5種常見反序列化器的利用鏈。

      GadgetSearch首先利用Soot解析Java字節(jié)碼,將字節(jié)碼轉(zhuǎn)化中間語言Jimple。然后,從Jimple中解析出類的基本信息,如類修飾符、父類、field、方法等以及方法中的操作指令new、Assign、Load、Store、Call,將這些信息保存成facts。接著用Datalog語法表達第4節(jié)描述的規(guī)則,用Souffle執(zhí)行Datalog文件進行混合分析。分析完成后產(chǎn)生兩個主要文件:Nodes.csv和Calls.csv。Nodes.csv記錄各個Method,有3類標簽,分別是EntryPoint、Method和SinkMethod;Calls.csv記錄方法之間的調(diào)用關(guān)系。最后,通過Neo4j-admin 將Nodes.csv和Calls.csv文件導(dǎo)入Neo4j 數(shù)據(jù)庫,并通過Cypher語句查詢從EntryPoint到SinkMethod的路徑,對方法調(diào)用路徑可視化,方便安全排查調(diào)用鏈是否可利用。

      5 實驗分析

      為了評估本文提出混合分析方法的有效性,需要設(shè)計實驗回答下面3個問題。

      RQ1:GadgetSearch能否挖掘到未公開的利用鏈?

      RQ3:如何評估本文提出的混合分析方法的必要性?

      測試的實驗環(huán)境為 Ubuntu16.04,Java 1.8.0_171, 內(nèi)存36 GB,24核Intel(R) Xeon(R) CPU E5-2630處理器。

      5.1 針對RQ1的實驗

      為了驗證GadgetSearch能夠挖掘未知利用鏈,本文對JDK和一些流行的Jar包進行了測試。最終發(fā)現(xiàn)5條未公開利用鏈,具體數(shù)據(jù)如表1所示。其中CVE-2021-43297是第一條僅依賴JDK就能夠命令執(zhí)行的Hessian利用鏈。換句話說,只要存在Hessian反序列化漏洞,攻擊者無須關(guān)心類路徑包含哪些第三方庫,直接利用這條鏈即可攻擊,危害十分嚴重。本文成功利用該鏈攻擊了Dubbo。

      表1 未公開利用鏈列表Table 1 List of CVE/CNVD

      5.2 針對RQ2的實驗

      挖掘Java反序列化的工具有Jack Of-MostTrades版本的 GadgetInspector(記為JGadgetInspector),以及Threedr3am 改進后的GadgetInspector(記為 TGadgetInspector) 。JGadgetInspector支持檢測Jackson、XStream、JND這3種反序列化利用鏈。GadgetSearch和TGadgetInspector都支持檢測Jackson、Fastjson、XStream、JND、Hessian這5種反序列化利用鏈。

      為了只找出能夠命令執(zhí)行的利用鏈,本文去掉了JGadgetInpsector和TGadgetInspector中不能夠造成命令執(zhí)行的危險函數(shù)(如ssrf,文件讀寫等)。TGadgetInspector檢測Fastjson利用鏈時,其為了檢測出新的利用鏈,將已知的利用鏈加入了黑名單,對黑名單中的鏈不再檢測。為了實驗的公平性,本文將TGadgetInspector中Fastjson的黑名單置為空。

      為了對比GadgetSearch和JGadget Inspector,TGadgetInspector檢測反序列化利用鏈的誤報率、漏報率以及運行效率,本文在Marshalsec,Ysoserial、Jackson CVE、XStream CVE數(shù)據(jù)集上進行測試。Marshalsec和Ysoserial是兩個業(yè)界較出名的Java反序列化利用鏈Payload生成工具,包含一些已知的反序列化利用鏈。Marshalsec包含Jackson、XStream、Hessian 3種反序列化利用鏈,Ysoserial只包含JND反序列化利用鏈,數(shù)據(jù)集詳情如表2所示。Jackson和XStream官方會為反序列化利用鏈申請CVE,所以本文從Jackson歷史CVE中篩選出15個能夠命令執(zhí)行的CVE,從XStream歷史CVE中篩選出14個能夠命令執(zhí)行的CVE作為另外兩組數(shù)據(jù)集。

      表2 Marshalsec 數(shù)據(jù)集Table 2 Marshalsec dataset

      Jackson檢測結(jié)果如表3所示。Marshalsec數(shù)據(jù)集中總計有 2條 Jackson利用鏈。JGadgetInspector挖掘出8條鏈,其中0條有效鏈,9條誤報鏈,漏報率為100%,誤報率為100%; TGadgetInspector挖掘出9條鏈,其中0條有效鏈,9條誤報鏈,漏報率為100%,誤報率為100%;GadgetSearch一共挖掘出18條利用鏈,且均為18條有效鏈,漏報率為0%,誤報率0%。

      表3 Jackson 檢測結(jié)果Table 3 Results of Jackson

      Fastjson檢測結(jié)果如表4所示。Marshalsec數(shù)據(jù)集中沒有相應(yīng)的Fastjson利用鏈, JGadgetInspector不支持 Fastjson利用鏈的檢測。TGadgetInspector一共檢測出633條利用鏈,其中0條有效鏈,漏報率100%,誤報率100%;GadgetSearch一共檢測出85條利用鏈,均為有效鏈,誤報率為0%,漏報率為0%。

      表4 Fastjson 檢測結(jié)果Table 4 Results of Fastjson

      XStream檢測結(jié)果如表5所示。Marshalsec數(shù)據(jù)集中包含 5條 XStream 利用鏈,JGadgetInspector檢測出101條利用鏈,其中有14條有效利用鏈,漏報了5條,誤報率為86%,漏報率為100%;TGadgetInspector一共檢測出269條利用鏈,其中12條有效利用鏈,漏報了5條,誤報率為95%,漏報率為100%;GadgetSearch一共檢測出126條利用鏈,且均為有效鏈,誤報率為0%,漏報率為0%。

      表5 XStream 檢測結(jié)果Table 5 Results of XStream

      Hessian檢測結(jié)果如表6所示。Marshalsec數(shù)據(jù)中包含3條Hessian利用鏈,JGadgetInspector不支持Hessian反序列化利用鏈的挖掘。TGadgetInspector一共檢測出1021條利用鏈,其中6條有效利用鏈,誤報率為99.4%,沒有檢測出Marshalsec數(shù)據(jù)集中包含的利用鏈,漏報率為100%;GadgetSearch一共檢測出36條利用鏈,且均為有效鏈,誤報率為0%,漏報率為0%。

      表6 Hessian 檢測結(jié)果Table 6 Results of Hessian

      JND檢測結(jié)果如表7所示。Ysoserial數(shù)據(jù)集中包含13條JND反序列化利用鏈。JGadgetInspector一共檢測出24條利用鏈,分析發(fā)現(xiàn)24條全是誤報,漏報率為100%,誤報率100%。針對JGadgetInspector報告的common- collections反序列化利用鏈,如圖6所示,經(jīng)過分析可認為此條鏈并不能直接利用。因為最終Method#invoke 調(diào)用時,第一個參數(shù)input是Class類,無法造成危害,不能達到命令執(zhí)行的效果,如圖7所示。TGadgetInspector一共發(fā)現(xiàn)了26條利用鏈,26條利用鏈均為誤報,漏報率100%,誤報率100%。GadgetSearch一共檢測出118條利用鏈,均為有效鏈,針對bsh-2.0b5.jar利用鏈過長超過了GadgetSearch設(shè)置的最大長度,未被檢測出有效利用鏈, 漏報率為7%,誤報率為0%。

      圖6 JGadgetInspector 檢測common-collections結(jié)果 Figure 6 The results of common-collections detected by JGadgetInspector

      圖7 common-collections 無效利用鏈 Figure 7 common-collections Invalid gadget chain

      表7 JND檢測結(jié)果Table 7 Results of JND

      在Jackson CVE數(shù)據(jù)集上JGadgetInspector 和TGadgetInspector均未檢測出相應(yīng)包含關(guān)鍵類的利用鏈,漏報率100%,GadgetSearch則全部檢測出,漏報率0%,檢測結(jié)果如表8所示。

      表8 Jackson CVE檢測結(jié)果Table 8 Results of Jackson CVE

      在XStream CVE數(shù)據(jù)集上的檢測結(jié)果如表9所示,JGadgetInspector 和TGadgetInspector能檢測出3個CVE,GadgetSearch能夠檢測出12個CVE。其中CVE-2021-39141、CVE-2021-39144、CVE-2021-39146、CVE-2021-39153為上報給XStream官方的,此外CVE-2021-39149基本等同 于本文發(fā)現(xiàn)的CVE-2021-39144,CVE-2021-39154基本等同于本文發(fā)現(xiàn)的CVE-2021-39146。CVE-2020-21344和CVE-2020-21345利用鏈過長,導(dǎo)致GadgetSearch無法檢測出相應(yīng)的利用鏈。

      表9 XStream CVE檢測結(jié)果Table 9 Results of XStream CVE

      從實驗結(jié)果可以看出,GadgetSearch的漏報率和誤報率都遠低于 JGadgetInspector和TGadgetInspector,主要原因是JGadgetInspector和TGadgetInspector入口函數(shù)和危險函數(shù)設(shè)置不全,以及沒有進行指針分析且調(diào)用圖不準確。

      GadgetSearch 檢測 Jackson、XStream、Hessian、JND的運行效率優(yōu)于JGadgetInspector和TGadgetInspector;檢測Fastjson的效率低于JGadgetInspector和 TGadgetInspector。Gadget Search設(shè)置的危險函數(shù)比TGadget Inspector全,在測試resin時GadgetSearch找到的從入口函數(shù)到危險函數(shù)的路徑比TGadgetInspector多,導(dǎo)致GadgetSearch后續(xù)指針分析和污點分析消耗了較多的時間。

      5.3 針對RQ3的實驗

      為了驗證本文提出的混合分析方法的有效性,本文做了3組對比實驗,分別利用調(diào)用圖分析、混合信息流分析以及混合分析,實驗結(jié)果如表10所示。在入口函數(shù)設(shè)置為toString和危險函數(shù)設(shè)置為Method#invoke的情況下,對JDK中的XStream利用鏈進行檢測。實驗結(jié)果表明,調(diào)用圖分析效率最高,但誤報數(shù)也最高?;旌闲畔⒘鞣治鲈谟邢薜臅r間(24 h)未能完成分析,混合分析誤報數(shù)最低,同時運行時間在可接受的范圍?;旌戏治龅恼`報主要來自轉(zhuǎn)移函數(shù)的黑名單不健全,污染了一些不該污染的返回值。

      表10 3種分析對比實驗結(jié)果Table 10 Comparison of experimental results

      5.4 Dubbo Hessian反序列化RCE分析

      下面將介紹GadgetSearch挖掘到了Hessian僅依賴JDK的反序列化利用鏈,并基于此利用鏈攻擊Dubbo的全過程。Dubbo 是一個高性能、輕量級的開源服務(wù)框架。其默認支持Hessian作為其數(shù)據(jù)傳輸時序列化和反序列化的方式。Hessian在反序列化Map類型時執(zhí)行map#put時會觸發(fā)Object#hashCode,但是Object#hashCode調(diào)用范圍比較小,未能找到可以利用的調(diào)用鏈。為了擴大利用鏈的搜索范圍,尋找除了Object#hashCode以外新的入口函數(shù)。分析GadgetSearch的調(diào)用圖,發(fā)現(xiàn)在執(zhí)行HessianInput#readMap時會將反序列化之后的obj和字符串拼接,觸發(fā)obj.toString() 函數(shù),所以本文找到了一個新的入口函數(shù)Object#toString,如圖8所示。

      圖8 Hessian 新入口函數(shù) Figure 8 New entry point of Hessian

      將Object#toString添加到入口函數(shù)重新運行GadgetSearch,輸出了利用鏈如圖9所示。MimeTypeParameterList#toString中調(diào)用了parameters. get(keys),parameters是類型為Hashtable的field,在反序列化時可控,可以設(shè)置parameters值為UIDefaults的實例,當執(zhí)行parameters.get(keys)時,實際是執(zhí)行UIDefaults# get,這樣就從MimeTypeParameter List#toString這個gadget跳到了UIDefaults#get這個gadget。UIDefaults#get中調(diào)用了UIDefaults# getFromHashtable,在UIDefaults# getFromHashtable中,通過super.get(key) 獲取了value值,由于UIDefaults繼承了Hashtable類,并且UIDefaults值是攻擊者可控的,所以取出的value也是攻擊者可控的。如果value是LazyValue類型,則調(diào)用value.create Value(this)。因為value攻擊者可控,所以可以設(shè)置value值為UIDefaults $ProxyLazyValue的實例,調(diào)用value.createValue(this)時,實際上是調(diào)用UIDefaults$ProxyLazyValue. create-Value(this),調(diào)到了UIDefaults$ProxyLazy Value# createValue gadget上。在UIDefaults$Proxy Lazy-Value# createValue中變量 className、args、methodName 均為field,所以可以從類名為className中獲取方法名為methodName的方法,然后通過MethodUtil.invoke調(diào)用獲取的方法,MethodUtil.invoke就是本文定義的危險函數(shù)。通過4個gadget,完成了從入口函數(shù)Object#toString到危險函數(shù)MethodUtil.invoke的調(diào)用。但是利用到此還未結(jié)束,還需要確定要調(diào)用哪個類的哪個方法,MethodUtil.invoke(method,obj,args)第一個參數(shù)是要調(diào)用的方法,第二個參數(shù)是調(diào)用的對象,第三個參數(shù)是要傳的參數(shù)。在UIDefaults$Proxy LazyValue#createValue中能控制第一個參數(shù)和第三個參數(shù),第二個參數(shù)無法設(shè)置為對應(yīng)的對象。所以這里要調(diào)用class的方法,但調(diào)用class的方法沒有什么危害。此外還可以調(diào)用靜態(tài)函數(shù),因為靜態(tài)函數(shù)的調(diào)用,對對象沒有要求,即使設(shè)置為null也可以。所以需要找一個有危害的靜態(tài)函數(shù)調(diào)用。從所有JDK的靜態(tài)函數(shù)中,找到了兩個合適的靜態(tài)函數(shù),com.sun.org.apache.xml. internal.security.utils. JavaUtils#writeBytesToFilename和Java.lang.System# load,JavaUtils# writeBytesToFilename函數(shù)可以對任意文件寫任意內(nèi)容,System#load 可以加載so文件,在加載so文件時觸發(fā)代碼執(zhí)行。所以可以將兩者組合,利用JavaUtils#writeBytesToFilename在臨時目錄寫入一個惡意的so文件,然后再用System#load加載該惡意的so即可觸發(fā)命令執(zhí)行。

      圖9 Hessian 反序列化利用鏈 Figure 9 Hessian gadget chain

      6 結(jié)束語

      本文提出了一種基于混合分析的反序列化利用鏈挖掘方法,并基于該方法實現(xiàn)了一款自動化挖掘Java反序列化利用鏈工具GadgetSearch,利用該工具發(fā)現(xiàn)了一條第三方庫中的Jackson未公開利用鏈,4條JDK中的XStream未公開利用鏈,1條JDK中的Hessian未公開利用鏈。同時,在對比實驗中GadgetSearch的誤報率和漏報率遠低于現(xiàn)有工具GadgetInspector。

      猜你喜歡
      污點序列化信息流
      基于代碼重寫的動態(tài)污點分析
      如何建構(gòu)序列化閱讀教學(xué)
      甘肅教育(2020年14期)2020-09-11 07:58:36
      基于信息流的作戰(zhàn)體系網(wǎng)絡(luò)效能仿真與優(yōu)化
      基于信息流的RBC系統(tǒng)外部通信網(wǎng)絡(luò)故障分析
      戰(zhàn)區(qū)聯(lián)合作戰(zhàn)指揮信息流評價模型
      使用Lightroom污點去除工具清理照片中的瑕疵
      Java 反序列化漏洞研究
      基于任務(wù)空間的體系作戰(zhàn)信息流圖構(gòu)建方法
      我國“污點證人”刑事責任豁免制度的構(gòu)建
      作文訓(xùn)練微格化、序列化初探
      語文知識(2015年12期)2015-02-28 22:02:15
      太康县| 应用必备| 泰兴市| 大新县| 灯塔市| 华蓥市| 思南县| 临汾市| 日土县| 江川县| 南投县| 金寨县| 湘西| 华安县| 广安市| 武鸣县| 中宁县| 炎陵县| 江北区| 扎鲁特旗| 邻水| 伊宁市| 上杭县| 璧山县| 绵竹市| 宁南县| 宿迁市| 子长县| 玛曲县| 德格县| 会同县| 石阡县| 庐江县| 蚌埠市| 柳河县| 涿州市| 西峡县| 嘉禾县| 镇江市| 白玉县| 中西区|