PackJ (発音パッケージ)は、ソフトウェアのサプライチェーン攻撃を緩和するのに役立つツールです。 NPM、Rubygems、Pypiなどの人気のあるオープンソースパッケージレジストリから、悪意のある、脆弱な、放棄された、タイプミスのスケート、およびその他の「危険な」パッケージを検出できます。ノイズを最小限に抑えるために簡単にカスタマイズできます。 PackJは博士課程の研究プロジェクトとしてスタートし、現在、さまざまな政府助成金の下で開発されています。
自己ホストされたPackJ WebServerと今月後半にいくつかの統合に注意してください。最新の状態を保つには、このレポをご覧ください。
複数の展開モデルをサポートしています。
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 Marketplaceの表示。例の例。
PackJを試す/テストする最も簡単な方法は、Dockerを使用することです。ポッドマンは、コンテナ化された(孤立)実行にもサポートされています。
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パッケージレジストリからのパッケージを検証できます。錆とPHPのサポートはWIPです。レジストリのサポートを積極的に追加しています。また、ローカル(未発表)NPMおよびPYPIパッケージの審査をサポートしています。
| レジストリ | 生態系 | サポート |
|---|---|---|
| npm | JavaScript | ✅ |
| ピピ | Python | ✅ |
| 貨物 | さび | ✅ |
| Rubygems | ルビー | ✅ |
| パッケージスト | Php | ✅ |
| Docker | Docker | |
| ヌゲット | 。ネット | ✅ |
| メイベン | Java | ✅ |
| cocoapods | 迅速 |
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コンテナでも実行できます。危険な属性と監査READMEでの使用方法の詳細をご覧ください。
PackJは、パッケージをsafe installationための軽量のサンドボックスを提供します。具体的には、悪意のあるパッケージが機密データを除去したり、機密ファイル(SSHキーなど)にアクセスしたり、マルウェアの持続を防ぎます。
ネイティブのコンプライレンスを含む、インストール時間スクリプトをサンドボックスします。 Straceを使用します(つまり、VM/コンテナは必要ありません)。
サンドボックスメカニズムとSandbox ReadMeでの使用方法の詳細をご覧ください。
$ 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; Dr Packjは、博士号の研究プロジェクトとして始まりました。さまざまな政府の助成金に支えられています。
PackJは、学術研究プロジェクトとして始まりました。具体的には、PackJが使用する静的コード分析手法は、Georgia Techの研究グループによる最先端のサイバーセキュリティ研究:Maloss Projectに基づいています。
PackJは、NSF、GRA、およびAlinNovateからの寛大な助成金に支えられています。
TL; DR最先端の脆弱性スキャナーは、サードパーティのオープンソースコードが良性であると仮定しています。したがって、そのようなツールはすべて、良性コードの偶発的なプログラミングバグ(log4jなどのCVE)からの脅威にのみ対処します。彼らは、依存関係の混乱、タイプミススクッティング、抗議(妨害)、アカウントハイジャック、および社会的工学など、供給チャネルの新しい脆弱性を使用して悪いアクターによって伝播される意図的に悪い(別名悪意のある)コードから、太陽光のような最新のソフトウェア供給チェーン攻撃から保護しません。最近の(Dec'22)例は、依存関係の混乱の脆弱性を使用して侵害されたPytorchパッケージです(CVEが割り当てられていません)。
PACKJは、CVEの監査だけでなく、深い静的+動的コード分析とメタデータチェックを実行して、シェルの産卵、SSHキーの使用、GitHubコード対パッケージコード(出所)の不一致、2FAの不足、その他の「リスクのある」動作と属性を検出します。このような不安定な属性は、CVEのように適格ではないため、既存のツールはどれもフラグを立てることができません。 PackJは、ソフトウェアサプライチェーンの悪意のある、タイプミススクッティング、放棄された、脆弱な、およびその他の不安定な依存関係(弱いリンク)にフラグを立てることができます。
現在のソフトウェアサプライチェーンの脅威モデルは、サードパーティのオープンソースコードが良性であると想定しているため、セキュリティの脆弱性は偶発的なプログラミングバグ(別名CVE)に対してのみ追跡されます。そのため、すべての既存のオープンソースの脆弱性スキャナーは、公的に既知のCVEを報告し、良性コードの偶発的なバグからの脅威に対処します。
偶発的なプログラミングバグの典型的な例は、ユーザー入力の境界チェックの欠落であり、これにより、コードはバッファオーバーフロー攻撃に対して脆弱になります。実際の人気のある例には、log4jとheartbleedが含まれます。攻撃者は、トリガーCVE(ハートベッドまたは数値的に高い入力の場合の細工されたTCP/IPパケットなどのトリガーCVEを開発する必要があります。 CVEは、ライブラリの新しいバージョンにパッチを適用またはアップグレードすることで修正できます(例えば、log4jの新しいバージョンがCVEを修正します)。
SolarWinds攻撃の後、最新のソフトウェアサプライチェーンの脅威の景観がシフトしました。悪い俳優は新しい脆弱性を発見しましたが、今回はコードではなく供給チャネルで。依存関係の混乱、タイプミススクッティング、抗議ウェア(妨害)、アカウントハイジャック、ソーシャルエンジニアリングなどのこれらの新しい脆弱性は、マルウェアを伝播するために活用されています。何千もの侵害されたNPM/PYPI/ルビーパッケージが報告されています。
CVEとは対照的に、マルウェアは意図的に悪い(悪意のある)コードです。さらに、マルウェア自体はエクスプロイトであり、新しいバージョンにアップグレードすることでパッチを適用または修正することはできません。たとえば、依存関係の混乱攻撃は意図的に悪意がありました。コードの偶発的なプログラミングバグを悪用しませんでした。同様に、戦争に抗議するために独自のコードを妨害する人気のあるパッケージの著者は非常に意図的であり、CVEを悪用しません。 Typo-Squattingは、不良俳優が人気のオープンソースパッケージレジストリでマルウェアを伝播するために使用する別の攻撃ベクトルです。コード内の偶発的なプログラミングバグやCVEではなく、開発者のタイプミスと未熟さを悪用します。
既存のスキャナーは、意図的に脆弱な(悪意のある)コードから、これらの太陽光のような最新のソフトウェア供給鎖攻撃を検出できません。これらのツールは、オープンソースの依存関係のソースコードを単にスキャンし、使用されているすべての依存関係のリストをコンパイルし、各<依存関係名、依存関係バージョン>をデータベース(例えば、NVD)で確認して、影響を受けるパッケージバージョン(log4jの脆弱なバージョン、libslバージョンの脆弱なバージョン)を確認します。
PACKJは、CVEの監査だけでなく、深い静的+動的コード分析とメタデータチェックを実行して、シェルの産卵、SSHキーの使用、GitHubコード対パッケージコード(出所)の不一致、2FAの不足、その他の「リスクのある」動作と属性を検出します。このような不安定な属性は、CVEのように適格ではないため、既存のツールはどれもフラグを立てることができません。 PackJは、ソフトウェアサプライチェーンの悪意のある、タイプミススクッティング、放棄された、脆弱な、およびその他の不安定な依存関係(弱いリンク)にフラグを立てることができます。詳細については、audit readmeをご覧ください
PackJは、脅威モデルに簡単にカスタマイズ(ゼロノイズ)できます。リポジトリ/プロジェクトのトップ監督に.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にリストされています。
PackJツールまたはオープンソースソフトウェアサプライチェーン攻撃の詳細については、私たちを参照してください
時計 ?このレポは最新の状態を保ちます。
機能またはサポートリクエストがありますか? GitHubディスカッションページにアクセスするか、Discordコミュニティに参加してディスカッションとリクエストをご覧ください。
PackJは、Ossillate Inc.のサイバーセキュリティ研究者と外部協力者によって開発され、開発者が信頼できないサードパーティのオープンソースソフトウェアの依存関係を調達する際に、サプライチェーン攻撃のリスクを軽減するのに役立ちました。開発者と協力者に感謝します。あなたが私たちの仕事が好きなら私たちに与えてあなたの感謝を示してください。
腕を組んでコードの貢献を歓迎します。 Convributing.MDガイドラインを参照してください。バグを見つけましたか?問題を開いてください。 Security.MDガイドラインを参照して、セキュリティの問題を報告してください。
PackJは現在、NPM、PYPI、およびRubyGemsパッケージを「リスクのある」属性のパッケージに免除できます。錆のサポートを追加しています。
PackJは、包括的な監査のために静的コード分析、動的トレース、およびメタデータ分析を使用します。静的分析だけでは、コードの難読化を使用してそれ自体をよりよく隠すことができる洗練されたマルウェアにフラグを立てるのに十分ではありません。動的分析は、 straceの下にパッケージをインストールし、ランタイムの動作を監視することにより実行されます。詳細については、audit readmeをご覧ください。
これは非常に一般的な悪意のある動作です。 PackJは、コードの難読化とシェルコマンドの産卵(Exec System Call)を検出します。たとえば、PackJは「ランタイムコード生成」を示すため、 getattr()およびeval() APIの使用にフラグを立てることができます。開発者は、その後、より深く見てみることができます。詳細については、main.pyを参照してください。