
Öffentlicher OCI-Image (Docker-Image) Sicherheitschecker
PISC (Public OCI-Image or docker-image Security Checker) ist ein Kommandozeilenwerkzeug zur Bewertung der Sicherheit von OCI-Container-Images.
Beendet sich mit Code 1, wenn eine der folgenden Bedingungen erfüllt ist:
Es kann verwendet werden, um automatisch die Sicherheit öffentlicher OCI-Images zu überprüfen, bevor sie in einer privaten Umgebung ausgeführt oder als Basis-Images in einer CI/CD-Pipeline verwendet werden.
API-Schlüssel abrufen für virustotal. Das standardmäßige kostenlose Endbenutzerkonto hat Einschränkungen.
docker run kapistka/pisc:latest /bin/bash ./scan.sh -delm --virustotal-key <virustotal-api-key> -i r0binak/mtkpi:v1.5
docker run kapistka/pisc:latest-feeds /bin/bash ./scan.sh -delm --offline-feeds --virustotal-key <virustotal-api-key> -i r0binak/mtkpi:v1.5
Siehe Dockerfile für eine Liste der Abhängigkeiten. Sie müssen trivy, grype, skopeo, jq und andere Pakete je nach verwendeter Distribution installieren.
Usage:
scan.sh [flags] [-i IMAGE | -f FILE | --tar TARFILE]
Flags:
-d, --date Überprüft das Alter des Images gegen einen Schwellenwert (Standard: 365 Tage).
--d-days <int> Benutzerdefinierter Schwellenwert für die Überprüfung des Erstellungsdatums (in Tagen). Beispiel: '--d-days 180'.
-e, --exploits Prüft auf Sicherheitslücken mit bekannten Exploits (mit Trivy + Grype + inthewild.io + empiricalsecurity.com).
--epss-and Verwendet UND-Logik zur Kombination von EPSS-Score und Exploit-Vorhandensein. Wenn deaktiviert, wird ODER-Logik angewendet (Standard: ODER).
--epss-min <float> Minimaler EPSS-Score-Schwellenwert zur Filterung von Sicherheitslücken (Standard: 0.5).
-f, --file <string> Stapelscan von Images aus einer Datei. Beispiel: '-f images.txt'.
-h, --help Zeigt diese Hilfemeldung an.
--ignore-errors Ignoriert Fehler von externen Werkzeugen und setzt die Ausführung fort.
-i, --image <string> Ein einzelnes zu scannendes Image. Beispiel: '-i r0binak/mtkpi:v1.4'.
-l, --latest Erkennt nicht versionierte Tags (z.B. ':latest').
-m, --misconfig Scannt nach gefährlichen Build-Fehlkonfigurationen.
--offline-feeds Verwendet ein eigenständiges Offline-Image mit vorab heruntergeladenen Sicherheitslücken-Feeds (z.B. :latest-feeds).
--scanner [trivy|grype|all] Wähle den zu verwendenden Scanner: Trivy, Grype oder beide (Standard: all)
--severity-min <string> Minimale Schwere der Sicherheitslücken [UNKNOWN|LOW|MEDIUM|HIGH|CRITICAL] Standard [HIGH]
--show-exploits Zeige Exploit-Details
--tar <string> Scanne lokales TAR-Archiv von Image-Layern. Beispiel: '--tar /path/to/private-image.tar'.
--trivy-server <string> Endpunkt-URL des Trivy-Servers. Beispiel: '--trivy-server http://trivy.something.io:8080'.
--trivy-token <string> Authentifizierungstoken für den Trivy-Server. Beispiel: '--trivy-token 0123456789abZ'.
-v, --version Zeigt die Version an.
--virustotal-key <string> VirusTotal-API-Schlüssel für Malware-Scan. Beispiel: '--virustotal-key 0123456789abcdef'.
--vulners-key <string> Vulners.com-API-Schlüssel (Alternative zu inthewild.io). Beispiel: '--vulners-key 0123456789ABCDXYZ'.
Zusätzliche Hinweise:
- Zur Authentifizierung bei einer Registry siehe 'scan-download-unpack.sh#L14'.
- Zum Konfigurieren von Ausschlüssen für bestimmte CVEs oder andere Kriterien siehe 'check-exclusion.sh#L5'.
Dieses Dienstprogramm kann in eine CI-Pipeline integriert werden, um einen Sicherheitsscan von Container-Images durchzuführen, bevor sie in eine private Registry gepusht werden. Kombinieren Sie diesen Schritt mit Image-Signing und automatisiertem Registry-Push für einen sicheren DevSecOps-Workflow. Nachfolgend ein Beispielkonfiguration:
security_scan:
stage: security
image: $SECURITY_IMAGE_FEEDS
script:
- |
/bin/bash /home/nonroot/scan.sh -delm --offline-feeds --virustotal-key $VIRUSTOTAL_API_KEY -f ${NEW_IMAGES_FILE}
# Auto-approve: If the scan fails (exit code >0), the pipeline stops before reaching this point.
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
# CVE-2024-3094 (XZ Utils) exploit
./scan.sh --virustotal-key <virustotal-api-key> -i r0binak/xzk8s:v1.1
════════════════════════════════════════
🍄 r0binak/xzk8s:v1.1 >>> virustotal detected malicious file
layer:0f28dfeb
https://www.virustotal.com/gui/file/0f28dfebbf3451ccfe3d5b11d17bc38cc8d1c4e721b842969466dc7989d835e3
https://www.virustotal.com/gui/file/dc24581c3500b9640e03c7a4c14cd7c22f88c533b831a7f6a49aaf3ba39fcde4
layer:230cc513
https://www.virustotal.com/gui/file/230cc513debf36c5294ba6dd2babd27934bb231362cd8d916ea1c58e9495d38f
https://www.virustotal.com/gui/file/935cfccfa8d31d0e03f2162e9b46b7f9df77db64efa2e4cfb4dbaebdf94be6d3
root/liblzma.so.5.6.0.patch 37/64 🐴 trojan.xzbackdoor/cve20243094
# vulnerabilities: trivy + grype + epss + exploits (IngressNightmare)
./scan.sh -e -i registry.k8s.io/ingress-nginx/controller:v1.11.2
════════════════════════════════════════════════
🐞 registry.k8s.io/ingress-nginx/controller:v1.11.2 >>> detected exploitable vulnerabilities
CVE SEVERITY SCORE EPSS EXPL FIX PACKAGE
CVE-2025-1974 CRITICAL 9.8 0.87 0 + k8s.io/ingress-nginx
📆 registry.k8s.io/ingress-nginx/controller:v1.11.2 >>> created: 2024-08-15. Last update: 2025-06-04
💡 registry.k8s.io/ingress-nginx/controller:v1.11.2 >>> use a newer tags:
v1.11.3 v1.11.4 v1.11.5 v1.11.6 v1.11.7
v1.12.0 v1.12.0-beta.0 v1.12.1 v1.12.2 v1.12.3
# dangerous image build misconfiguration cve-2024-21626
./scan.sh -m -i r0binak/cve-2024-21626:v4
════════════════════════════════════════
🐳 r0binak/cve-2024-21626:v4 >>> detected dangerous misconfiguration
CVE-2024-21626 runC Escape
https://nitroc.org/en/posts/cve-2024-21626-illustrated/
# test malware image - https://github.com/ruzickap/malware-cryptominer-container
./scan.sh --virustotal-key <virustotal-api-key> -i peru/malware-cryptominer-container
════════════════════════════════════════
🍄 peru/malware-cryptominer-container >>> virustotal detected malicious file
layer:42467519
https://www.virustotal.com/gui/file/42467519cb14e8ef1b80db6b3e91e652fdd56a2cfc44f1a9278f4237434ff9a8
https://www.virustotal.com/gui/file/f935a501fb24a47ee77c966898a05f197bcfe0f5f2338ce5a3425c2b9b6a3a46
usr/share/nginx/html/eicar/eicar.com.txt 66/69 🧬 virus.eicar/test
usr/share/nginx/html/eicar/eicarcom2.zip 55/65 🧬 virus.eicar/test
usr/share/nginx/html/malware/ILOVEYOU.vbs 47/58 🐛 worm.loveletter/scriptworm
usr/share/nginx/html/malware/Invoke-ConPtyShell.ps1 24/62 👾 hacktool.boxter/powershell
usr/share/nginx/html/malware/L0Lz.bat 41/61 🐴 trojan.disabler/joke
usr/share/nginx/html/malware/Linux.Trojan.Multiverze.elf.x86 44/67 🐴 trojan.gafgyt/mirai
usr/share/nginx/html/malware/MadMan.exe 37/63 🧬 virus.madman
usr/share/nginx/html/malware/Melissa.doc 58/62 🧬 virus.melissa/w97m
usr/share/nginx/html/malware/Py.Trojan.NecroBot.py 33/64 🐴 trojan.python/necrobot
usr/share/nginx/html/malware/Trojan.Java.Fractureiser.MTB.jar 32/65 🐴 trojan.java/fractureiser
usr/share/nginx/html/malware/TrojanSpy.MacOS.XCSSET.A.bin 44/63 🐴 trojan.xcsset/xtesc
usr/share/nginx/html/malware/Txt.Malware.Sustes.sh 37/62 💰 miner.zojfor/shell
usr/share/nginx/html/malware/Unix.Downloader.Rocke.sh 38/62 🐴 trojan.zojfor/shell
usr/share/nginx/html/malware/Unix.Malware.Kaiji.elf.arm 40/67 🐴 trojan.kaiji/ddos
usr/share/nginx/html/malware/Unix.Trojan.Mirai.elf.m68k 44/67 🐴 trojan.mirai/bootnet
usr/share/nginx/html/malware/Unix.Trojan.Mirai.elf.mips 46/63 🐴 trojan.mirai/gafgyt
usr/share/nginx/html/malware/Unix.Trojan.Mirai.elf.ppc 47/66 🐴 trojan.gafgyt/mirai
usr/share/nginx/html/malware/Unix.Trojan.Mirai.elf.sparc 44/66 🐴 trojan.mirai/gafgyt
usr/share/nginx/html/malware/Unix.Trojan.Mirai.elf.x86_64 40/63 🐴 trojan.mirai/gafgyt
usr/share/nginx/html/malware/Unix.Trojan.Spike.elf.arm 43/63 🐴 trojan.dofloo/rootkit
usr/share/nginx/html/malware/Walker.com 42/62 🧬 virus.walker/abraxas
usr/share/nginx/html/malware/WannaCry.exe 66/72 🔑 trojan.wannacryptor/wannacry
usr/share/nginx/html/malware/Win.Trojan.Perl.perl 36/60 💩 Malware.Generic-Script.Save.169b6505
usr/share/nginx/html/malware/Zloader.xlsm 44/67 🐴 trojan.esls/zloader
usr/share/nginx/html/xmrig/xmrig 43/64 💰 miner.xmrig/lkoez