想接管別人的整個Java生態系統?只需一次中間人攻擊

大受歡迎且廣泛部署的幾百個Java庫和JVM編譯器,它們下載依賴項時,仍在用HTTP協議,卻沒有校驗完整性。本來只是想給一個小型項目做一個簡單漏洞報告,不料猛地發現了這個安全漏洞,影響了基於Java虛擬機(JVM)做開發的整個生態系統。

初探

Max Veytsman於2014年發表了一篇很棒的文章,名爲《如何接管任意Java(或Closure或Scala)開發人員的計算機》,這項工作正是基於這篇文章開展的。

當時,由Sonatype運行的Maven中央倉庫在提供JAR文件時,還不支持SSL(HTTPS)。多虧Max的文章,Sonatype幾天內就修復了這個問題。我強烈建議你在閱讀本文之前,至少先略讀一下那篇文章。雖然它已經發表了5年,但其中的警告仍然有效,不僅如此,現在還能適用於Kotlin和Groovy的開發人員。

然而,這一次不是因爲存儲庫主機缺乏對HTTPS的支持,而是因爲普遍都在採用“一字之差”的HTTP,所以直到今天,仍有成千上萬的開源項目易受攻擊。

Max在他的文章中介紹了一個名爲Dilettante的工具,“它是一箇中間人代理,攔截來自【任何工件(artifact)倉庫】的JAR包,並將惡意代碼注入其中。通過Dilettante代理HTTP流量,將會在【從工件倉庫下載的】任何JAR包裏開後門。”

Dilettante是一個簡單的POC,它所做的僅僅是讓Java在屏幕上展現貓圖片。但就是這種非常簡單的技術,卻可以用來大面積惡意破壞Java生態系統——只要項目是通過HTTP而不是HTTPS下載依賴項的。

圖中貓咪說:聽說你提供JAR包不用ssl?

HTTPS不僅能加密客戶端和服務器之間的流量,還能保證客戶端是在與其所請求的服務器進行通信,避免有人在中間冒名頂替(即MITM,中間人攻擊)。

我是怎麼發現的?

有一次,我發現自己的項目中有一個工件用的是HTTP。

// Ktor沒有發佈到jcenter倉庫。
	maven {
	    setUrl("http://dl.bintray.com/kotlin/ktor")
	}

這是怎麼來的?

這是從Ktor倉庫複製和粘貼來的。我深入研究Ktor倉庫的歷史,發現直到最近,Ktor還在用HTTP來解析依賴關係。有一點要注意,Ktor是JetBrains的一個官方庫。就連JetBrains的官方庫都這樣?我十分好奇,開始尋找其他哪裏還有這個庫。

誰容易遭受攻擊?

長話短說:GitHub上一些最流行的基於JVM的項目,它們曾經或仍然容易受到攻擊。

組織 項目 加星數 已完成 GitHub上的問題 已確認 已修復 會審覈 不審覈 審覈結果 保證影響 CVE(漏洞和披露) 無已發佈的發行版本 備註
arrow-kt arrow 2718 鏈接 未完成 CVE-2019-11404
ben-manes caffeine 6021 鏈接 無妨
cbeust jcommander 1287 鏈接 未完成
cbeust testng 1285 鏈接 未完成
cbeust kobalt 370 鏈接 未完成 構建工具。影響到用戶。
CodeNarc CodeNarc 204 鏈接 未完成
controlsfx controlsfx 229 鏈接 未完成
diffplug spotless 700 鏈接 尚無定論
Eclipse vorto 103 鏈接 未完成 CVE-2019-10248
Eclipse buildship 422 鏈接 未完成
Eclipse xtext-maven 6 鏈接 未完成 CVE-2019-10249
Eclipse hawkbit 184 鏈接 未完成 CVE-2019-10240
Eclipse xtext-xtend 55 鏈接 未完成 CVE-2019-10249
Eclipse sw360 23 鏈接 未完成
ehcache ehcache3 1323 鏈接 無妨 提交請求(pr)
FasterXML jackson-module-scala 385 鏈接 未完成
grails grails-core 2474 鏈接 無妨 CVE-2019-12728
HellFirePvP AstralSorcery 99 鏈接 未完成 “我的世界”模組
immutables immutables 2409 鏈接 未完成
ktorio ktor 5290 鏈接 未完成 CVE-2019-10102
MightyPirates OpenComputers 792 鏈接 未完成 “我的世界”模組
MinecraftForge CoreMods 22 鏈接 未完成 “我的世界”模組
NationalSecurityAgency datawave 243 鏈接 未完成
nebula-plugins nebula-kotlin-plugin 54 鏈接 未完成
nebula-plugins nebula-test 37 鏈接 未完成
nebula-plugins nebula-grails-plugin 2 鏈接 未完成
nebula-plugins nebula-clojure-plugin 12 鏈接 未完成
nextflow-io nextflow 818 鏈接 未完成
OpenAPITools openapi-generator 2456 鏈接 未完成 CVE-2019-11405 代碼生成器
PayPal Gibberish-Detector-Java 18 鏈接 未完成
PayPal digraph-parser 21 鏈接 未完成
PayPal SeLion 213 鏈接 未完成
PayPal NNAnalytics 60 鏈接 無妨
PayPal gimel 152 鏈接 未完成
PayPal aurora 81 鏈接 未完成
powermock powermock 2599 鏈接 未完成
SlimeKnights TinkersConstruct 592 鏈接 未完成 “我的世界”模組
sourcerer-io sourcerer-app 4523 鏈接 未完成
spinnaker spinnaker 6213 鏈接 未完成
spockframework spock 2368 鏈接 未完成
swagger-api swagger-codegen 9540 鏈接 未完成 代碼生成器
target data-validator 12 鏈接 未完成
TheGreyGhost MinecraftByExample 549 鏈接 未完成
typelevel cats 3261 鏈接 無妨
uber uReplicator 493 鏈接 未完成
uber uberscriptquery 42 鏈接 未完成
uber chaperone 603 鏈接 未完成
WebGoat WebGoat 2546 鏈接 未完成
xtext maven-xtext-example 51 鏈接 未完成
總加星數 63960
Sheetsu.com提供

注意:“已完成”列寫着“是”的項目已完全解決了問題,並且已審覈過,或爲其之前的版本發佈了CVE編號。

下面是上表的Google Sheets地址,有興趣可以去看看。

不安全依賴的解決方案

除了上面列出的項目之外,還有一些大型社區和組織也會受此漏洞影響。

“我的世界(Minecraft)”遊戲模組

這是我找的第一個地方,不出所料,馬上就找到了這個漏洞,在幾乎所有模組的構建的基礎架構中都有它。

JetBrains

考慮到Ktor事件可能不是一次性事件,我開始關注JetBrains在GitHub上的項目。
Kotlin 編譯器

Kotlin是JetBrains開發的編程語言,可編譯爲JVM、LLVM和JavaScript,在Android開發人員中很受歡迎。谷歌最近指定Kotlin現在成爲Android開發的首選語言

我在Kotlin編譯器代碼庫中,發現了許多實例,它們的構建的基礎設施和測試都通過HTTP下載依賴項.

不僅Kotlin編譯器的源代碼的依賴容易受到攻擊,而且易受攻擊的代碼倉庫也用在了Gradle的“buildscript”類路徑,這增加了把牽連到的工件發佈出去的潛在風險。

如果這還不夠糟糕,那麼buildscript類路徑也用於解析以前版本的Kotlin編譯器,從而使編譯器可能遭受“Trusting Trust”攻擊(參見下面更詳細的內容)。

IntelliJ IDEA
IntelliJ和一些官方插件不僅容易受到攻擊,而且很多情況下,創建啓動項目會用到代碼生成器,所以IntelliJ生成的項目也容易受到攻擊。

Gradle

Gradle是一個有趣的案例。作爲Gradle的貢獻者,你不會受到此漏洞的影響。但是,當在Gradle公司的Team City CI基礎設施上,用Gradle構建Gradle代碼庫時,該基礎設施會覆蓋一些默認值,改成用HTTP從JFrog Artifactory實例上獲取工件。幸運的是,該基礎設施與Gradle JFrog Artifactory服務器位於同一網絡中。

話又說回來,Gradle公司的JFrog Artifactory服務器還通過HTTP爲其他工件服務器建立鏡像,因此可能會將這些鏡像暴露給基於MITM的緩存中毒(cache poisoning)攻擊。

Elastic Search

在撰寫本文時,Elastic Search代碼庫有3.86萬次加星,是GitHub上最受矚目的Java項目。Elastic Search的主工程有超過1100個貢獻者。因此我確定,Elastic構建裏的測試邏輯部分易受此漏洞影響。

Apache

我在Apache軟件基金會(Apache Software Foundation)的幾個項目中發現了這個漏洞。

其中值得注意的將在下文列出。

截至本文發佈之日,Apache軟件基金會已決定不給受影響項目發佈CVE編號。雖然這些項目大多沒有統計過是否被此漏洞攻陷。
Groovy 編譯器


Apache Groovy是在JVM上做開發最流行的替代品之一,也容易受到攻擊。在撰寫本文時,根據Tiobe索引,Groovy在世界​編程語言中受歡迎程度排名第19。與Kotlin類似,Groovy編譯器的buildscript類路徑有通過HTTP解析的依賴關係。這也導致了工件被破壞的可能性。

幸運的是,構建Groovy編譯器的引導編譯器完全用Java編寫,因此受“Trusting Trust”攻擊的可能性非常小。
此外,我還發現Groovy的Eclipse插件易受攻擊。

Hadoop
Apache Hadoop有超過193個貢獻者,成爲貢獻者最多的項目。所有貢獻者在他們機器上運行的Hadoop構建都可能被MITM攻陷。
Kafka
Apache Kafka最初由LinkedIn團隊編寫,是一個快速的事件代理。LinkedIn在內部使用Kafka,每天攝取的信息條數已經超過1萬億條。我發現Kafka的構建系統是通過HTTP而不是HTTPS加載Gradle插件。

Apache其他項目
我發現,易受攻擊的Apache項目包括但不限於以下項目:Casandra、Geode、Storm、Bigtop、Fink、OpenJPA、Royal Compiler和Airavata。

Jenkins

Jenkins在全球有超過100萬用戶,是使用最廣泛的開源自動化服務器。

Jenkins社區宣佈2017年的紀錄增長和創新

Jenkins被用作自託管的CI管道,用於自動構建和測試軟件。Jenkins和許多Jenkins官方插件都附帶了通過HTTP下載的依賴項。

Spring

我在spring-security-oauth項目發現了第一個(漏洞)位置。Spring項目是我開始研究基於Maven的第一個項目,因此不得不找了一種完全不同的搜索方法,用來通過GitHub搜索功能檢查Maven POM文件。我一開始尋找,就發現這個漏洞存在於Spring組織下的許多其他項目中。

Spring團隊立即做出響應,開始修補他們的所有項目。因受Pivotal項目重度影響,Pivotal開發了一個工具,用以查找和替換整個代碼庫中所有使用HTTP的地方。該工具在此:
spring-io/nohttp

Red Hat

這個漏洞還影響了Red Hat維護的許多項目。這些項目包括但不限於Hibernate ORM、RestEasy和Wildfly(舊稱JBoss)生態系統中的許多項目。

Eclipse基金會

與Red Hat和Apache基金會類似,漏洞也影響了Eclipse基金會的項目Vorto、Buildship、xtext、Orion和Birt。

Oracle

此漏洞還影響了Oracle的一些開源項目,包括VisualVM、PGQL、OpenGrok和Helidon。

測試庫和框架

一些非常流行的JVM測試庫和框架也很容易受到攻擊,包括TestNG、Spock和PowerMock。

其他項目

其他項目,包括Grails、FasterJacksonXML和Ehcache3的Scala模塊也發現了此漏洞。此外,我在網飛(Netflix)、谷歌、Twitter、美國國家安全局(NSA)、Stripe、Gluon(Scene Builder)PortSwigger、Black Duck、Snyk、LinkedIn和PayPal的開源項目中也發現了這個漏洞。諷刺的是,當我向PayPal的安全團隊提交問題報告漏洞時,他們關閉了這個問題,因爲他們認爲MITM “超出了他們的HackerOne計劃範圍”。

MITM的常見程度如何?

我對常見的MITM的初步研究,源於我研究惡意破壞XML的解析器。這些解析器加載了通過HTTP加載的DTD文件,以實現XXE。相關信息以後找機會另寫文章詳述。我發現MITM的常見程度相當驚人。

互聯網服務提供商

令我驚訝的是,互聯網服務提供商(ISP)似乎經常做MITM。

康卡斯特開始向我在互聯網上請求的頁面注入400多行JavaScript代碼,以便當瀏覽器渲染頁面時,用JavaScript生成彈出窗口,向我推銷新的調制解調器。

引用自:康卡斯特持續將自己的代碼注入您訪問的網站

印度的Bharat Sanchar Nigam Limited(BSNL)也曾將廣告注入用戶通過HTTP訪問的網頁。

這就說明,MITM的基礎條件早已具備,稍加利用就能影響JAR文件。

惡意行爲者

當惡意行爲者獲得對系統的訪問權限時,他們通常會迅速利用新的立足點來建立MITM。Verizon每年都會發布數據泄露調查報告(Data Breach Investigation Report,DBIR),分析每年最常被利用的各種攻擊媒介。下面引用自他們的一份報告。

行爲
三大威脅行爲是黑客入侵、惡意軟件和社會工程學。最常見的黑客入侵行爲的類型是使用被盜的登錄憑據、利用後門程序和中間人(man-in-the-middle,即MITM的全寫)攻擊。
引用自: Verizon 2011數據違規調查報告;第69頁

引用自該報告的分析:

我推測,一旦黑客已在系統中立足,MITM就比較次要了。但荷蘭高科技犯罪部門的數據顯示,MITM本身就值得關注的——在他們統計到的32個數據泄露事件中,有15個涉及MITM行爲。
引用自:Stack Exchange上的回答:“中間人”攻擊極爲罕見嗎?

應把MITM攻擊視爲軟件安全中確定存在的威脅。

通過公共WiFi連接

拋開所有其他攻擊媒介,開發人員通過公共WiFi從事這些項目的工作,都等同於放開了他們的電腦,可能會受到惡意攻擊。這種攻擊可以用著名的Firefox插件Firesheep演示。

WiFi熱點的潛在危害可能會對開發人員產生重大影響,因爲他們很多人會在咖啡店、開發者大會等地方使用公共WiFi。只需要WiFi Pineapple,加上他們電腦未緩存過的依賴就可以感染他們的電腦了。

政府機構

拜斯諾登所賜,我們現在知道了美國政府三個郵件中介(letter agencies)對美國公民進行MITM攻擊的各種方法。

NSA靠跟美國電信公司的祕密合作伙伴關係,誘使目標訪問FoxAcid服務器。作爲Turmoil系統的一部分,NSA將祕密服務器(代號爲Quantum)放置在互聯網骨幹網的關鍵位置,確保它們可以比其他網站更快響應。靠這個速度差,這些服務器可以在合法網站響應之前,模擬成目標要訪問的網站,從而欺騙目標的瀏覽器訪問Foxacid服務器。
引用自: NSA如何使用QUANTUM和FOXACID攻擊Tor/Firefox用戶

以前,由於BGP路由配置錯誤,美國國內的互聯網流量也有過通過國外路由的歷史。

通過HTTP加載的最常見的存儲庫

讓我們看一下使用HTTP的最常見代碼庫的一些統計信息。請注意,這些數字並不精確,可能略微大些,因爲GitHub的搜索本質上是模糊搜索。

Maven中央倉庫(Maven Central)

Maven中央倉庫是JVM生態系統中最常用的工件服務器,是Maven使用的默認工件服務器,是JVM工件託管空間中的第一個主要參與者。

JFrog JCenter

JCenter是Maven中央倉庫的超集。開發人員把他們的工件發佈到JFrog Bintray後,可以請求在此創建他們工件的鏡像。

JFrog Bintray

JFrog Bintray讓開發人員可以爲開源項目免費創建自己的工件服務器。

公司 服務器 URL 使用Maven數 使用Gradle數
Sonatype Maven Central 鏈接 ~4萬 ~5600
Sonatype Maven Central 鏈接 偏斜數據(Skewed Data) ~11800
JFrog JCenter 鏈接 ~15200 ~37200
JFrog Bintray 鏈接 ~7300 ~17300
Pivotal Spring 鏈接 ~187000 ~27000
Sheetsu.com提供

顯然,這是Gradle和Maven項目中廣泛存在的一個安全漏洞。

編寫一個(理論上的)Java庫蠕蟲

作爲一個思維實驗,我草擬了濫用此MITM漏洞來創建Java庫蠕蟲的理論。實驗結果參見此處:
讓咱們寫一個(理論上的)Java庫蠕蟲
若你覺得“太長不看”,簡單說來如下圖:

該漏洞的後果是,在發佈期間使用有MITM漏洞的依賴,可能會讓惡意代碼攻陷構建出來的工件,從而感染下游用戶。

修復過去

對於已經發布的庫,除非這些項目構建是完全可重複的,否則無可奈何。

對於易受此影響的編譯器(Kotlin)、用於測試自己的測試庫(Spock和TestNG)、用於構建自己的構建工具(Gradle),這可能是一個問題,因爲信任鏈已被打破。大多數編譯器都用於編譯自己。有關此主題的更多信息,請參閱Ken Thompson寫的論文《Reflections on Trusting Trust》,這篇相對較短。

修復未來

我認爲像Gradle、Maven和SBT這樣的構建工具,應該默認用HTTPS解析依賴關係,除非用戶明確聲明不用HTTPS。這將迫使用戶明確聲明使用不安全的協議,從而防止不小心寫錯。我向Gradle和Maven都提出了要求實現該功能的提案,鏈接如下,請幫我投個贊成票!

Deprecate HTTP Download by JLLeitschuh · Pull Request #9419 · gradle/gradle

[MNG-6673] Deprecate HTTP Download & Upload - ASF JIRA

代碼倉庫的自動審查

Pivotal開發的nohttp工具可以查找所有出現的HTTP,除了列入白名單的HTTP(比如XML命名空間名稱)。這將確保HTTP不會在其他地方引起問題(比如Gradle Wrapper位置,DTD聲明等)。它可以尋找和替換“HTTP”,並集成在構建裏,確保將來不使用HTTP。
spring-io/nohttp

工件主機將在2020年1月棄用HTTP

隨着此漏洞的範圍變得越來越大,我很快意識到,修復這個漏洞的一些責任在Maven Central和JCenter等工件主機上。我聯繫了兩個最大的工件主機Sonatype(Maven Central)、JFrog(JCenter),以及Pivotal(Spring)、Eclipse Foundation、Jenkins、Red Hat和JetBrains等較小的主機,詢問它們是否願意從2020年1月15日起完全阻止通過HTTP發出的下載請求。

25%的Maven Central下載仍在使用HTTP

JFrog和Pivotal很快就都告訴我他們會跟進。

個人容易受到這種影響嗎?

鑑於我發現許多廣泛使用的開源項目都存在這個漏洞,我建議任何開發JVM軟件的人,都應檢查代碼庫的構建邏輯,以解決使用HTTP依賴的問題。

我需要找什麼?

對於Gradle,你應該尋找像這樣的代碼庫配置。

// 這些依賴項用於整個構建的類路徑
	buildscript {
	    repositories {
	        maven {
	            url 'http://[SOME URL HERE]'
	        }
	    }
	    // ...
	}
	

	// 這些依賴項用作編譯器的輸入,並用於測試的類路徑
	repositories {
	    maven {
	        url 'http://[SOME URL HERE]'
	    }
	}
	// ...
	

	// 這是沒有安全上傳構建工件的一個例子。
	// 若你找到了這個,那麼用於上傳的證書可能就受到了威脅。
	uploadArchives {
	    repositories {
	        mavenDeployer {
	            snapshotRepository(url: 'http://[SOME URL HERE]') {
	                authentication userName: repoUser, password: repoPassword
	            }
	            repository(url: 'http://[SOME URL HERE]') {
	                authentication(userName: repoUser, password: repoPassword);
	            }
	        }
	    }
	}

Gradle開發人員可能還應檢查所有init.gradle腳本,它們在其公司內部分發,但一般不檢入源代碼管理系統。

對於基於Maven的項目,你要尋找像這樣的代碼庫配置。

<!-- 這些依賴項用作編譯器的輸入,並用於測試的類路徑 -->
	<repositories>
	  <repository>
	    <id>[SOME ID]</id>
	    <name>Example insecure repository</name>
	    <url>http://[SOME URL HERE]</url>
	  </repository>
	</repositories>
	
	<!-- ... -->	

	<!-- 這是沒有安全上傳構建工件的一個例子。 -->
	<!-- 若你找到了這個,那麼用於上傳的證書可能就受到了威脅。 -->
	<distributionManagement>
	  <repository>
	    <id>[SOME ID]</id>
	    <name>Example insecure repository</name>
	    <url>http://[SOME URL HERE]</url>
	  </repository>
	</distributionManagement>
	

	<!-- 這些依賴項用於整個構建的類路徑 -->
	<pluginRepositories>
	  <pluginRepository>
	    <id>[SOME ID]</id>
	    <name>Example insecure repository</name>
	    <url>http://[SOME URL HERE]</url>
	  </pluginRepository>
	</pluginRepositories>

Maven開發人員還應該檢查~/.m2/settings.xml文件中的配置,因爲代碼庫憑據通常就存在這裏。

此外,JFrog Artifactory或Sonatype的Nexus的企業用戶,應檢查其服務器的配置,看它們是否通過HTTP創建了其他工件服務器的鏡像。

在JFrog Artifactory中不安全的配置的例子

我已經聯繫了Sonatype和JFrog,要求他們在未來的更新中,對不安全的配置向用戶/管理員提出警告。

JFrog迴應說,該功能已正式成爲他們路線圖的一部分,但還沒有計劃發佈日期。

如果發現此漏洞,該怎麼辦?

要把執行潛在惡意Jar的整個機器(開發機、構建機等)看成可能被攻陷了。這也意味着該機器可以訪問的任何內容(其他項目、憑據、其他主機等)也應該視爲可能被攻陷了。共享工件的緩存,如~/.gradle和~/.m2目錄,其中的Gradle和Maven的緩存工件都應視爲已受污染,應該刪除。爲避免單個易受攻擊的應用程序連累其構建的每個項目,最佳做法是隔離構建。

如果你是易受此攻擊的開源項目的維護者,那麼你有責任審查先前的版本,或提交CVE編號,通知下游用戶可能存在的危害。

結束語

不幸的是,我只能聯繫受此漏洞影響的一小部分項目。你在工作中依賴的許多開源項目可能都容易受此影響。如果你可以,請聯繫你發現的受影響項目,一起保護Java生態系統。

如果你使用開源軟件,或用這些構建工具開發商業軟件,我強烈建議:爲整個軟件供應鏈的安全,請審查你的構建。

特別鳴謝

感謝我聯繫的所有組織中,所有真正令人敬畏的專業安全團隊和項目維護人員。我自己是絕不可能修補所有地方的。其中一些團隊,在我報告後幾小時內就做出迴應,並在第二天就推出修復程序。另外,我要感謝Snyk願意做這些CVE報告的CNA。我還要感謝Max Veytsman創造了Dilettante。用POC使披露流程更加順暢。

深入研究的附註

如果你是一名安全研究人員,並希望在其他Java項目中發現這些安全漏洞,我可能漏了說明我在Github搜索時用的查詢條件,補充如下:

在GitHub搜索功能裏查詢漏洞時可用以下查詢條件

在GITHUB_ORGANIZATION的Gradle構建文件裏搜索使用“http://”之處

https://github.com/search?l=Gradle&q=org%3A[GITHUB_ORGANIZATION]+http%3A%2F%2F&type=Code

在工程的源代碼裏搜索代碼倉庫的通用查詢條件

https://github.com/search?q=org%3A[GITHUB_ORGANIZATION]+repositories&type=Code

在Gradle Builds裏搜索的特殊查詢條件

https://github.com/search?l=Gradle&q=org%3A[GITHUB_ORGANIZATION]+repositories&type=Code

在Maven POM文件裏搜索的特殊查詢條件

https://github.com/search?l=Maven+POM&q=org%[GITHUB_ORGANIZATION]+repositories&type=Code
https://github.com/search?l=Maven+POM&q=org%[GITHUB_ORGANIZATION]+repository&type=Code

如果你用這些查詢條件在某項目中發現此問題,請指回本文。

檢查發佈版本異同的工具

原文鏈接:

https://medium.com/bugbountywriteup/want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-1fc329d898fb

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章