This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org
Generating Custom SSL Certificates for WebScarab
When using WebScarab to proxy SSL conversations, you may want to avoid the somewhat annoying warnings for an unrecognized certificate. Generating a custom SSL certificate is how you can remove these warning messages and its rather straight forward. Read on to see how.
Background
Below is an illustration of what happens when WebScarab is used as a intercepting proxy for SSL connections.
-------- ----------- --------- | server |<--[1]-->| WebScarab |<--[2]-->| browser | -------- ----------- ---------
For [1], you are using the "real" SSL certificate from the website you are browsing to. That SSL certificate is signed by a recognized certificate authority (CA). The thing that makes those CA's special is that browsers know about them and trust them. For example in Firefox:
- Open Edit -> Preferences -> Advanced -> Encryption
- View Certificates button
- Authorities tab
to see a list of built-in trusted CA's. The only thing that needs to trust this certificate is WebScarab which Rogan (WebScarab project lead) has said it will by default.
For [2], you are using the the server.p12 certificate which comes with WebScarab. The difference between [1] and [2] is that the CA which signed that certs is NOT built into browsers so they do not trust them by default. Additionally, the domain name of this certificate will not match the domain your browser is accessing. The default is the webscarab CA and a host name of webscarab.
Generating a Certificate
Since you're browser doesn't trust the CA which signed server.p12 in [2] above, you've got two choices:
- Instruct the browser to trust the certificate. This will work for the CA part but not for the host name. You will still be prompted by the browser so this doesn't really help much. I know that you can have Firefox trust the CA used in [2] permanently - though its a bunch of clicks in Firefox 3 - about 6 or 7 clicks and you still have the host name mis-match issue.
- Use a .p12 file & CA certificate. You'll have to have WebScarab use the new .p12 file and install the CA certificate into your browser.
Rogan has graciously put a script to do this in the WebScarab Git repository. You can get it here or copy and paste it from the listing at the bottom of this page.
The script that Rogan provides will create a CA certificate and a new .p12 certificate for WebScarab to use. The name of the .p12 certificate is based on the first argument to that script. If you called that script like:
$ ./cert.sh www.example.com
It will generate a bunch of output and create a www.example.com.p12 file for WebScarab and a ca_cert.pem file (this is the CA used to sign www.example.com.p12). The script will run fine on Linux (I just tried it) and possibly OS X but won't work on Windows (maybe with Cygwin - any volunteers?).
Take the www.example.com.p12 (assuming you ran the script like above) and let WebScarab know about it. To do this you will need to place it in ${WEBSCARAB_HOME}/certs/. WebScarab checks in that directory at start up for any SSL certificates and remembers what it finds.
Take the ca_cert.pem file and configure your browser to trust that CA. For Firefox:
- Open Edit -> Preferences -> Advanced -> Encryption
- View Certificates button
- Authorities
- Click the Import button and navigate to the ca_cert.pem file
Make sure you at least check the box "Trust this CA to identify web sites." option when you are importing - it will bring up a window with that information.
For IE, I don't know off the top of my head. Try this link except for instead of downloading it you can right-click on the ca_cert.pem file and select "Install Certificate"
FYI: Firefox and IE will both need to be configured if both are used as they keep their lists of trusted CAs in different places.
Added Bonus If you keep the working directory for cert.sh, you can create new custom SSL certificates and the CA will stay the same. No need to continually add CAs to the browser(s) of your choice. If you know all the domains you'll be testing, you can run cert.sh multiple time and just restart WebScarab once to get them all recognized.
For the curious, this is the directory structure the cert.sh script Rogan linked creates:
./ |-- cert.sh |-- sslcerts | |-- ca_cert.pem | |-- certindex.txt | |-- certindex.txt.attr | |-- certindex.txt.old | |-- certs | | `-- 100001.pem | |-- openssl.cnf | |-- private | | |-- ca_key.pem | | `-- www.example.com-key.pem | |-- serial | |-- serial.old | |-- www.example.com-cert.pem | `-- www.example.com-req.pem `-- www.example.com.p12 3 directories, 14 files
Notes
- I was not precise in terms and used SSL and HTTPS loosely in the above. This process would also applies to TLS - I just didn't want to type SSL/TLS over and over.
- Matt Tesauro was the author of this document. If you have corrections, feel free to make them yourself (its a Wiki after all) or contact Matt at mtesauro (at) gmail.com
- The certificate script can be copy and pasted from here:
#!/bin/sh if [ ! -d sslcerts ] ; then mkdir sslcerts || die "Couldn't create sslcerts directory" fi if [ ! -d sslcerts/certs ] ; then mkdir sslcerts/certs || die "Couldn't create certs directory" fi if [ ! -d sslcerts/private ] ; then mkdir sslcerts/private || die "Couldn't create private directory" fi if [ ! -f sslcerts/serial ] ; then echo '100001' > sslcerts/serial fi touch sslcerts/certindex.txt if [ ! -f sslcerts/openssl.cnf ] ; then cat <<-EOF > sslcerts/openssl.cnf # # OpenSSL configuration file. # # Establish working directory. dir = . [ ca ] default_ca = CA_default [ CA_default ] serial = ./serial database = ./certindex.txt new_certs_dir = ./certs certificate = ./ca_cert.pem private_key = ./private/ca_key.pem default_days = 365 default_md = md5 preserve = no email_in_dn = no nameopt = default_ca certopt = default_ca policy = policy_anything [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = match commonName = supplied emailAddress = optional [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = 1024 # Size of keys default_keyfile = key.pem # name of generated keys default_md = md5 # message digest algorithm string_mask = nombstr # permitted characters distinguished_name = req_distinguished_name req_extensions = v3_req [ req_distinguished_name ] # Variable name Prompt string #------------------------- ---------------------------------- 0.organizationName = Organization Name (company) organizationalUnitName = Organizational Unit Name (department, division) emailAddress = Email Address emailAddress_max = 40 localityName = Locality Name (city, district) stateOrProvinceName = State or Province Name (full name) countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 commonName = Common Name (hostname, IP, or your name) commonName_max = 64 # Default values for the above, for consistency and less typing. # Variable name Value #------------------------ ------------------------------ 0.organizationName_default = WebScarab localityName_default = WebScarab stateOrProvinceName_default = WebScarab countryName_default = ZA [ v3_ca ] basicConstraints = CA:TRUE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always [ v3_req ] basicConstraints = CA:FALSE subjectKeyIdentifier = hash EOF fi if [ ! -f sslcerts/private/ca_key.pem -a ! -f sslcerts/ca_cert.p12 ] ; then printf "\n\n\n\n\n\n\n" | \ openssl req -new -x509 -extensions v3_ca -keyout sslcerts/private/ca_key.pem \ -out sslcerts/ca_cert.pem -days 3650 -config ./sslcerts/openssl.cnf \ -passin pass:password -passout pass:password fi cd sslcerts # Create the cert for the specified site if [ ! -f $1-req.pem ] ; then printf "\n\n\n\n\n\n$1\n" | \ openssl req -new -nodes \ -out $1-req.pem -keyout ./private/$1-key.pem \ -days 3650 -config ./openssl.cnf fi if [ ! -f $1-cert.pem ] ; then printf "y\ny\n" | \ openssl ca -out $1-cert.pem -days 3650 \ -key password -config ./openssl.cnf -infiles $1-req.pem fi if [ ! -f ../$1.p12 ] ; then openssl pkcs12 -export -in $1-cert.pem -inkey ./private/$1-key.pem \ -certfile ca_cert.pem -out ../$1.p12 -password pass:password fi