軟件供應(yīng)鏈攻擊的特征是向軟件包中注入惡意代碼,以破壞供應(yīng)鏈下游的相關(guān)系統(tǒng)。近年來(lái),許多供應(yīng)鏈攻擊在軟件開發(fā)過(guò)程中充分利用了開放源代碼的使用, 這是由依賴項(xiàng)管理器(dependency managers)提供的,它在整個(gè)軟件生命周期中自動(dòng)解析,下載和安裝數(shù)百個(gè)開放源代碼包,從而促進(jìn)了供應(yīng)鏈攻擊。
本文介紹了174個(gè)惡意軟件包的數(shù)據(jù)集,這些數(shù)據(jù)包在開源軟件供應(yīng)鏈的真實(shí)攻擊中使用,并通過(guò)流行的軟件包存儲(chǔ)庫(kù)npm、PyPI和RubyGems分發(fā),對(duì)2015年11月至2019年11月的軟件包進(jìn)行了手動(dòng)收集和分析。
本文還提出了兩種通用攻擊樹,以提供有關(guān)將惡意代碼注入下游用戶的依賴樹以及在不同時(shí)間和不同條件下執(zhí)行此類代碼的技術(shù)的結(jié)構(gòu)化概述。這項(xiàng)工作旨在促進(jìn)開源和研究社區(qū)在未來(lái)發(fā)展的預(yù)防和保障措施。
01Introduction
通常,軟件供應(yīng)鏈攻擊旨在將惡意代碼注入到軟件產(chǎn)品中。攻擊者經(jīng)常篡改給定供應(yīng)商的最終產(chǎn)品,以使其帶有有效的數(shù)字簽名,因?yàn)樵摂?shù)字簽名是由相應(yīng)的供應(yīng)商簽名的,并且可以由最終用戶通過(guò)受信任的分發(fā)渠道(例如分銷商)獲得,即網(wǎng)站下載或更新。
此類供應(yīng)鏈攻擊的一個(gè)突出例子是NotPetya,這是一種被隱藏在流行的烏克蘭會(huì)計(jì)軟件的惡意更新中的勒索軟件。2017年,NotPetya目標(biāo)是烏克蘭公司,但也打擊了全球的公司,造成了數(shù)十億美元的損失,據(jù)說(shuō)是當(dāng)今已知的最具破壞性的網(wǎng)絡(luò)攻擊之一。同年,可從供應(yīng)商的官方網(wǎng)站下載惡意版本的CCleaner(一種適用于Microsoft Windows系統(tǒng)的流行維護(hù)工具),并且超過(guò)一個(gè)月沒(méi)有被發(fā)現(xiàn)。在此期間,它被下載了約230萬(wàn)次。
供應(yīng)鏈攻擊的另一種形式是將惡意代碼注入到軟件供應(yīng)商產(chǎn)品的依賴項(xiàng)中。這種攻擊媒介已經(jīng)由Elias Levy在2003年進(jìn)行了預(yù)測(cè),并且近年來(lái)隨著該方案的出現(xiàn),出現(xiàn)了許多實(shí)際攻擊。這種攻擊成為可能,因?yàn)楝F(xiàn)代軟件項(xiàng)目通常依賴于多個(gè)開源程序包,這些程序包本身引入了許多可傳遞的依賴關(guān)系。這種攻擊濫用了開發(fā)人員對(duì)托管在常用服務(wù)器上的軟件包的真實(shí)性和完整性的信任,并濫用了鼓勵(lì)這種做法的自動(dòng)構(gòu)建系統(tǒng)。
數(shù)千個(gè)開源軟件項(xiàng)目可能需要單個(gè)開源軟件包,這使得開源軟件包成為軟件供應(yīng)鏈攻擊的非常有吸引力的目標(biāo)。最近對(duì)npm軟件包event-stream的攻擊表明了此類攻擊的潛在范圍:只需通過(guò)要求原始開發(fā)人員接管其維護(hù)工作,即可將所謂的攻擊者授予顯著npm軟件包的所有權(quán)。當(dāng)時(shí),event-stream還被另外1600個(gè)軟件包使用,平均每周被下載150萬(wàn)次。
開源軟件供應(yīng)鏈攻擊可與易受攻擊的開源軟件包的問(wèn)題相提并論,后者可能會(huì)將其漏洞傳遞給相關(guān)的軟件項(xiàng)目,這屬于OWASP 前10應(yīng)用程序安全風(fēng)險(xiǎn)之一。但是,在供應(yīng)鏈攻擊的情況下,會(huì)故意注入惡意代碼,攻擊者會(huì)采用混淆和規(guī)避技術(shù)來(lái)避免被人或程序分析工具檢測(cè)到。
02Methodology
相關(guān)工作主要涉及易受攻擊的程序包,這些程序包包含偶然引入的設(shè)計(jì)缺陷或代碼錯(cuò)誤,沒(méi)有惡意。但由于疏忽大意,可能構(gòu)成潛在的安全風(fēng)險(xiǎn)。與此相反,惡意軟件包包含故意的設(shè)計(jì)缺陷或代碼錯(cuò)誤,這些缺陷或代碼錯(cuò)誤在軟件生命周期中被謹(jǐn)慎的加以利用或觸發(fā)。
區(qū)分易受攻擊的軟件包和惡意軟件包很重要。如前所述,易受攻擊的軟件包可能包含設(shè)計(jì)缺陷或代碼錯(cuò)誤,這些缺陷或代碼錯(cuò)誤是無(wú)意間但由于疏忽而意外引入的,并且可能構(gòu)成潛在的安全風(fēng)險(xiǎn)。
從技術(shù)上講,惡意和易受攻擊的編碼可能相似甚至相同,因此,主要區(qū)別在于攻擊者的意圖。這項(xiàng)工作有兩個(gè)方面的作用:使用攻擊樹對(duì)可能的攻擊進(jìn)行系統(tǒng)描述,以及在實(shí)際攻擊中使用的惡意軟件包數(shù)據(jù)集。攻擊樹能夠表示對(duì)系統(tǒng)的攻擊。攻擊的主要目標(biāo)用作根節(jié)點(diǎn),子節(jié)點(diǎn)代表實(shí)現(xiàn)該目標(biāo)的可能方法。
第一個(gè)攻擊樹的目的是將惡意代碼注入下游用戶的軟件供應(yīng)鏈,而第二個(gè)攻擊樹的目的是在不同情況下觸發(fā)其惡意行為。手動(dòng)分析每個(gè)惡意軟件包和信息源,并在提供足夠信息的情況下將其映射到每個(gè)攻擊樹的節(jié)點(diǎn)。如果不存在擬合節(jié)點(diǎn),則添加一個(gè)新節(jié)點(diǎn)。這種迭代方法確保攻擊樹的節(jié)點(diǎn)代表現(xiàn)實(shí)的攻擊向量。但是,該方法的缺點(diǎn)是這些樹不完整,因?yàn)樗鼈儾环从成形从^察到或未描述的攻擊媒介。
在此期間,對(duì)漏洞數(shù)據(jù)庫(kù)Snyk、特定于語(yǔ)言的安全建議和研究博客進(jìn)行了審查,以確定惡意包和可能的攻擊向量。注意,這些來(lái)源僅提及軟件包的名稱和受影響的版本,因此,實(shí)際的惡意代碼必須從其他來(lái)源下載。但是,這種惡意程序包通常在相應(yīng)編程語(yǔ)言的標(biāo)準(zhǔn)程序包存儲(chǔ)庫(kù)中不再可用,例如npm或PyPI。
相反,在可能的情況下,它們是從不推薦使用的鏡像,互聯(lián)網(wǎng)檔案和公共研究資料庫(kù)中檢索到的。如果可以檢索到惡意軟件包的代碼,則會(huì)對(duì)其進(jìn)行手動(dòng)分析和分類。這樣做是為了確認(rèn)軟件包的惡意軟件,將其映射到現(xiàn)有的攻擊樹或在必要時(shí)進(jìn)行擴(kuò)展。軟件包的惡意版本的發(fā)布日期根據(jù)Libraries.io(該服務(wù)可監(jiān)視所有主要軟件包存儲(chǔ)庫(kù)中軟件包的發(fā)布)而定。咨詢和公共事件報(bào)告可用于對(duì)惡意程序包進(jìn)行公開披露。
03Threat Analysis and Attack Trees
本節(jié)從高層次介紹與開源軟件開發(fā)項(xiàng)目相關(guān)的活動(dòng)和系統(tǒng)開始,并以兩個(gè)攻擊樹為結(jié)尾。本屆的攻擊樹是基于在野觀察到的實(shí)際惡意軟件包以及安全研究人員和從業(yè)人員描述的潛在攻擊和弱點(diǎn)以迭代方式創(chuàng)建的。
通常,攻擊樹允許對(duì)針對(duì)任何類型的系統(tǒng)的攻擊進(jìn)行系統(tǒng)的描述。因此,給定樹的根節(jié)點(diǎn)對(duì)應(yīng)于攻擊者的頂級(jí)目標(biāo),子節(jié)點(diǎn)代表實(shí)現(xiàn)此目標(biāo)的替代方法。攻擊樹的頂級(jí)目標(biāo)是將惡意代碼注入軟件供應(yīng)鏈,從而注入開發(fā)項(xiàng)目的依存關(guān)系,并在不同情況下觸發(fā)該惡意代碼。
A、開源開發(fā)項(xiàng)目
在如上圖所示的典型開發(fā)環(huán)境中,維護(hù)者是開發(fā)項(xiàng)目的成員,他們管理所描述的系統(tǒng),提供,審查和批準(zhǔn)文稿,定義和觸發(fā)構(gòu)建過(guò)程。開源項(xiàng)目還從貢獻(xiàn)者那里獲得代碼貢獻(xiàn),維護(hù)者可以對(duì)其進(jìn)行審查并合并到項(xiàng)目的代碼庫(kù)中。
構(gòu)建過(guò)程(build process)將攝取項(xiàng)目的源代碼和其他資源,并且其目標(biāo)是產(chǎn)生軟件工件。這些工件隨后被發(fā)布,以使它們可供最終用戶和其他開發(fā)項(xiàng)目使用。
項(xiàng)目資源位于版本控制系統(tǒng)(VCS)中,例如Git,并將其復(fù)制到構(gòu)建系統(tǒng)的本地文件系統(tǒng)中。在這些資源中有直接依賴項(xiàng)的聲明,在構(gòu)建過(guò)程開始時(shí),依賴項(xiàng)管理器會(huì)對(duì)其進(jìn)行分析,以建立具有所有直接和傳遞性依賴項(xiàng)的完整依賴項(xiàng)樹。由于在構(gòu)建期間(例如,在編譯時(shí)或在測(cè)試執(zhí)行期間)都需要它們,因此它們是從軟件包存儲(chǔ)庫(kù)中下載的,這些存儲(chǔ)庫(kù)包括用于Python的PyPI,用于Node.js的npm或用于Java的Maven Central。
在成功構(gòu)建的最后,程序代碼和其他資源被組合到一個(gè)或多個(gè)構(gòu)建工件中,這些工件可能會(huì)被簽名并最終發(fā)布。要么是諸如應(yīng)用商店之類的分發(fā)平臺(tái),以便最終用戶可以使用它們,要么將其打包為其他開發(fā)項(xiàng)目的存儲(chǔ)庫(kù)。
這樣的項(xiàng)目環(huán)境受眾多信任邊界的約束,并且許多威脅都針對(duì)各自的數(shù)據(jù)流,數(shù)據(jù)存儲(chǔ)和流程。即使僅考慮單個(gè)軟件項(xiàng)目的環(huán)境,管理這些威脅也可能具有挑戰(zhàn)性。當(dāng)考慮具有數(shù)十個(gè)或數(shù)百個(gè)依賴項(xiàng)的供應(yīng)鏈時(shí),要注意每個(gè)單獨(dú)的依賴項(xiàng)都存在這樣的環(huán)境。顯然,此類項(xiàng)目的組合攻擊面比完全由內(nèi)部開發(fā)的軟件要大得多。
從攻擊者的角度出發(fā),惡意行為者打算通過(guò)感染一個(gè)或多個(gè)上游開源軟件包來(lái)?yè)p害軟件項(xiàng)目的構(gòu)建或運(yùn)行時(shí)環(huán)境的安全性,每個(gè)上游開源軟件包均在與上圖相當(dāng)?shù)沫h(huán)境中開發(fā)。在以下各節(jié)中,將通過(guò)兩個(gè)攻擊樹來(lái)描述實(shí)現(xiàn)此目標(biāo)的方法,這兩個(gè)攻擊樹提供了有關(guān)攻擊路徑的結(jié)構(gòu)化概述,這些攻擊路徑用于將惡意代碼注入下游用戶的依賴樹并在不同時(shí)間或不同條件下觸發(fā)其執(zhí)行。
B、注入惡意代碼
上圖所示的攻擊樹的最高目標(biāo)是將惡意代碼注入到下游軟件包的依賴樹中。因此,一旦具有惡意代碼的軟件包在分發(fā)平臺(tái)(例如,分發(fā)平臺(tái))上可用,就可以實(shí)現(xiàn)該目標(biāo)。軟件包存儲(chǔ)庫(kù)成為一個(gè)或多個(gè)其他軟件包的直接或傳遞依賴項(xiàng)。這樣,這種類型的代碼注入不同于其他注入攻擊,其中許多攻擊在應(yīng)用程序運(yùn)行時(shí)利用安全漏洞,例如,安全漏洞。由于缺乏用戶輸入清理功能而可能導(dǎo)致緩沖區(qū)溢出攻擊。要將軟件包注入依賴樹中,攻擊者可能會(huì)采用兩種可能的策略,即感染現(xiàn)有軟件包或提交新軟件包。
顯然,使用其他人未使用的名稱開發(fā)和發(fā)布新的惡意程序包可以避免干擾其他合法項(xiàng)目維護(hù)者。但是,此類程序包必須由下游用戶發(fā)現(xiàn)并引用,以便最終進(jìn)入受害者程序包的依賴關(guān)系樹中。這可以通過(guò)使用與現(xiàn)有軟件包名稱類似的名稱(搶注)或通過(guò)開發(fā)和推廣木馬病毒來(lái)實(shí)現(xiàn)。攻擊者還可能借此機(jī)會(huì)重用由其原始的合法維護(hù)者撤回的現(xiàn)有項(xiàng)目,程序包或用戶帳戶的標(biāo)識(shí)符(免費(fèi)使用)。
第二種策略是感染已經(jīng)具有用戶、貢獻(xiàn)者和維護(hù)者的現(xiàn)有軟件包。攻擊者可能出于各種原因選擇軟件包,例如大量或特定的下游用戶組。但是,到目前為止收集的數(shù)據(jù)尚無(wú)法驗(yàn)證相應(yīng)的假設(shè)。一旦攻擊者選擇了要感染的軟件包,就可以將惡意代碼注入到源中,在構(gòu)建過(guò)程中或注入到軟件包存儲(chǔ)庫(kù)中。
開源項(xiàng)目通過(guò)社區(qū)的貢獻(xiàn)來(lái)生存和奮斗,因此,攻擊者可以模仿良性的項(xiàng)目貢獻(xiàn)者。例如,攻擊者可能通過(guò)創(chuàng)建帶有錯(cuò)誤修復(fù)或看似有用的功能或依賴項(xiàng)的拉取請(qǐng)求(PR)來(lái)假裝解決現(xiàn)有問(wèn)題。后者可以用來(lái)創(chuàng)建對(duì)使用先前描述的技術(shù)從頭創(chuàng)建的攻擊者-控制器程序包的依賴關(guān)系。無(wú)論如何,此PR必須由合法的項(xiàng)目維護(hù)者批準(zhǔn)并合并到主代碼分支中。或者攻擊者可能會(huì)通過(guò)使用脆弱或受到破壞的憑據(jù)或?qū)Π踩舾械腁PI令牌將攻擊者的全部惡意代碼提交給項(xiàng)目的代碼庫(kù)。
此外,攻擊者可以通過(guò)社會(huì)工程成為維護(hù)者。在任何情況下,無(wú)論惡意代碼如何添加到源中,無(wú)論在哪里進(jìn)行構(gòu)建,它都將在下一個(gè)發(fā)行版本中成為正式軟件包的一部分。與對(duì)構(gòu)建系統(tǒng)和軟件包存儲(chǔ)庫(kù)的攻擊相比,VCS中的惡意代碼更易于手動(dòng)或自動(dòng)查看提交或整個(gè)存儲(chǔ)庫(kù)。
構(gòu)建系統(tǒng)的折衷通常需要篡改在整個(gè)構(gòu)建過(guò)程中使用的資源,例如編譯器,構(gòu)建插件或網(wǎng)絡(luò)服務(wù)(例如代理或DNS服務(wù)器)。如果構(gòu)建系統(tǒng)(無(wú)論是開發(fā)人員的工作站還是Jenkins之類的構(gòu)建服務(wù)器)容易受到漏洞攻擊,或者如果通信渠道不安全以致攻擊者可以操縱從存儲(chǔ)庫(kù)中下載軟件包,這些資源可能會(huì)受到損害。目標(biāo)軟件包的發(fā)布版本也可以在共享的構(gòu)建系統(tǒng)上運(yùn)行,因此可以被多個(gè)項(xiàng)目使用。
根據(jù)設(shè)置的不同,此類構(gòu)建過(guò)程可能不是孤立運(yùn)行的,因此,包緩存或構(gòu)建插件之類的資源會(huì)在不同項(xiàng)目的構(gòu)建之間共享。在這種情況下,攻擊者可能會(huì)在其控制下的惡意構(gòu)建項(xiàng)目期間破壞共享資源,從而使目標(biāo)項(xiàng)目在以后的時(shí)間點(diǎn)受到破壞。
即使是流行的軟件包系統(tǒng)信息庫(kù),也仍然會(huì)遭受簡(jiǎn)單但嚴(yán)重的安全漏洞。盡管所有其他攻擊媒介都試圖將惡意代碼注入到單個(gè)程序包中,但利用程序包存儲(chǔ)庫(kù)中的漏洞本身會(huì)使帶有其所有程序包的整個(gè)存儲(chǔ)庫(kù)處于危險(xiǎn)之中。
類似于在源代碼中注入代碼,攻擊者可能會(huì)使用脆弱或受到破壞的憑據(jù)或通過(guò)社會(huì)工程獲得維護(hù)者授權(quán),以發(fā)布合法版本的惡意版本。由于前者已被用于多種攻擊中,因此諸如核心基礎(chǔ)設(shè)施(Core Infrastructure Initiative)的徽章計(jì)劃之類的計(jì)劃向項(xiàng)目維護(hù)者提供了正式建議,以啟用雙因素身份驗(yàn)證。
此外,攻擊者可能會(huì)將惡意程序包版本上載到原始維護(hù)者未提供的備用存儲(chǔ)庫(kù)或存儲(chǔ)庫(kù)鏡像,并等待受害者從那里獲取依賴關(guān)系。據(jù)說(shuō)此類存儲(chǔ)庫(kù)和鏡像不那么受歡迎,攻擊取決于受害者的配置,例如查詢依賴關(guān)系或使用鏡像的存儲(chǔ)庫(kù)順序。
C、執(zhí)行惡意代碼
一旦某個(gè)項(xiàng)目的依賴關(guān)系樹中存在惡意代碼,上圖所示的攻擊樹就具有在不同條件下觸發(fā)惡意代碼的頂級(jí)目標(biāo)。這樣的條件可以用來(lái)逃避對(duì)特定用戶和系統(tǒng)的檢測(cè)和/或目標(biāo)攻擊。
惡意代碼可能在受感染的軟件包及其下游用戶的不同生命周期階段觸發(fā)。如果測(cè)試用例中包含惡意代碼,則攻擊主要針對(duì)被感染程序包的貢獻(xiàn)者和維護(hù)者,他們?cè)谄溟_發(fā)人員工作站和構(gòu)建系統(tǒng)上運(yùn)行此類測(cè)試。
在許多記錄的攻擊中,惡意代碼被包含在安裝腳本里,安裝腳本在軟件包安裝期間由下游用戶或其依賴關(guān)系管理器自動(dòng)執(zhí)行。此類安裝腳本適用于Python和Node.js,可用于執(zhí)行安裝前或安裝后活動(dòng)。安裝腳本中的惡意代碼使下游程序包的提供者和維護(hù)者及其最終用戶受到威脅。惡意代碼也可能在下游程序包的運(yùn)行時(shí)觸發(fā),這要求將其作為受害者程序包的常規(guī)控制流的一部分進(jìn)行調(diào)用。
在Python中,這可以通過(guò)在init .py中包含惡意代碼來(lái)實(shí)現(xiàn),該惡意代碼通過(guò)import語(yǔ)句調(diào)用。在JavaScript中,這可以通過(guò)猴子補(bǔ)丁(monkey-patching)等現(xiàn)有方法來(lái)實(shí)現(xiàn)。細(xì)化此目標(biāo)可以輕松涵蓋各個(gè)編程語(yǔ)言,程序包管理器等的細(xì)節(jié)。
與生命周期階段無(wú)關(guān),惡意行為的執(zhí)行可能總是觸發(fā)(無(wú)條件的)或僅在滿足某些條件時(shí)(有條件的執(zhí)行)觸發(fā)。對(duì)于任何其他惡意軟件,條件執(zhí)行會(huì)使惡意開源軟件包的動(dòng)態(tài)檢測(cè)復(fù)雜化,因?yàn)樵谏诚洵h(huán)境中可能無(wú)法理解或滿足相應(yīng)條件。以應(yīng)用程序狀態(tài)為條件的執(zhí)行是逃避檢測(cè)的常見(jiàn)手段,例如在測(cè)試環(huán)境或?qū)S玫膼阂廛浖治錾诚渲小M瑯樱鱾€(gè)構(gòu)建系統(tǒng)的細(xì)節(jié)可能會(huì)包含在各自的子目標(biāo)中,例如Jenkins環(huán)境變量的存在表明惡意代碼是在構(gòu)建期間而不是在生產(chǎn)環(huán)境中觸發(fā)的。
此外,條件可能與特定的受害者包有關(guān),例如檢查特定的應(yīng)用程序狀態(tài),例如加密錢包的余額。大量重復(fù)使用開放源代碼軟件包可能導(dǎo)致以下事實(shí):惡意軟件包最終出現(xiàn)在許多下游軟件包的依賴關(guān)系樹中。如果攻擊者只對(duì)某些軟件包感興趣,則它們可能會(huì)在手邊給定依賴關(guān)系樹的節(jié)點(diǎn)上限制代碼執(zhí)行。此外,所使用的操作系統(tǒng)可以作為條件。
05Description of the Dataset
總共可以識(shí)別469個(gè)惡意軟件包。此外,還發(fā)現(xiàn)了59個(gè)可被確認(rèn)為POC的軟件包(由研究人員發(fā)布),因此不再進(jìn)行進(jìn)一步檢查。最終,能夠?yàn)?74個(gè)軟件包獲得至少一個(gè)受影響的版本。Npm的惡意軟件包成功下載率為109/374(29.14%),PyPI為28/44(63.64%),RubyGems為37/41(90.24%)和Maven Central為0/10(0.00%)。
A、組成和結(jié)構(gòu)
該數(shù)據(jù)集包含在npm上發(fā)布的62.6%的程序包,因此是用JavaScript為Node.js編寫的。其余的軟件包通過(guò)PyPI(16.1%,Python)和RubyGems(21.3%,Ruby)發(fā)布。不幸的是,無(wú)法下載針對(duì)Android開發(fā)人員的惡意Java軟件包。對(duì)于PHP,根本無(wú)法識(shí)別任何惡意軟件包。
完整的數(shù)據(jù)集可在GitHub上免費(fèi)獲得:https://dasfreak.github.io/Backstabbers-Knife-Collection。出于道德原因,僅在有正當(dāng)理由的情況下才允許訪問(wèn)。數(shù)據(jù)集的結(jié)構(gòu)如下:package-manager/package-name/version/package.file。惡意軟件包在第一級(jí)由其原始軟件包管理器分組。此外,一個(gè)軟件包的多個(gè)受影響版本會(huì)在相應(yīng)軟件包名稱下。事件流受影響版本示例:npm/event-stream/3.3.6/event-stream-3.3.6.tgz。
B、時(shí)間方面
上圖可視化了收集到的軟件包的發(fā)布日期,范圍從2015年11月到2019年11月。發(fā)布和披露日期是根據(jù)軟件包的上載時(shí)間和相應(yīng)通報(bào)的發(fā)布日期來(lái)標(biāo)識(shí)的,這些通報(bào)將相應(yīng)版本標(biāo)識(shí)為惡意。顯然,已發(fā)布的惡意軟件包數(shù)量呈增長(zhǎng)趨勢(shì)。雖然已知用于PyPI的惡意程序包可以追溯到2015年,并且此后一直在增加,但npm在2017年獲得了大量惡意程序包,而RubyGems上的惡意程序包在2019年經(jīng)歷了最高點(diǎn)。
上圖顯示在被公開報(bào)告之前,平均有209天的惡意軟件包可用(min=-1,max= 1216,ρ= 258,x= 67)。盡管知道npm/eslint-scope/3.7.2的感染,但由于開發(fā)人員的重新打包策略,該軟件包仍在使用中。npm/rpc-websocket/0.7.7最大值達(dá)到了1,216天,它接管了一個(gè)廢棄的軟件包,很長(zhǎng)時(shí)間沒(méi)有被發(fā)現(xiàn)。
總的來(lái)說(shuō),這表明軟件包傾向于長(zhǎng)期可用。雖然PyPI的平均在線時(shí)間最高,但該時(shí)間段的npm變化最大,而RubyGems傾向于更及時(shí)地檢測(cè)到惡意軟件包。
C、惡意行為的觸發(fā)
程序包的惡意行為可能在與程序包交互的不同點(diǎn)觸發(fā)。最典型地,可以安裝、測(cè)試或執(zhí)行軟件包。每個(gè)軟件包存儲(chǔ)庫(kù)的分離如下圖所示。它說(shuō)明了在安裝過(guò)程中對(duì)任意代碼的錯(cuò)誤處理會(huì)產(chǎn)生使用最多的感染媒介。
顯然,大多數(shù)惡意軟件包(56%)會(huì)在安裝時(shí)啟動(dòng)其例程。這可以由軟件包存儲(chǔ)庫(kù)的安裝命令觸發(fā),例如npm install
與此相反,Ruby沒(méi)有實(shí)現(xiàn)這種安裝邏輯,Ruby中不存在該情況的軟件包。因此,在RubyGems上找到的所有包都將運(yùn)行時(shí)用作觸發(fā)器。總體而言,有43%的程序包在程序運(yùn)行時(shí)(即從其他函數(shù)調(diào)用時(shí))暴露了其惡意行為。
對(duì)于1%的軟件包,測(cè)試程序被用作觸發(fā)器。調(diào)用npm/ladder-text-js/1.0.0的測(cè)試?yán)虒?zhí)行sudo rm-rf / *,這可能會(huì)刪除所有文件。
D、有條件的執(zhí)行
如上圖所示,有41%的軟件包在檢查條件之前會(huì)觸發(fā)進(jìn)一步的執(zhí)行。這可能取決于應(yīng)用程序的狀態(tài),例如檢查主應(yīng)用程序是否處于生產(chǎn)模式(例如RubyGems/paranoid2/1.1.6),域名的可解析性(例如npm/logsymbles/2.2.0)或加密錢包中包含的金額(例如npm/flatmap- stream/0.1.1)。
其他技術(shù)是檢查依賴關(guān)系樹中是否存在另一個(gè)軟件包(例如npm/load-from-cwd-or-npm/3.0.2)或該軟件包是否在某個(gè)操作系統(tǒng)上執(zhí)行(例如PyPI / libpeshka / 0.6)。
在PyPI和RubyGems上發(fā)布的大多數(shù)軟件包都是無(wú)條件執(zhí)行的。對(duì)于npm,條件執(zhí)行和無(wú)條件執(zhí)行的比率幾乎相等。
E、注入惡意軟件包
在上圖中,很明顯,大多數(shù)(61%)惡意軟件包都是通過(guò)域名搶注來(lái)模仿現(xiàn)有軟件包的名稱的。對(duì)該現(xiàn)象的更深入分析顯示,平均搶注程序包到目標(biāo)的Levenshtein距離為2.3(,,min= 0,max= 11,ρ= 2.05,x= 1.0)。在某些情況下,可以從其他軟件包存儲(chǔ)庫(kù)中獲得搶注目標(biāo)。完全相同名稱的Linux軟件包系統(tǒng)信息庫(kù)apt。例如python-sqlite就是這種情況。在以kafka-python為目標(biāo)的pythonkafka的情況下,最大距離為11。常用的技術(shù)是添加或刪除連字符,省略單個(gè)字母或交換經(jīng)常被錯(cuò)誤鍵入的字母。經(jīng)常被針對(duì)的單詞是,,color”或與之對(duì)應(yīng)的英式英語(yǔ)單詞,,color”。
第二種最常見(jiàn)的注入方法是感染現(xiàn)有包裝。這通常可以通過(guò)存儲(chǔ)庫(kù)系統(tǒng)的憑據(jù)受損(例如npm/eslint-scope/3.7.2)來(lái)實(shí)現(xiàn)。在大多數(shù)情況下,無(wú)法回顧確切的感染技術(shù)。這是因?yàn)橄嚓P(guān)的來(lái)源通常會(huì)從版本控制系統(tǒng)中刪除,或者沒(méi)有進(jìn)一步公開有關(guān)注入的詳細(xì)信息。因此,這些軟件包被列為感染現(xiàn)有軟件包。
另一種注入技術(shù)是創(chuàng)建一個(gè)新軟件包,其中僅包含木馬惡意軟件包。在這些軟件包中找不到有意義的拼寫搶注目標(biāo)。這些軟件包可以與受感染的現(xiàn)有軟件包結(jié)合使用,也可以獨(dú)立使用。
F、主要目標(biāo)
如下圖所示,大多數(shù)軟件包都針對(duì)數(shù)據(jù)滲透。通常,感興趣的數(shù)據(jù)是/etc/passwd,~/.ssh/*,~/.npmrc或~/.bash歷史記錄的內(nèi)容。此外,惡意程序包試圖泄漏環(huán)境變量(其中可能包含訪問(wèn)令牌)和常規(guī)系統(tǒng)信息。另一個(gè)流行的目標(biāo)是語(yǔ)音和文本聊天應(yīng)用程序Discord的令牌。Discord用戶的帳戶可能會(huì)鏈接到信用卡信息,因此可用于財(cái)務(wù)欺詐。
此外,有34%的軟件包充當(dāng)Dropper來(lái)下載第二階段的有效負(fù)載。另有5%的用戶利用后門(即反彈shell)到遠(yuǎn)程服務(wù)器,并等待進(jìn)一步的說(shuō)明。3%的目的是通過(guò)用fork炸彈和文件刪除(例如npm/destroyer-of-worlds/1.0.0)耗盡資源或破壞其他軟件包的功能(npm/load-from-cwd-or-npm/3.0.2)。3%將財(cái)務(wù)收益作為主要目標(biāo),如在后臺(tái)運(yùn)行加密礦工(npm/hooka-tools / 1.0.0)或直接竊取加密貨幣(例如pip/colourama/0.1.6)。另外,可能會(huì)發(fā)生上述目標(biāo)的組合。
G、目標(biāo)操作系統(tǒng)
為了識(shí)別目標(biāo)操作系統(tǒng),對(duì)源代碼進(jìn)行了手動(dòng)分析,以獲得可能像if platform.system() is “Windows”一樣構(gòu)造的提示,例如使用PyPI/openvc/1.0.0 或者通過(guò)依賴僅在某些OS上可用的資源而隱含的。這些資源可能是包含敏感信息的文件,如.bashrc等(npm/font-scrubber/1.2.2)或可執(zhí)行文件,如/bin/sh(npm/rpc-websocket/0.7.11)。
對(duì)針對(duì)其目標(biāo)操作系統(tǒng)(OS)的軟件包的分析表明,大多數(shù)軟件包(53%)是不可知的,即不依賴于操作系統(tǒng)特定的功能。該分析是對(duì)程序包的初始可見(jiàn)代碼進(jìn)行的,因此第二階段有效負(fù)載的目標(biāo)OS仍然未知。但是,由于構(gòu)建環(huán)境通常是在此類OS上運(yùn)行的,因此與Unix類似的系統(tǒng)似乎比Windows和macOS更具針對(duì)性。
只有一種已知的macOS案例是目標(biāo),其中軟件包npm/angluar-cli/0.0.1通過(guò)刪除和修改macOS的McAfee病毒掃描程序?qū)acOS進(jìn)行拒絕服務(wù)攻擊。
H、混淆
惡意行為者經(jīng)常試圖掩蓋其代碼的存在,即阻礙其被肉眼看到。在數(shù)據(jù)集中將近一半的軟件包(49%)采用了某種混淆處理。大多數(shù)情況下,使用不同的編碼(Base64或Hex)來(lái)掩蓋惡意功能或可疑變量(例如域名)的存在。
良性軟件包經(jīng)常使用的一種壓縮源代碼并節(jié)省帶寬的技術(shù)是最小化的。但是,這對(duì)于惡意行為者來(lái)說(shuō)是一個(gè)機(jī)會(huì),可以潛入人類無(wú)法讀取的額外代碼(例如npm/tensorplow/1.0.0)。隱藏變量的另一種方法是使用字符串采樣。這需要一個(gè)看似隨機(jī)的字符串,該字符串用于通過(guò)逐個(gè)字母的選擇來(lái)重建有意義的字符串(例如npm/ember-power-timepicker/1.0.8)。
在一種情況下,惡意功能被加密隱藏。軟件包npm/flatmap-stream/0.1.1利用AES256和目標(biāo)軟件包的簡(jiǎn)短描述作為解密密鑰。這樣,惡意行為僅在目標(biāo)軟件包使用時(shí)才暴露出來(lái)。此外,存在上述技術(shù)的組合。
I、群集
為了推斷攻擊活動(dòng)的存在,對(duì)所有軟件包進(jìn)行了分析,以重新使用惡意代碼或依賴關(guān)系。這樣,有可能識(shí)別出21個(gè)群集,至少有兩個(gè)程序包具有相同的惡意代碼,或者由攻擊者控制的程序包依賴于另一個(gè)具有實(shí)際惡意代碼的程序包,這些群集至少有兩個(gè)。總共174個(gè)軟件包中的157個(gè)(占90%)屬于一個(gè)集群。平均而言,群集包括7.28個(gè)程序包(min= 2,max= 36,ρ= 8.96,x = 3)。
對(duì)一個(gè)群集中的包裝的出版物發(fā)布日期進(jìn)行交叉比較發(fā)現(xiàn),發(fā)布之間的平均時(shí)間間隔為42天,618(min=140,max= 353天,1102,ρ= 78天,010,x = 7天,1551)。最大的集群形成在crossenv的36個(gè)軟件包,平均時(shí)間間隔為5.98天。它分兩期發(fā)布,2017年7月19日在15分鐘內(nèi)發(fā)布了11個(gè)軟件包,2017年8月1日在30分鐘內(nèi)發(fā)布了另外25個(gè)軟件包。
發(fā)布日期間隔為353天的集群由兩個(gè)軟件包PyPI/jeilyfish /0.7.0和PyPI/python3-dateutil /2.9.1組成。第一次發(fā)布于18/12/11 12:26 AM,其中包含的代碼可以下載腳本以從Windows計(jì)算機(jī)中竊取SSH和GPG密鑰。直到第二個(gè)軟件包在19/29/19 11:43 AM發(fā)布之后很長(zhǎng)時(shí)間都未被檢測(cè)到,該軟件包本身并不包含惡意代碼,但引用了第一個(gè)軟件包。在19/12/19 05:53 PM被報(bào)告并刪除了該群集。
盡管大多數(shù)群集只包含一個(gè)軟件包存儲(chǔ)庫(kù)中的軟件包,但是可以找到一個(gè)群集,其中主要包含npm中的軟件包,以及RubyGems中的RubyGems/active-support/5.2.0。這意味著存在攻擊活動(dòng),或者至少技術(shù)跨多個(gè)軟件包存儲(chǔ)庫(kù)流動(dòng)。
J、兩個(gè)惡意軟件包的代碼審查
根據(jù)對(duì)代碼相似性的手動(dòng)評(píng)估,上圖的npm/jqeury/3.3.1(左)和RubyGems/active-support/5.2.0(右)都屬于同一集群,即使它們發(fā)布在不同的存儲(chǔ)庫(kù)中。
06Conclution
從攻擊者的角度來(lái)看,程序包存儲(chǔ)庫(kù)代表了可靠且可擴(kuò)展的惡意軟件分發(fā)渠道。到目前為止,Node.js(npm)和Python(PyPI)的存儲(chǔ)庫(kù)是惡意軟件包的主要目標(biāo),這可能是由于在軟件包安裝過(guò)程中可以輕松觸發(fā)惡意代碼這一事實(shí)。已經(jīng)存在許多可以由不同利益相關(guān)者實(shí)施的對(duì)策,例如面向開放源代碼維護(hù)者的多因素身份驗(yàn)證,面向開放源代碼用戶的版本固定和禁用安裝腳本,或者隔離構(gòu)建過(guò)程和增強(qiáng)構(gòu)建服務(wù)器。
但是,盡管提高了利益相關(guān)者的普遍意識(shí),這種對(duì)策必須更易于訪問(wèn),并且在可能的情況下默認(rèn)實(shí)施,以防止開源軟件供應(yīng)鏈攻擊。
A、結(jié)果
從觀察到的案例和相關(guān)工作中得出了兩個(gè)攻擊樹。一種用于將惡意程序包注入開源生態(tài)系統(tǒng),另一種用于執(zhí)行惡意代碼。這些攻擊樹可對(duì)過(guò)去和將來(lái)的攻擊進(jìn)行系統(tǒng)描述。能夠創(chuàng)建第一個(gè)手動(dòng)管理的惡意開源軟件包的數(shù)據(jù)集,該數(shù)據(jù)包已在現(xiàn)實(shí)世界的攻擊中使用。從2015年11月到2019年11月,它包含174個(gè)惡意軟件包(npm 62.6%,PyPI 16.1%,RubyGems 21.3%)。
手動(dòng)分析顯示,大多數(shù)軟件包(56%)會(huì)在安裝時(shí)觸發(fā)其惡意行為,另有41%使用進(jìn)一步的條件確定是否運(yùn)行。超過(guò)一半的軟件包(61%)利用域名搶注將自身注入到生態(tài)系統(tǒng)中,而數(shù)據(jù)泄露是最常見(jiàn)的目標(biāo)(55%)。這些軟件包通常與操作系統(tǒng)無(wú)關(guān)(53%),并且經(jīng)常采用混淆處理(49%)來(lái)隱藏自身。最終可以通過(guò)不同的編程語(yǔ)言,通過(guò)重用的代碼來(lái)檢測(cè)惡意軟件包的多個(gè)群集。
B、未來(lái)的工作
希望有新的技術(shù)和工具來(lái)掃描整個(gè)程序包存儲(chǔ)庫(kù)中的可疑程序包,例如根據(jù)觀察發(fā)現(xiàn)惡意代碼可在同一廣告系列的程序包甚至語(yǔ)言之間重復(fù)使用。在這種情況下,手動(dòng)管理和標(biāo)記的數(shù)據(jù)集允許有監(jiān)督的學(xué)習(xí)方法,這些方法支持對(duì)惡意軟件包的自動(dòng)化和整個(gè)存儲(chǔ)庫(kù)范圍內(nèi)的搜索。此外,關(guān)于現(xiàn)有和新的緩解策略,本文提出的數(shù)據(jù)集可作為基準(zhǔn)。
審核編輯 :李倩
-
開源軟件
+關(guān)注
關(guān)注
0文章
210瀏覽量
15929 -
源代碼
+關(guān)注
關(guān)注
96文章
2946瀏覽量
66811 -
供應(yīng)鏈
+關(guān)注
關(guān)注
3文章
1677瀏覽量
38950
原文標(biāo)題:開源軟件供應(yīng)鏈攻擊回顧
文章出處:【微信號(hào):談思實(shí)驗(yàn)室,微信公眾號(hào):談思實(shí)驗(yàn)室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論