Oracle 12c及Oracle 18c組件jssu程序存在漏洞,易受符號鏈接攻擊影響,攻擊者可利用此漏洞獲得服務器root權限,此漏洞由安華金和公司安全實驗室發(fā)現,CVE編號為CVE-2019-2444。本文將詳細說明漏洞涉及的技術細節(jié),并介紹與此漏洞相關的攻擊手段。
漏洞點
程序jssu是為Oracle Scheduler提供服務的組件,保存于Oracle主安裝目錄的bin文件夾下。在使用了credential的情況下,Scheduler會使用jssu程序來登錄系統進行操作。不過,jssu程序之所以會受到符號攻擊影響,原因與其功能關系不大,而是以下幾個方面:
首先是jssu程序本身的屬主及權限。默認情況下,程序所屬用戶是root,而用戶組是oinstall,與oralce用戶的用戶組相同。程序權限為4750,即所屬用戶組可讀可執(zhí)行,且設置了suid位。
其次,jssu程序運行時會在工作目錄下生成一個日志文件,并向其中寫入內容。該文件由程序的進程ID命名,具有固定的格式,即已知進程ID,就可推測出日志文件的文件名。生成的日志文件,其所屬用戶和用戶組與jssu程序相同,且其權限可被實際登錄用戶當前設置的umask控制。
總結這兩點,我們現在擁有一個以oracle用戶即可執(zhí)行,所屬用戶為root,設置了suid位,且可向當前工作目錄輸出文件的程序。由此,產生了一個符號鏈接攻擊思路。
作為攻擊者,我們以oracle用戶登錄,并啟動jssu。如果能在jssu寫入日志前,將輸出文件定義成一個指向我們所需位置的符號鏈接,由于jssu程序運行時具有root用戶權限,這樣我們就得了向任意位置寫入文件的能力。且此文件所屬用戶為root,用戶組為oinstall,讀寫權限可控。也就是說,得到的文件可以被oracle用戶修改。由此延伸,將符號鏈接指向/etc/ld.so.preload,文件產生后,我們就可以用oracle用戶修改這個文件。/etc/ld.so.preload文件可以控制系統中所有進程啟動時預先加載的動態(tài)鏈接庫,正常情況下只有root用戶可以修改。而攻擊成功后,oracle用戶就可以修改這個文件,指定一個由我們控制的動態(tài)鏈接庫文件,我們就可以通過這個動態(tài)鏈接庫拿一個root用戶的shell,更詳細的說明請見下一節(jié)。
攻擊流程
1.作為準備,復制一個shell程序(/bin/bash)作為備份,在后面步驟中將會修改這個備份的權限,使執(zhí)行者可以拿一個root用戶權限的shell。
2.構建一個動態(tài)鏈接庫,即“攻擊思路”中提到的將要通過/etc/ld.so.preload加載到所有進程中的動態(tài)鏈接庫。使用我們定義的函數”覆蓋“默認的geteuid函數,新函數的邏輯非常簡單,判斷當前進程的有效用戶是否為root,如果是則修改之前準備好的shell程序備份的權限為04777(所有用戶可讀寫,suid位已設置),修改所屬用戶和用戶組為root。
3.構建一個可執(zhí)行程序,完成調用jssu和制作符號鏈接的工作。程序主體首先設置umask為0000,然后使用fork創(chuàng)建一個子進程。子進程啟動jssu程序;父進程則通過子進程ID,構造出jssu將要寫入的日志文件名,提前使用這個文件名生成一個指向/etc/ld.so.preload的符號鏈接。父進程等待一段時間(保證jssu有輸出),殺掉子進程。如一切順利,此時/etc/ld.so.preload已經被創(chuàng)建,所屬用戶root,所屬用戶組oinstall,權限0666,內容為jssu的輸出日志。
4.修改/etc/ld.so.preload,將已準備好的動態(tài)鏈接庫路徑寫入,覆蓋所有jssu的輸出。
5.等待一個root權限進程調用geteuid函數,觸發(fā)我們準備的動態(tài)鏈接庫中的代碼。這一步我們可以直接在命令行運行“sudo 2>/dev/null >/dev/null”,這個程序滿足我們的需求,結束后動態(tài)鏈接庫中的代碼已經被執(zhí)行,我們準備的shell程序備份的運行權限和所屬用戶已經按我們的需求做了修改。此時,任意用戶都可以通過在命令行運行這個shell備份獲得一個root權限的shell。
6.運行已經修改好的shell程序備份,拿到root權限shell。
完整的攻擊鏈
總結CVE-2019-2444漏洞技術細節(jié),其實現的是在本地將oracle用戶權限提升為root用戶權限。在現實環(huán)境中,運行Oracle數據庫的服務器上,oracle用戶也是一個很高權限用戶,并不會輕易泄露,那這個漏洞利用是不是就沒有價值了呢?
并非如此,CVE-2019-2444漏洞的利用只是完成了一個攻擊鏈的最后一步,即拿到root權限,達到完全控制。實際上,在相同版本的Oracle數據庫中還存在著的其他的漏洞,可以與CVE-2019-2444配合,組成一個完整的攻擊鏈。例如:cve-2018-3004,此漏洞利用可通過Java反序列化向量繞過Oracle JVM內置的安全機制,達到提升用戶權限的目的。在漏洞細節(jié)已在互聯網公布,本文只梳理其關鍵技術點,具體細節(jié)可參考以下鏈接:
http://obtruse.syfrtext.com/2018/07/oracle-privilege-escalation-via.html
關于CVE-2018-3004
Oracle內置了Java虛擬機,用戶可以使用Java語言來構建存儲過程,但出于安全原因,Oracle JVM會嚴格限制低權限用戶對于文件系統的使用,例如使用java執(zhí)行本地程序,訪問本地文件等。而CVE-2018-3004漏洞,借助Java的XML反序列化方法,繞過了Oracle JVM的限制,從而可以直接訪問數據庫本地文件系統 。
Java的序列化和反序列化的作用是將JVM運行時存在于內存中的Object轉化成能夠長期保存的字節(jié)流,在將來所需時,可以將字節(jié)流重新組裝得到原先的Object。序列化和反序列化可以將Java的Object“持久”化,擺脫JVM生存周期的限制 ,也可以用來在主機間進行傳輸。XML反序列化就是一種以XML格式來保存Java Object的標準,相關描述可見如下鏈接:
https://www.oracle.com/technetwork/java/persistence3-139471.html
XML反序列化,可以描述一個Java Object,以及用來構建Object時所需要調用的方法和相關參數。在Oracle中,使用XMLDecoder類重新組裝XML序列化后的對象,而在組裝過程中所調用的對象方法,沒有被Oracle JVM限制權限。因此,可以使用XML反序列化構建一個FileWriter對象,并調用其write方法,就可以實現文件寫入操作。
文件寫入就是CVE-2018-3004的核心,利用此漏洞,低權限用戶可以任意寫入、追加或者覆蓋oracle用戶擁有寫入權限的文件。在ssh服務已經開啟的服務器上,如果向oracle用戶ssh配置中authorized_key文件中寫入一個由攻擊者構造的公鑰,此時,攻擊者就可以直接ssh登錄服務器的oracle用戶。
總結
CVE-2019-2444是一個使用符號鏈接攻擊手段,達到本地提權效果的漏洞,攻擊者可由oracle用戶權限提升至root用戶權限 ;CVE-2018-3004是一個使用Java反序列化攻擊手段達到遠程提權登錄效果的漏洞,擁有數據庫普通用戶權限且可遠程登錄的攻擊者可借由此漏洞ssh遠程連接數據庫服務器,并以oracle用戶登錄。兩個漏洞結合起來,就可以讓一個普通的數據庫使用者獲得數據庫所在服務器的root權限。