PackJ (Prononced Package) est un outil pour aider à atténuer les attaques de chaîne d'approvisionnement logicielles. Il peut détecter des packages malveillants, vulnérables, abandonnés, de typo-squatting et d'autres forfaits "risqués" des registres populaires de packages open source, tels que NPM, Rubygems et PYPI. Il peut être facilement personnalisé pour minimiser le bruit. Packj a commencé comme un projet de recherche de doctorat et est actuellement en cours de développement sous diverses subventions gouvernementales.
Remarque le serveur de ligne d'auto-hébergement et plusieurs intégrations à venir plus tard ce mois-ci? Regardez ce dépôt pour rester à jour.
Nous prenons en charge plusieurs modèles de déploiement:
Utilisez PackJ pour auditer les dépendances dans les demandes de traction.
- 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 }}Voir sur GitHub Marketplace. Exemple PR Run.
Le moyen le plus rapide d'essayer / tester Packj est d'utiliser Docker. Podman est également pris en charge pour les exécutions conteneurisées (isolées).
docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help
Cloner ce repo,
git clone https://github.com/ossillate-inc/packj.git && cd packj
Installer des dépendances
bundle install && pip3 install -r requirements.txt
Commencez par l'aide:
python3 main.py --help
Packj peut vérifier les packages pubus des registres de package NPM, PYPI, Rust, PHP et Rubygems. Le support de rouille et de PHP est WIP. Nous ajoutons activement le soutien aux registres. Il prend également en charge la vérification des packages NPM et PYPI locaux (non publiés).
| Enregistrement | Écosystème | Soutenu |
|---|---|---|
| NPM | Javascrip | ✅ |
| PYPI | Python | ✅ |
| Cargaison | Rouiller | ✅ |
| Rubygems | Rubis | ✅ |
| Packagiste | Php | ✅ |
| Docker | Docker | |
| Nuget | .FILET | ✅ |
| Maven | Java | ✅ |
| Cocoapodes | Rapide |
Packj propose les outils suivants:
Packj audits des packages de logiciels open source pour les attributs "risqués" qui les rendent vulnérables aux attaques de chaîne d'approvisionnement. Par exemple, les packages avec des domaines de messagerie expirés (sans 2FA), un écart temporel de grande envergure, des API sensibles ou des autorisations d'accès, etc. sont signalés comme risqués.
Audit ce qui suit est pris en charge:
python3 main.py audit -p pypi:requests rubygems:overcommitpython3 main.py audit -f npm:package.json pypi:requirements.txt Par défaut, audit effectue une analyse de code statique uniquement pour détecter le code risqué. Vous pouvez également PaaS -t ou --trace Indicateur pour effectuer une analyse de code dynamique, qui installera tous les packages demandés sous Strace et surveillera le comportement de temps d'installation des packages. Veuillez consulter l'exemple de sortie ci-dessous.
$ 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",
]
}
AVERTISSEMENT: Étant donné que les packages peuvent exécuter du code malveillant lors de l'installation, il est recommandé d'utiliser uniquement
-tou--tracelors de l'exécution dans un conteneur Docker ou une machine virtuelle.
L'audit peut également être effectué dans des conteneurs Docker / Podman. Veuillez trouver des détails sur les attributs risqués et comment utiliser chez Audit Readme.
Packj offre un sable léger pour safe installation d'un package. Plus précisément, il empêche les packages malveillants d'exfiltrant des données sensibles, l'accès à des fichiers sensibles (par exemple, les clés SSH) et les logiciels malveillants persistants.
Il sablet des scripts d'installation, y compris toute complication native. Il utilise Strace (c'est-à-dire, pas de machine virtuelle / conteneur requise).
Veuillez trouver des détails sur le mécanisme de sable et comment utiliser sur 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 a commencé comme un projet de recherche de doctorat. Il est soutenu par diverses subventions gouvernementales.
Packj a commencé comme un projet de recherche universitaire. Plus précisément, les techniques d'analyse de code statique utilisées par Packj sont basées sur la recherche de cybersécurité de pointe: le projet Maloss par notre groupe de recherche chez Georgia Tech.
Packj est soutenu par des subventions généreuses de NSF, GRA et Alinnovate.
TL; DR Les scanners de vulnérabilité de pointe supposent que le code de source ouverte tiers est bénin. Par conséquent, tous ces outils ne traitent que des menaces des bogues de programmation accidentels dans le code bénin (aka cves tels que log4j). Ils ne protègent pas contre les attaques de chaîne d'approvisionnement modernes de type solarwinds contre le code délibérément mauvais (aka malveillant) qui se propage par de mauvais acteurs utilisant de nouvelles vulnérabilités dans le canal d'approvisionnement, y compris la confusion de dépendance, la typo-squatting, le protestation (sabotage), le détournement de compte et le génie social. Un exemple récent (22 déc.
PackJ a non seulement des audits pour CVE, mais effectue également une analyse de code dynamique statique + profonde ainsi que des vérifications de métadonnées pour détecter tout comportement et attributs "risqué", tels que le frai de shell, l'utilisation des clés SSH, l'inadéquation du code github par rapport au code emballé (provenance), le manque de 2FA, et plusieurs autres. Ces attributs non sécurisés ne sont pas considérés comme CVE, c'est pourquoi aucun des outils existants ne peut les signaler. Packj peut signaler des dépendances malveillantes, typo-squatting, abandonnées, vulnérables et autres dépendances insécurisées (liens faibles) dans votre chaîne d'approvisionnement logicielle.
Le modèle de menace de chaîne d'approvisionnement logicielle actuel suppose que le code de source ouverte tiers est bénin et, par conséquent, les vulnérabilités de sécurité ne sont suivies que pour des bogues de programmation accidentels (AKA CVE). En tant que tels, tous les scanners de vulnérabilité open source existants ne rapportent que les CVE connus et traitent les menaces des bogues accidentels dans le code bénin.
Un exemple typique d'un bogue de programmation accidentel est une vérification des limites manquantes sur l'entrée utilisateur, ce qui rend le code vulnérable aux attaques de débordement de tampon. Les exemples populaires du monde réel incluent Log4j et Heartbleed. Les attaquants doivent développer un exploit pour déclencher des CVE (par exemple, un paquet TCP / IP artisanal en cas de cœur ou une entrée numériquement élevée pour provoquer un débordement de tampon). Les CVE peuvent être corrigées en correctant ou en mettant la mise à niveau vers une version plus récente de la bibliothèque (par exemple, la version plus récente de LOG4J corrige le CVE).
Le paysage des menaces de la chaîne d'approvisionnement des logiciels modernes s'est déplacé après l'attaque de Solarwinds. Les mauvais acteurs ont trouvé de nouvelles vulnérabilités, mais cette fois dans le canal d'approvisionnement, pas du code. Ces nouvelles vulnérabilités telles que la confusion de dépendance, la faute de frappe, le protestation (sabotage), le détournement de compte et l'ingénierie sociale sont exploitées pour propager les logiciels malveillants. Des milliers de packages NPM / PYPI / Ruby compromis ont été signalés.
Contrairement à CVE, les logiciels malveillants sont délibérément mauvais (alias malveillants). De plus, le malware lui-même est un exploit et ne peut pas être corrigé ou corrigé en mettant à niveau vers une version plus récente. Par exemple, l'attaque de confusion de dépendance était intentionnellement malveillante; Il n'a exploité aucun bogue de programmation accidentel dans le code. De même, un auteur de Popular Package sabotant son propre code pour protester contre la guerre est très intentionnel et n'exploite aucun CVE. La faute de frappe est un autre vecteur d'attaque que les mauvais acteurs utilisent pour propager les logiciels malveillants dans les registres de packages ouverts populaires: il exploite les fautes de frappe et l'inexpérience des développeurs, et non des bogues de programmation accidentels ou des CVE dans le code.
Les scanners existants ne parviennent pas à détecter ces attaques de chaîne d'approvisionnement logicielle modernes de type solarwinds à partir de code délibérément vulnérable (malveillant). Ces outils scannent simplement le code source pour les dépendances open source, compilent une liste de toutes les dépendances utilisées et recherchez chaque <dépendance, version de dépendance> dans une base de données (par exemple, NVD) pour signaler les versions de package affectées (par exemple, version vulnérable de Log4J, version libssl affectée par Heartbleed).
PackJ a non seulement des audits pour CVE, mais effectue également une analyse de code dynamique statique + profonde ainsi que des vérifications de métadonnées pour détecter tout comportement et attributs "risqué", tels que le frai de shell, l'utilisation des clés SSH, l'inadéquation du code github par rapport au code emballé (provenance), le manque de 2FA, et plusieurs autres. Ces attributs non sécurisés ne sont pas considérés comme CVE, c'est pourquoi aucun des outils existants ne peut les signaler. Packj peut signaler des dépendances malveillantes, typo-squatting, abandonnées, vulnérables et autres dépendances insécurisées (liens faibles) dans votre chaîne d'approvisionnement logicielle. Veuillez en savoir plus sur Audit Readme
Packj peut être facilement personnalisé (bruit zéro) à votre modèle de menace. Ajoutez simplement un fichier .packj.yaml dans le répertoire supérieur de votre repo / projet et réduisez la fatigue d'alerte en commentant les attributs indésirables.
Nous avons trouvé plus de 40 et 20 packages malveillants sur PYPI et Rubygems, respectivement en utilisant cet outil. Un certain nombre d'entre eux ont été retirés. Reportez-vous à un exemple ci-dessous:
$ 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 a signalé Krisqian (V0.0.7) comme suspect en raison de l'absence de référentiel source et de l'utilisation d'API sensibles (réseau, génération de code) pendant le temps d'installation du package (dans setup.py). Nous avons décidé de regarder plus profondément et avons trouvé le forfait malveillant. Veuillez trouver notre analyse détaillée sur https://packj.dev/malware/krisqian.
Plus d'exemples de logiciels malveillants que nous avons trouvés sont répertoriés sur https://packj.dev/malware, veuillez nous contacter à [email protected] pour la liste complète.
Pour en savoir plus sur l'outil Packj ou les attaques de chaîne d'approvisionnement en logiciels open source, reportez-vous à notre
Montre ? ce référentiel pour rester à jour.
Vous avez une fonction ou une demande de support? Veuillez visiter notre page de discussion GitHub ou rejoindre notre communauté Discord pour la discussion et les demandes.
Packj a été développé par des chercheurs en cybersécurité d'Ossillate Inc. et des collaborateurs externes pour aider les développeurs à atténuer les risques d'attaques de la chaîne d'approvisionnement lors de l'approvisionnement en matière de dépendances logicielles à source ouverte tierces non fidèles. Nous remercions nos développeurs et collaborateurs. Montrez votre appréciation en nous donnant un si vous aimez notre travail.
Nous accueillons les contributions du code à bras ouverts. Voir Contribution.MD Lignes directrices. Vous avez trouvé un bug? Veuillez ouvrir un problème. Reportez-vous à nos directives Security.MD pour signaler un problème de sécurité.
PackJ peut actuellement vérifier les packages NPM, PYPI et RubyGems pour les attributs "risqués". Nous ajoutons le support de la rouille.
PackJ utilise l'analyse de code statique, le traçage dynamique et l'analyse des métadonnées pour une audit complète. L'analyse statique à elle seule n'est pas suffisante pour signaler les logiciels malveillants sophistiqués qui peuvent se cacher mieux en utilisant l'obscurcissement du code. L'analyse dynamique est effectuée en installant le package sous strace et en surveillant son comportement d'exécution. Veuillez en savoir plus sur Audit Readme.
Il s'agit d'un comportement malveillant très courant. Packj détecte l'obscuscation du code ainsi que la frai des commandes shell (EXEC System Call). Par exemple, PackJ peut signaler l'utilisation de getattr() et eval() car ils indiquent la «génération de code d'exécution»; Un développeur peut aller à l'époque plus profondément. Voir main.py pour plus de détails.