emudra-weak-keys
This is a Zeek package to detect connections that use eMudhra intermediate CA certificates with compromised/well-known private keys.
For more information see, e.g., the original Bugzilla entry or https://emudhra.we-have-a-problem.com/.
Please note that this detection only works for connections using TLS 1.2 and below. In TLS 1.3, certificates are encrypted and Zeek does not know which certificates cross over the wire.
Background & Impact
The eMudhra CA issued several intermediate CA certificates with very weak ECDSA private keys (e.g. a key that's the number 4).
Thus, this enables anyone to trivially create certificates that are signed by any of the impacted CA certificates. To today's knowledge, there are 8 affected keys, 6 of which are in certificates that were trusted for the web PKI.
While major webbrowsers immediately distrusted the affected intermediate CA certificates, devices that are not as readily updateable will be at danger of accepting these malicious certificates for potentially significant periods of times.
For detailed background and a timeline see this Bugzilla entry.
Detection Logic
This package matches on the Subject Public Key Info (SPKI) of the affected intermediate CA certificates. The SPKI is the bit of the certificate that contains the compromised keys - so this will also detect any potentially unknown cross-signs, or any other certificates that might be created with the same keys.
List of SPKIs:
| Intermediate | SPKI SHA-256 |
|---|---|
| EM EV TLS CA - G3B (eMudhra BV) | E0254C7FCDC265E2F0F8A428DABB75AB4AE039B4872D62F5EE57F0877D5A8A41 |
| EM OV TLS CA - G3B (eMudhra BV) | 43BFFA19D6EF651451F6841E019931E96F6F2EAEFF28AB4B6F1CE4576DE2717B |
| EM DV TLS CA - G3B (eMudhra BV) | EBED6475C2C2D80FCB199F3FE8DD6E6B3CE60B77EB15D4E42C3DEC0C6F5B5105 |
| EM EV TLS CA - G3C (eMudhra Inc) | 5C0660A2B164910D8FF589C18E14552E9E0EC237DCEFE2CB736D41A4811F81A0 |
| EM OV TLS CA - G3C (eMudhra Inc) | 63ECEFEE431D49523BC1136C4E72D0206A477086CAF606CD5CF025686C109CF8 |
| EM DV TLS CA - G3C (eMudhra Inc) | 49DD353DC2B919A3770645117D0E60C16115E7D1BC259EEFE734B00EA434FE5F |
| EM OV CS CA - G3B (eMudhra BV) | EC4FFA1AD0AC88081314B7AAFFEF6A91F97CD57291BB5BA686C5415F5EB4F6B6 |
| EM OV CS CA - G3C (eMudhra Inc) | 92C063D67E8F14DB71D288E11266FFDAF69CBF115F7BAB14F3BC2F68D25E0E30 |
Usage
zkg install corelight/emudhra-weak-keys
or load the scripts directly:
zeek -r trace.pcap /path/to/emudhra-weak-keys/scripts
The package checks every certificate that's parsed by Zeek against the list.
Notices
All notice types are under EMudhraWeakKeys::
| Notice | Observation |
|---|---|
Compromised_Intermediate_Cert |
Affected intermediate cert seen in connection |
Compromised_Intermediate_Cert_Established |
Affected cert seen, handshake finished |
Compromised_Intermediate_Issuer |
Certificate with an affected issuer seen in connection |
Compromised_Intermediate_Issuer_Established |
Affected issuer seen, handshake finished |
Results go into notice.log; no additional log is created.
By default, the _Cert notices are issued once per server IP address per day,
and the _Established notices are issued once per client IP address per day.
Please note that the Compromised_Intermediate_Cert notices flag that
a compromised certificate was present in the connection, whereas the
Compromised_Intermediate_Issuer notices only match on the issuer string
of the certificates; this is a weaker signal.
Furthermore, the Established notices only track if the handshake finished; this does
not necessarily mean that any data was exchanged. Some clients might finish the handshake
even if certificate verification fails, and only abort afterwards.
The script checks both client and server certificate chains. It is unlikely that you will see these certificates in client certificates (if you do - please reach out to us and let us know).
Certificates are also checked in non-TLS protocols that Zeek supports (RDP, Kerberos). Certificates transferred as files (e.g. downloaded via HTTP) are not checked.
Configuration Options
The notice suppression interval can be changed via EMudhraWeakKeys::suppression_interval.
There are lots of other options that can be used to, e.g. change the list of compromised keys. Please see the script file for more details.
Limitations
- In TLS 1.3 the certificate chain is encrypted and cannot be seen by Zeek, so detection only works for TLS 1.2 and earlier (unless decryption is used).
- The issuer name check does not apply to certificates seen in non-TLS protocols. Some name normalization is performed for the issuer check, but this does not cover all possible cases.
Note: This package was created with the help of Claude Opus 5.5. All code and text was reviewed, edited & verified manually.