
Scanner offline per la compromissione della chiave CA eMudhra/emSign di ottobre 2026, individua i certificati interessati nei trust store del sistema operativo, nei bundle CA, nei cacerts di Java, in NSS e nelle immagini dei container.
Strumenti di rilevamento per la compromissione della chiave privata della CA intermedia eMudhra / emSign di ottobre 2026. Otto CA intermedie sono state emesse con chiavi P-384 i cui scalari privati erano interi minuscoli (valori recuperati 4, 56, 66, 115, 155, 156, 230, 237), quindi chiunque può falsificare banalmente certificati che concatenano a esse. I browser e i trust store dei sistemi operativi hanno applicato rapidamente la diffida - ma la maggior parte dei trust store non-browser non si aggiorna automaticamente, ed è proprio questo che questo strumento individua.
Stato: l'incidente è in corso, quindi considera gli IOC inclusi come un'istantanea (ogni esecuzione stampa la loro data
generated). Per aggiornarli, aggiornatools/sources/*.jsondal tracker upstream e riesegui il generatore (sotto).
trustscan (Python) e trustscan.ps1 (Windows/PowerShell) inventariano
i trust store e i bundle CA su un host e segnalano qualsiasi elemento corrispondente ai certificati
interessati. Solo stdlib + cryptography; nessun'altra dipendenza.
Richiede Python 3 e cryptography (l'unica dipendenza):
pip install -r requirements.txt
# scan this host's trust stores and CA bundles
python trustscan.py
# machine-readable for ticketing
python trustscan.py --format csv > findings.csv
# Windows-native: cert stores (both scopes) + GPO roots + env bundles
pwsh -File trustscan.ps1
Codici di uscita: 0 = pulito, 1 = riscontro/i, 2 = errore. I risultati solo INFO (vedi
--flag-aaa sotto) escono con 0.
Ogni esecuzione termina con un avviso di una riga sul percorso di cross-sign AAA (vedi
Ambito e limitazioni). In modalità text fa
parte del report; in modalità json/csv va su stderr così l'output
leggibile da macchina resta pulito.
Ogni certificato trovato in qualsiasi posizione sottostante viene sottoposto a fingerprint e verificato in quattro modi:
| Corrispondenza | Gravità | Significato |
|---|---|---|
compromised_ca_cert | CRITICAL | esatta intermediate compromessa (SHA-256 del certificato) |
compromised_key_reuse | CRITICAL | un certificato diverso che porta una chiave compromessa (SPKI SHA-256) - intercetta i cross-sign di Sectigo e qualsiasi riemissione |
issued_by_compromised_ca | HIGH | una leaf/sub-CA il cui AuthorityKeyIdentifier punta a un'intermediate compromessa - falsificabile |
distrust_root_present | CRITICAL | una root emSign non attendibile è ancora considerata attendibile qui. La sua chiave è intatta - ma le chiavi delle intermediate sono pubbliche, quindi finché questa root è attendibile un certificato falsificato per qualsiasi dominio viene validato per ogni client che non controlla la revoca (la maggior parte dei client non-browser). Rimuoverla / aggiornare il bundle. Da sola questo non chiude il percorso di cross-sign AAA (sotto) |
Un'ulteriore verifica è opt-in (--flag-aaa / -FlagAaa):
| Corrispondenza | Gravità | Significato |
|---|---|---|
cross_sign_root_present | INFO | è presente la legittima root Sectigo AAA Certificate Services. Ha fatto cross-sign delle otto intermediate, quindi ancora il loro secondo percorso di fiducia; la sua chiave è intatta. Mozilla e Chrome l'hanno rimossa ad aprile 2025, ma Windows, Apple, i bundle Linux più vecchi e molti keystore Java la considerano ancora attendibile. Segnalata solo su richiesta, per i team che decidono se rimuoverla (l'aggiornamento Debian per questo incidente lo fa); non influisce mai sul codice di uscita |
Per impostazione predefinita AAA Certificate Services non viene segnalata: la sua chiave è intatta e rimuoverla è una scelta deliberata, non una remediation predefinita. Vedi le limitazioni sotto per capire perché questo è importante.
trustscan| Fonte | Di cosa si tratta | Percorsi verificati |
|---|---|---|
certifi | Bundle CA Python | certifi.where() (risolto a runtime) |
bundles → distro | Aggregati ca-certificates del sistema operativo | Debian/Arch/Alpine /etc/ssl/certs/ca-certificates.crt · RHEL /etc/pki/tls/certs/ca-bundle.crt, /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem, cacerts Java consolidato, directory admin anchors/ · SUSE /etc/ssl/ca-bundle.pem, /var/lib/ca-certificates/ca-bundle.pem · directory sorgente Debian /usr/share/ca-certificates/ · /etc/ssl/cert.pem |
bundles → FreeBSD | ca_root_nss | /usr/local/share/certs/ca-root-nss.crt · /usr/local/etc/ssl/cert.pem |
bundles → Homebrew / MacPorts | brew / port ca-certificates, openssl | /opt/homebrew/etc/ca-certificates/cert.pem · /opt/homebrew/etc/openssl*/cert.pem · /usr/local/etc/... (Intel) · /opt/local/etc/{openssl,ssl}/cert.pem |
bundles → curl | bundle curl standalone | /usr/local/share/curl/curl-ca-bundle.crt · /opt/local/share/curl/curl-ca-bundle.crt · C:\Program Files\Git\...\ca-bundle.crt |
bundles → conda | ssl/cacert.pem di ogni env | $CONDA_PREFIX · /opt/conda · ~/anaconda3, ~/miniconda3, ~/miniforge3 (incl. envs/*) |
bundles → AWS CLI v2 | botocore incluso | /usr/local/aws-cli/.../botocore/cacert.pem · C:\Program Files\Amazon\AWSCLIV2\... |
bundles → cloud SDK / registry / ecosistema | altri bundle inclusi | gcloud / Azure CLI third_party/certifi · container-registry /etc/{docker,containers}/certs.d/*/ · Perl Mozilla::CA · Erlang/Elixir certifi |
bundles → pip | certifi incluso in pip | <pip>/_vendor/certifi/cacert.pem (risolto tramite import pip) |
nss | Firefox / Thunderbird / Chrome-Linux + DB NSS di sistema | ~/.mozilla/firefox/*/cert9.db · ~/.thunderbird/*/cert9.db · ~/snap/firefox/common/.mozilla/firefox/*/cert9.db · ~/.pki/nssdb/cert9.db · /etc/pki/nssdb/cert9.db · %APPDATA%\Mozilla\Firefox\Profiles\*\cert9.db · %APPDATA%\Thunderbird\Profiles\*\cert9.db |
| Fonte | Percorsi verificati |
|---|---|
os (Linux) | /etc/ssl/certs · /usr/local/share/ca-certificates · /etc/pki/tls/certs · /etc/pki/ca-trust/extracted/pem (ricorsivo), più Android/AOSP /system/etc/security/cacerts, /apex/com.android.conscrypt/cacerts, cacerts-added/ (file con nome hash) |
os (macOS) | security find-certificate -a -p sui keychain predefiniti + SystemRootCertificates.keychain |
os (Windows, Python) | ssl.enum_certificates per ROOT, CA, MY, TrustedPublisher, AuthRoot + root LocalMachine distribuite via Group Policy (registry) |
java | $JAVA_HOME + root JVM (/usr/lib/jvm/*, /opt/java/*, /Library/Java/JavaVirtualMachines/*, C:\Program Files\Java\*, Adoptium, Corretto, Microsoft) → .../lib/security/cacerts |
env | file in SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, NODE_EXTRA_CA_CERTS; directory in SSL_CERT_DIR |
containers (opt-in) | Docker /var/lib/docker/overlay2/*/diff, podman (root + rootless, incl. altri utenti), snapshot overlayfs di containerd - analizza il bundle aggregato di ogni layer; richiede root, il nome della posizione indica il layer |
apptrust (opt-in) | truststore Java di app-server e data-infra (Tomcat, WildFly/JBoss, Kafka, Elasticsearch) e JRE inclusi nelle applicazioni sotto /opt/*/jre/.../cacerts, C:\Program Files\*\jre\... - JRE privati inclusi dai vendor che la scansione Java dell'host non rileva |
target --path | store referenziati dalla configurazione (nginx, Apache, HAProxy, Oracle sqlnet.ora, LDAP) e bundle per progetto (Composer vendor/composer/ca-bundle/...) - punta --path su di essi |
paths | qualsiasi file/directory passati |
--rootfs <dir> | le posizioni degli store distro / curl / Java / Android all'interno di un'immagine o rootfs di firmware estratti |