PackJ (發音包裝)是一種幫助減輕軟件供應鏈攻擊的工具。它可以發現惡意,脆弱,廢棄的,錯別字,以及來自諸如NPM,RubyGems和PYPI等流行的開源軟件包註冊表中的其他“風險”套件。它可以輕鬆自定義以最大程度地減少噪聲。 PackJ最初是一項博士研究項目,目前正在各種政府贈款下開發。
注意自我託管的PackJ Web服務器和本月晚些時候的幾個集成?觀看此存儲庫,以保持最新狀態。
我們支持多個部署模型:
使用PackJ在拉請請求中審核依賴項。
- name : Packj Security Audit
uses : ossillate-inc/[email protected]
with :
# TODO: replace with your dependency files in the repo
DEPENDENCY_FILES : pypi:requirements.txt,npm:package.json,rubygems:Gemfile
REPO_TOKEN : ${{ secrets.GITHUB_TOKEN }}在Github市場上查看。示例公關運行。
嘗試/測試PackJ的最快方法是使用Docker。 Podman還支持容器化(隔離)運行。
docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help
克隆這個倉庫,
git clone https://github.com/ossillate-inc/packj.git && cd packj
安裝依賴項
bundle install && pip3 install -r requirements.txt
從幫助開始:
python3 main.py --help
Packj可以審查NPM,PYPI,Rust,PHP和RubyGems軟件包註冊表的Pub套裝。生鏽和PHP支持是WIP。我們正在積極增加對註冊表的支持。它還支持審查本地(未發表)NPM和PYPI軟件包。
| 註冊表 | 生態系統 | 支持 |
|---|---|---|
| NPM | JavaScript | ✅ |
| PYPI | Python | ✅ |
| 貨物 | 銹 | ✅ |
| 紅寶石 | 紅寶石 | ✅ |
| Packagist | php | ✅ |
| Docker | Docker | |
| nuget | 。網 | ✅ |
| 小牛 | 爪哇 | ✅ |
| 可可錄 | 迅速 |
PackJ提供以下工具:
PackJ審核“風險”屬性的開源軟件包,使其容易受到供應鏈攻擊的影響。例如,具有過期電子郵件域(缺少2FA),較大的釋放時間差距,敏感API或訪問權限等的軟件包被標記為風險。
支持以下審核:
python3 main.py audit -p pypi:requests rubygems:overcommitpython3 main.py audit -f npm:package.json pypi:requirements.txt默認情況下, audit僅執行靜態代碼分析以檢測風險代碼。您也可以PAAS -t或--trace標誌也可以執行動態代碼分析,該分析將在strace下安裝所有請求的軟件包,並監視軟件包的安裝時間行為。請參閱下面的示例輸出。
$ docker run -v /tmp:/tmp/packj -it ossillate/packj:latest audit --trace -p npm:browserify
[+] Fetching 'browserify' from npm..........PASS [ver 17.0.0]
[+] Checking package description.........PASS [browser-side require() the node way]
[+] Checking release history.............PASS [484 version(s)]
[+] Checking version........................RISK [702 days old]
[+] Checking release time gap............PASS [68 days since last release]
[+] Checking author.........................PASS [[email protected]]
[+] Checking email/domain validity.......RISK [expired author email domain]
[+] Checking readme.........................PASS [26838 bytes]
[+] Checking homepage.......................PASS [https://github.com/browserify/browserify#readme]
[+] Checking downloads......................PASS [2M weekly]
[+] Checking repo URL.......................PASS [https://github.com/browserify/browserify]
[+] Checking repo data...................PASS [stars: 14189, forks: 1244]
[+] Checking if repo is a forked copy....PASS [original, not forked]
[+] Checking repo description............PASS [browser-side require() the node.js way]
[+] Checking repo activity...............PASS [commits: 2290, contributors: 207, tags: 413]
[+] Checking for CVEs.......................PASS [none found]
[+] Checking dependencies...................RISK [48 found]
[+] Downloading package from npm............PASS [163.83 KB]
[+] Analyzing code..........................RISK [needs 3 perm(s): decode,codegen,file]
[+] Checking files/funcs....................PASS [429 files (383 .js), 744 funcs, LoC: 9.7K]
[+] Installing package and tracing code.....PASS [found 5 process,1130 files,22 network syscalls]
=============================================
[+] 5 risk(s) found, package is undesirable!
=> Complete report: /tmp/packj_54rbjhgm/report_npm-browserify-17.0.0_hlr1rhcz.json
{
"undesirable": [
"old package: 702 days old",
"invalid or no author email: expired author email domain",
"generates new code at runtime",
"reads files and dirs",
"forks or exits OS processes",
]
}
警告:由於軟件包可以在安裝過程中執行惡意代碼,因此建議僅在Docker容器或虛擬機內運行時僅使用
-t或--trace。
審核也可以在Docker/Podman容器中進行。請查找有關風險屬性以及如何在審核讀數中使用的詳細信息。
PackJ提供了輕巧的沙箱,可safe installation包裝。具體而言,它可以防止惡意軟件包剝落敏感數據,訪問敏感文件(例如,SSH鍵)和持續惡意軟件。
它的沙盒安裝時間腳本,包括任何本機補充。它使用strace (即無需VM/容器)。
請查找有關沙箱機制以及如何在沙盒式填充物中使用的詳細信息。
$ python3 main.py sandbox gem install overcommit
Fetching: overcommit-0.59.1.gem (100%)
Install hooks by running `overcommit --install` in your Git repository
Successfully installed overcommit-0.59.1
Parsing documentation for overcommit-0.59.1
Installing ri documentation for overcommit-0.59.1
#############################
# Review summarized activity
#############################
[+] Network connections
[+] DNS (1 IPv4 addresses) at port 53 [rule: ALLOW]
[+] rubygems.org (4 IPv6 addresses) at port 443 [rule: IPv6 rules not supported]
[+] rubygems.org (4 IPv4 addresses) at port 443 [rule: ALLOW]
[+] Filesystem changes
/
└── home
└── ubuntu
└── .ruby
├── gems
│ ├── iniparse-1.5.0 [new: DIR, 15 files, 46.6K bytes]
│ ├── rexml-3.2.5 [new: DIR, 77 files, 455.6K bytes]
│ ├── overcommit-0.59.1 [new: DIR, 252 files, 432.7K bytes]
│ └── childprocess-4.1.0 [new: DIR, 57 files, 141.2K bytes]
├── cache
│ ├── iniparse-1.5.0.gem [new: FILE, 16.4K bytes]
│ ├── rexml-3.2.5.gem [new: FILE, 93.2K bytes]
│ ├── childprocess-4.1.0.gem [new: FILE, 34.3K bytes]
│ └── overcommit-0.59.1.gem [new: FILE, 84K bytes]
├── specifications
│ ├── rexml-3.2.5.gemspec [new: FILE, 2.7K bytes]
│ ├── overcommit-0.59.1.gemspec [new: FILE, 1.7K bytes]
│ ├── childprocess-4.1.0.gemspec [new: FILE, 1.8K bytes]
│ └── iniparse-1.5.0.gemspec [new: FILE, 1.3K bytes]
├── bin
│ └── overcommit [new: FILE, 622 bytes]
└── doc
├── iniparse-1.5.0
│ └── ri [new: DIR, 119 files, 131.7K bytes]
├── rexml-3.2.5
│ └── ri [new: DIR, 836 files, 841K bytes]
├── overcommit-0.59.1
│ └── ri [new: DIR, 1046 files, 1.5M bytes]
└── childprocess-4.1.0
└── ri [new: DIR, 272 files, 297.8K bytes]
[C]ommit all changes, [Q|q]uit & discard changes, [L|l]ist details:
TL; PackJ博士最初是一個博士研究項目。它得到了各種政府贈款的支持。
PackJ最初是一個學術研究項目。具體而言,PackJ使用的靜態代碼分析技術基於最先進的網絡安全研究:Maloss項目由我們的研究小組在佐治亞理工學院的研究小組。
PackJ由NSF,GRA和Alinnovate的慷慨贈款支持。
TL; DR最先進的漏洞掃描儀假定第三方開源代碼是良性的。因此,所有此類工具都只能解決良性代碼中意外編程錯誤的威脅(又稱cves,例如log4j)。它們不能防止像太陽風一樣的現代軟件供應鏈攻擊免受故意糟糕的(又名惡意)代碼,該代碼是由壞演員在供應渠道中使用新漏洞傳播的,包括供應渠道,包括依賴性混亂,錯別字,抗議軟件(Sabotaging),帳戶劫持和社交工程。最近的(DEC'22)示例是Pytorch軟件包,它使用依賴性混亂漏洞(未分配CVE)妥協。
PackJ不僅對CVE進行了審核,而且還執行深層靜態+動態代碼分析以及元數據檢查以檢測任何“風險”的行為和屬性,例如殼產卵,使用SSH鍵,不匹配Github代碼與包裝代碼(源代碼),缺乏2FA等。這種不安全的屬性不符合CVE的資格,這就是為什麼現有工具無法標記它們的原因。 Packj可以在軟件供應鏈中標記惡意,錯別字,廢棄,脆弱和其他不安全的依賴關係(弱鏈接)。
當前的軟件供應鏈威脅模型假設第三方開源代碼是良性的,因此,僅針對意外編程錯誤(又名CVE)跟踪安全漏洞。因此,所有現有的開源漏洞掃描儀僅報告公開已知的CVE,並解決良性代碼中意外錯誤的威脅。
意外編程錯誤的一個典型示例是缺少對用戶輸入的界限,這使得代碼容易受到緩衝溢出攻擊。現實世界中的流行示例包括log4j和Heartbleed。攻擊者需要開發一個漏洞來觸發CVE(例如,在Heartbleed或數值高輸入的情況下製作的TCP/IP數據包以引起緩衝區溢出)。 CVE可以通過修補或升級到庫的較新版本來修復(例如,Log4J的較新版本修復了CVE)。
現代軟件供應鏈威脅景觀在Solarwinds攻擊後發生了變化。壞演員發現了新的漏洞,但是這次是在供應渠道,而不是代碼。這些新的漏洞,例如依賴性混亂,錯別字,抗議軟件(破壞),帳戶劫持和社會工程,以傳播惡意軟件。據報導,數以千計的NPM/PYPI/RUBY軟件包已被報導。
與CVE相比,惡意軟件故意不好(又稱惡意)代碼。此外,惡意軟件本身是一種利用,無法通過升級到較新版本來修補或修復。例如,依賴混亂攻擊是故意惡意的。它沒有利用代碼中的任何意外編程錯誤。同樣,流行包裹破壞自己的代碼以抗議戰爭的作者是非常有意的,並且沒有利用任何CVE。 Typo-squatting是另一個攻擊向量,不良演員用來在流行的開源軟件包註冊表中傳播惡意軟件:它利用開發人員的錯別字和不經驗,而不是偶然的編程錯誤或代碼中的CVE。
現有的掃描儀未能從故意脆弱的(惡意)代碼中檢測出這些類似於太陽能的現代軟件供應鏈攻擊。這些工具只需掃描源代碼以獲取開源依賴項,編譯所使用的所有依賴項列表,然後在數據庫(例如,NVD)中查看每個依賴性依賴性<依賴項,依賴關係 - version-version>以報告影響的軟件包版本(例如,log4j的Log4J,Libssl版本的libssl版本受到了Heartbleded的影響)。
PackJ不僅對CVE進行了審核,而且還執行深層靜態+動態代碼分析以及元數據檢查以檢測任何“風險”的行為和屬性,例如殼產卵,使用SSH鍵,不匹配Github代碼與包裝代碼(源代碼),缺乏2FA等。這種不安全的屬性不符合CVE的資格,這就是為什麼現有工具無法標記它們的原因。 Packj可以在軟件供應鏈中標記惡意,錯別字,廢棄,脆弱和其他不安全的依賴關係(弱鏈接)。請在審核讀書中閱讀更多
可以輕鬆自定義PackJ(零噪聲),以對您的威脅模型進行定制。只需在您的回購/項目的頂部DIR中添加.packj.yaml文件,然後通過評論不需要的屬性來減少警報疲勞。
我們使用此工具分別在PYPI和RubyGems上發現了40多個惡意包裹。其中許多被拆除。請參閱下面的示例:
$ python3 main.py audit pypi:krisqian
[+] Fetching 'krisqian' from pypi...OK [ver 0.0.7]
[+] Checking version...OK [256 days old]
[+] Checking release history...OK [7 version(s)]
[+] Checking release time gap...OK [1 days since last release]
[+] Checking author...OK [[email protected]]
[+] Checking email/domain validity...OK [[email protected]]
[+] Checking readme...ALERT [no readme]
[+] Checking homepage...OK [https://www.bilibili.com/bangumi/media/md140632]
[+] Checking downloads...OK [13 weekly]
[+] Checking repo_url URL...OK [None]
[+] Checking for CVEs...OK [none found]
[+] Checking dependencies...OK [none found]
[+] Downloading package 'KrisQian' (ver 0.0.7) from pypi...OK [1.94 KB]
[+] Analyzing code...ALERT [needs 3 perms: process,network,file]
[+] Checking files/funcs...OK [9 files (2 .py), 6 funcs, LoC: 184]
=============================================
[+] 6 risk(s) found, package is undesirable!
{
"undesirable": [
"no readme",
"only 45 weekly downloads",
"no source repo found",
"generates new code at runtime",
"fetches data over the network: ['KrisQian-0.0.7/setup.py:40', 'KrisQian-0.0.7/setup.py:50']",
"reads files and dirs: ['KrisQian-0.0.7/setup.py:59', 'KrisQian-0.0.7/setup.py:70']"
]
}
=> Complete report: pypi-KrisQian-0.0.7.json
=> View pre-vetted package report at https://packj.dev/package/PyPi/KrisQian/0.0.7
PackJ標記為Krisqian(V0.0.7)是可疑的,這是由於缺乏源回購,並且在包裝安裝時間(setup.py)期間使用敏感API(網絡,代碼生成)。我們決定更深入地看一下,發現包裹惡意。請在https://packj.dev/malware/krisqian上找到我們的詳細分析。
我們發現的更多惡意軟件示例在https://packj.dev/malware上列出,請通過[email protected]與我們聯繫以獲取完整列表。
要了解有關PackJ工具或開源軟件供應鏈攻擊的更多信息,請參閱我們的
手錶 ?此存儲庫保持最新狀態。
有功能或支持請求嗎?請訪問我們的GitHub討論頁面或加入我們的Discord社區以進行討論和請求。
PackJ是由Ossillate Inc.和外部合作者的網絡安全研究人員開發的,可以幫助開發人員在採購不受信任的第三方開源軟件依賴性時減輕供應鏈攻擊的風險。我們感謝開發人員和合作者。如果您喜歡我們的工作,請通過給我們來表示讚賞。
我們歡迎用張開雙臂貢獻代碼。請參閱貢獻。 MD指南。找到一個錯誤?請打開一個問題。請參閱我們的Security.MD指南以報告安全問題。
PackJ當前可以獸醫vet NPM,PYPI和RubyGems軟件包,以獲得“風險”屬性。我們正在增加對生鏽的支持。
PackJ使用靜態代碼分析,動態跟踪和元數據分析進行全面審核。僅靜態分析就不足以標記複雜的惡意軟件,可以使用代碼混淆可以更好地隱藏自身。通過在strace下安裝軟件包並監視其運行時行為來執行動態分析。請在Audit Readme上閱讀更多信息。
這是一種非常常見的惡意行為。 PACKJ檢測代碼混淆以及Shell命令的產卵(Exec System Call)。例如,PackJ可以標記使用getattr()和eval() API表示“運行時代碼生成”;開發人員可以去更深入地看。有關詳細信息,請參見Main.py。