ossillate-inc/packj
GitHub: ossillate-inc/packj
Packj 是一款专注于软件供应链安全的综合审计工具,旨在通过深度静态分析与动态追踪技术,识别开源依赖包中的恶意代码、潜在漏洞及高风险行为。
Stars: 684 | Forks: 37
#
Packj 标记恶意/高风险的开源软件包
*Packj*(发音同 package)是一款有助于缓解软件供应链攻击的工具。它可以检测来自流行开源软件包仓库(如 NPM、RubyGems 和 PyPI)中的恶意、存在漏洞、已废弃、拼写错误(typo-squatting)以及其他“高风险”软件包。它易于定制,以最大限度地减少噪音。Packj 起源于一个博士研究项目,目前正由多项政府拨款支持开发。
[](https://github.com/ossillate-inc/packj/stargazers)  [](https://github.com/ossillate-inc/packj/blob/main/CONTRIBUTING.md)  [](https://discord.gg/qFcqaV2wYa) [](https://www.gnu.org/licenses/agpl-3.0) [](https://hub.docker.com/r/ossillate/packj/tags)

# 目录
* [开始使用](#get-started) - 提供 Docker 镜像、GitHub Action 和软件包形式
* [功能](#functionality) - 深度静态/动态代码分析和沙箱机制
* [支持的生态系统](#supported-ecosystems) - NPM, PyPI, Rubygems, PHP, Rust
* [我们的故事](#our-story) - 始于博士研究项目,由政府拨款支持
* [为什么选择 Packj](#why-packj) - 现有的 CVE 扫描器假设代码是良性的,且不分析其行为
* [定制化](#customization) - 根据您的威胁模型关闭警报以减少噪音
* [发现的恶意软件](#malware-found) - 报告了超过 70 个恶意的 PyPI 和 RubyGems 包
* [演讲和视频](#resources) - 来自 PyCon, OpenSourceSummit, BlackHAT 的演示
* [项目路线图](#feature-roadmap) - 查看或建议新功能;加入我们的 [discord 频道](https://discord.gg/qFcqaV2wYa)
* [团队与协作](#team-and-contributors) - 由学术界/工业界的网络安全研究人员领导
* [常见问题](#faq) - 支持的包管理器,关于技术的常见问题等
# 开始使用
我们支持多种部署模式:
### GitHub runner
使用 Packj 审计 Pull Request 中的依赖项。
```
- name: Packj Security Audit
uses: ossillate-inc/packj-github-action@v0.0.10-beta
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 [市场](https://github.com/marketplace/actions/packj-security-audit)查看。示例 [PR 运行](https://github.com/ossillate-inc/packj-github-action-demo/pull/3#issuecomment-1274797138)。
### 2. Docker 镜像(推荐)
尝试/测试 Packj 的最快方法是使用 Docker。同时也支持 Podman 进行容器化(隔离)运行。
```
docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help
```
### 3. 源代码仓库
克隆此仓库,
```
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 软件包仓库的已发布软件包。Rust 和 PHP 支持尚在开发中(WIP)。我们正在积极增加对更多仓库的支持。
它还支持审查本地(未发布)的 NPM 和 PyPI 软件包。
| Registry | Ecosystem | Supported |
| --------- | ---------- | ------------------ |
| NPM | JavaScript | :white_check_mark: |
| PyPI | Python | :white_check_mark: |
| Cargo | Rust | :white_check_mark: |
| Rubygems | Ruby | :white_check_mark: |
| Packagist | PHP | :white_check_mark: |
| Docker | Docker | :x: |
| Nuget | .NET | :white_check_mark: |
| Maven | Java | :white_check_mark: |
| Cocoapods | Swift | :x: |
# 功能
Packj 提供以下工具:
* [Audit](#auditing-a-package) - 用于审查软件包的“高风险”属性。
* [Sandbox](#sandboxed-package-installation) - 用于安全地安装软件包。
## 审计软件包
Packj 审计开源软件包中容易遭受供应链攻击的“高风险”属性。例如,电子邮件域名过期(缺少 2FA)、发布时间间隔过长、敏感 API 或访问权限等的软件包会被标记为高风险。
支持审计以下内容:
- 多个软件包:`python3 main.py audit -p pypi:requests rubygems:overcommit`
- 依赖文件:`python3 main.py audit -f npm:package.json pypi:requirements.txt`
默认情况下,`audit` 仅执行静态代码分析以检测高风险代码。您可以传入 `-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 [mail@substack.net]
[+] 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/Podman 容器中执行审计。有关风险属性详情及使用方法,请查看 [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md)。
## 沙箱化软件包安装
Packj 为软件包的“安全安装”提供了轻量级沙箱机制。具体来说,它能防止恶意软件包渗出敏感数据、访问敏感文件(如 SSH 密钥)以及持久化恶意软件。
它对安装时脚本(包括任何原生编译)进行沙箱处理。它使用 **strace**(即**无需**虚拟机/容器)。
有关沙箱机制及使用方法的详情,请查看 [Sandbox README](https://github.com/ossillate-inc/packj/blob/main/packj/sandbox/README.md)。
```
$ 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
#############################
# 审查汇总活动
#############################
[+] 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:
```
# 我们的故事
**简而言之** Packj 起源于一个博士研究项目。它由多项政府拨款支持。
Packj 最初是一个学术研究项目。具体来说,Packj 使用的静态代码分析技术基于尖端的网络安全研究:我们在 Georgia Tech 的研究[小组](http://cyfi.ece.gatech.edu)的 [MalOSS](https://github.com/osssanitizer/maloss) 项目。
Packj 获得了 [NSF](https://www.sbir.gov/node/2083473)、[GRA](https://gra.org/company/227/OSSPolice.html) 和 [ALInnovate](https://innovatealabama.org) 的慷慨资助。
# 为什么选择 Packj
**简而言之** 最先进的漏洞扫描器假设第三方开源代码是良性的(BENIGN)。因此,所有此类工具仅解决良性代码中意外编程错误(即 CVE,如 Log4J)带来的威胁。它们无法防范 Solarwinds 类似的现代软件供应链攻击,这类攻击源于不良行为者利用供应链中的新漏洞(包括依赖混淆、拼写劫持、抗议软件(蓄意破坏)、账户劫持和社会工程学)传播的故意恶意代码(即恶意代码)。最近的一个例子(22 年 12 月)是 PyTorch 软件包因依赖混淆漏洞被攻破(未分配 CVE)。
Packj 不仅审计 CVE,还执行深度静态+动态代码分析以及元数据检查,以检测任何“高风险”行为和属性,例如生成 Shell、使用 SSH 密钥、GitHub 代码与打包代码不匹配(来源追溯)、缺少 2FA 等。这些不安全属性不符合 CVE 标准,这也是现有工具无法标记它们的原因。Packj 可以标记您软件供应链中的恶意、拼写劫持、已废弃、易受攻击以及其他不安全的依赖项(薄弱环节)。
当前的软件供应链威胁模型**假设**第三方开源代码是良性的,因此,只追踪意外编程错误(即 CVE)的安全漏洞。因此,所有现有的开源漏洞扫描器**仅**报告公开已知的 CVE,并解决良性代码中意外错误带来的威胁。
意外编程错误的一个典型例子是缺少对用户输入的边界检查,这使代码容易受到缓冲区溢出攻击。现实世界中流行的例子包括 Log4J 和 HeartBleed。攻击者需要开发漏洞利用程序来触发 CVE(例如,HeartBleed 中精心设计的 TCP/IP 数据包,或导致缓冲区溢出的数值巨大的输入)。CVE 可以通过修补或升级到较新版本的库来修复(例如,较新版本的 Log4J 修复了该 CVE)。
现代软件供应链威胁格局在 Solarwinds 攻击后发生了**转变**。不良行为者发现了新漏洞,但这次是在供应链通道中,而不是代码中。这些新漏洞,如依赖混淆、拼写劫持、抗议软件(蓄意破坏)、账户劫持和社会工程学,正被利用来传播恶意软件。已有数千个受损的 NPM/PyPI/Ruby 软件包被报告。
与 CVE 相比,恶意软件是故意的恶意代码。此外,恶意软件本身就是漏洞利用,无法通过升级到较新版本进行修补或修复。例如,[依赖混淆攻击](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)是故意恶意的;它没有利用代码中的任何意外编程错误。同样,一个流行软件包的作者破坏自己的代码以[抗议](https://en.wikipedia.org/wiki/Peacenotwar)战争,这完全是有意的,并不利用任何 CVE。拼写劫持是不良行为者用来在流行的开源软件包仓库中传播恶意软件的另一种攻击载体:它利用了[开发人员的拼写错误和经验不足](https://discuss.python.org/t/improving-risks-and-consequences-against-typosquatting-on-pypi/5090),而不是代码中的意外编程错误或 CVE。
现有扫描器**无法**检测到这些来自故意易受攻击(恶意)代码的 Solarwinds 式现代软件供应链攻击。这些工具只是扫描开源依赖项的源代码,编译所有正在使用的依赖项列表,并在数据库(例如 NVD)中查找每个 <依赖项-名称, 依赖项-版本>,以报告受影响的软件包版本(例如,Log4J 的易受攻击版本,受 HeartBleed 影响的 LibSSL 版本)。
Packj 不仅审计 CVE,还执行深度静态+动态代码分析以及元数据检查,以检测任何“高风险”行为和属性,例如生成 Shell、使用 SSH 密钥、GitHub 代码与打包代码不匹配(来源追溯)、缺少 2FA 等。这些不安全属性不符合 CVE 标准,这也是现有工具无法标记它们的原因。Packj 可以标记您软件供应链中的恶意、拼写劫持、已废弃、易受攻击以及其他不安全的依赖项(薄弱环节)。请在 [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md#faq) 阅读更多内容
# 定制化
Packj 可以根据您的威胁模型轻松定制(零噪音)。只需在您的仓库/项目的顶层目录中添加一个 [.packj.yaml](https://github.com/ossillate-inc/packj/blob/main/.packj.yaml) 文件,并通过注释掉不需要的属性来减少警报疲劳。
# 发现的恶意软件
我们使用此工具在 PyPI 和 Rubygems 上分别发现了超过 40 个和 20 个恶意软件包。其中许多已被下架。请参考以下示例:
```
$ 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 [KrisWuQian@baidu.com]
[+] Checking email/domain validity...OK [KrisWuQian@baidu.com]
[+] 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/krisqian) 查看我们的详细分析。
我们发现的更多恶意软件示例列在 [https://packj.dev/malware](https://packj.dev/malware)。如需完整列表,请通过 [oss@ossillate.com](mailto:oss@ossillate.com) 联系我们。
# 资源
要了解有关 Packj 工具或开源软件供应链攻击的更多信息,请参考我们的
[](https://www.youtube.com/watch?v=Rcuqn56uCDk)
[](https://www.youtube.com/watch?v=a7BfDGeW_jY)
- PyConUS'22 [演讲](https://www.youtube.com/watch?v=Rcuqn56uCDk)和[幻灯片](https://speakerdeck.com/ashishbijlani/pyconus22-slides)。
- BlackHAT Asia'22 Arsenal [演示](https://www.blackhat.com/asia-22/arsenal/schedule/#mitigating-open-source-software-supply-chain-attacks-26241)
- PackagingCon'21 [演讲](https://www.youtube.com/watch?v=PHfN-NrUCoo)和[幻灯片](https://speakerdeck.com/ashishbijlani/mitigating-open-source-software-supply-chain-attacks)
- BlackHat USA'22 Arsenal 演讲[使用 Packj 检测拼写劫持、后门、已废弃及其他“高风险”开源软件包]( )
- 关于开源软件安全的学术[学位论文](https://cyfi.ece.gatech.edu/publications/DUAN-DISSERTATION-2019.pdf),以及我们在 Georgia Tech 的研究小组发起这项研究的[论文](https://www.ndss-symposium.org/wp-content/uploads/ndss2021_1B-1_23055_paper.pdf)。
- Open Source Summit, Europe'22 演讲[为依赖项评分以检测开源软件供应链中的“薄弱环节”](https://osseu2022.sched.com/overview/type/SupplyChainSecurityCon) - 演讲视频在 [YouTube](https://www.youtube.com/watch?v=a7BfDGeW_jY)
- NullCon'22 演讲[使用 Packj 挖掘恶意及其他“高风险”开源软件包](https://nullcon.net/goa-2022/unearthing-malicious-and-other-risky-open-source-packages-using-packj)
# 功能路线图
* 添加 Rust 分析器。Rust 正在开发中 [预计时间:24 年 2 月]。
* 添加功能以检测多种(待定)“高风险”代码以及元数据属性 [预计时间:24 年 2 月]。
* 自托管 Packj 网络服务器和若干有用的集成(例如 Gitlab runner)[预计时间:24 年 4 月]。
Watch :eyes: 此仓库以保持更新。
有功能或支持请求?请访问我们的 [GitHub 讨论页面](https://github.com/ossillate-inc/packj/discussions/)或加入我们的 [discord 社区](https://discord.gg/qFcqaV2wYa)进行讨论和提出请求。
# 团队和贡献者
Packj 由 [Ossillate Inc.](https://packj.dev/team) 的网络安全研究人员和外部合作者开发,旨在帮助开发人员在获取不受信任的第三方开源软件依赖项时降低供应链攻击的风险。我们要感谢我们的开发人员和合作者。如果您喜欢我们的工作,请给我们一个 :star: 以示支持。
我们张开双臂欢迎代码贡献。请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 指南。发现错误?请开启一个 issue。报告安全问题请参考我们的 [SECURITY.md](SECURITY.md) 指南。
# 常见问题
显示示例运行/输出
```
$ 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 [mail@substack.net]
[+] 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",
]
}
```
显示示例运行/输出
```
$ 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
#############################
# 审查汇总活动
#############################
[+] 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:
```
显示详细回答
Packj 最初是一个学术研究项目。具体来说,Packj 使用的静态代码分析技术基于尖端的网络安全研究:我们在 Georgia Tech 的研究[小组](http://cyfi.ece.gatech.edu)的 [MalOSS](https://github.com/osssanitizer/maloss) 项目。
显示详细回答
当前的软件供应链威胁模型**假设**第三方开源代码是良性的,因此,只追踪意外编程错误(即 CVE)的安全漏洞。因此,所有现有的开源漏洞扫描器**仅**报告公开已知的 CVE,并解决良性代码中意外错误带来的威胁。
意外编程错误的一个典型例子是缺少对用户输入的边界检查,这使代码容易受到缓冲区溢出攻击。现实世界中流行的例子包括 Log4J 和 HeartBleed。攻击者需要开发漏洞利用程序来触发 CVE(例如,HeartBleed 中精心设计的 TCP/IP 数据包,或导致缓冲区溢出的数值巨大的输入)。CVE 可以通过修补或升级到较新版本的库来修复(例如,较新版本的 Log4J 修复了该 CVE)。
现代软件供应链威胁格局在 Solarwinds 攻击后发生了**转变**。不良行为者发现了新漏洞,但这次是在供应链通道中,而不是代码中。这些新漏洞,如依赖混淆、拼写劫持、抗议软件(蓄意破坏)、账户劫持和社会工程学,正被利用来传播恶意软件。已有数千个受损的 NPM/PyPI/Ruby 软件包被报告。
与 CVE 相比,恶意软件是故意的恶意代码。此外,恶意软件本身就是漏洞利用,无法通过升级到较新版本进行修补或修复。例如,[依赖混淆攻击](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)是故意恶意的;它没有利用代码中的任何意外编程错误。同样,一个流行软件包的作者破坏自己的代码以[抗议](https://en.wikipedia.org/wiki/Peacenotwar)战争,这完全是有意的,并不利用任何 CVE。拼写劫持是不良行为者用来在流行的开源软件包仓库中传播恶意软件的另一种攻击载体:它利用了[开发人员的拼写错误和经验不足](https://discuss.python.org/t/improving-risks-and-consequences-against-typosquatting-on-pypi/5090),而不是代码中的意外编程错误或 CVE。
现有扫描器**无法**检测到这些来自故意易受攻击(恶意)代码的 Solarwinds 式现代软件供应链攻击。这些工具只是扫描开源依赖项的源代码,编译所有正在使用的依赖项列表,并在数据库(例如 NVD)中查找每个 <依赖项-名称, 依赖项-版本>,以报告受影响的软件包版本(例如,Log4J 的易受攻击版本,受 HeartBleed 影响的 LibSSL 版本)。
Packj 不仅审计 CVE,还执行深度静态+动态代码分析以及元数据检查,以检测任何“高风险”行为和属性,例如生成 Shell、使用 SSH 密钥、GitHub 代码与打包代码不匹配(来源追溯)、缺少 2FA 等。这些不安全属性不符合 CVE 标准,这也是现有工具无法标记它们的原因。Packj 可以标记您软件供应链中的恶意、拼写劫持、已废弃、易受攻击以及其他不安全的依赖项(薄弱环节)。请在 [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md#faq) 阅读更多内容
显示示例恶意软件
```
$ 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 [KrisWuQian@baidu.com]
[+] Checking email/domain validity...OK [KrisWuQian@baidu.com]
[+] 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 目前可以审查 NPM、PyPI 和 RubyGems 软件包的“高风险”属性。我们正在增加对 Rust 的支持。Packj 采用什么技术来检测高风险/恶意软件包?
Packj 使用静态代码分析、动态追踪和元数据分析进行综合审计。仅靠静态分析不足以标记那些利用代码混淆更好地隐藏自身的复杂恶意软件。动态分析是通过在 `strace` 下安装软件包并监控其运行时行为来执行的。请在 [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md) 阅读更多内容。它能检测混淆调用吗?例如,一个经过 base 64 加密的字符串被解密后传递给 shell?
这是一种非常常见的恶意行为。Packj 可以检测代码混淆以及 shell 命令的生成(exec 系统调用)。例如,Packj 可以标记 `getattr()` 和 `eval()` API 的使用,因为它们表明存在“运行时代码生成”;开发人员随后可以进行深入调查。详情请参见 [main.py](https://github.com/ossillate-inc/packj/blob/main/packj/audit/main.py#L512)。标签:DAST, DevSecOps工具, LNA, NPM安全, PyPI安全, RubyGems安全, Solarwinds攻击防护, Typosquatting检测, 供应链攻击, 依赖包安全审计, 动态沙箱执行, 包管理器安全, 开源安全治理, 开源组件漏洞检测, 恶意依赖识别, 恶意软件分析, 文档安全, 自定义DNS解析器, 请求拦截, 软件供应链安全, 软件开发工具包, 远程方法调用, 逆向工具, 错误基检测, 静态代码分析