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。