Cатсн²² (in)sесuяitу / ChrisJohnRiley

Because we're damned if we do, and we're damned if we don't!

Tag Archives: HTTPS

SSL certificate impersonation… for shits and giggles!

Cultural Note: Shits and giggles == englishize(for the lulz) –> Urban Dictionary Ref.

How often as penetration testers do we see SSL protected services using self signed certificates… If you’re anything like the average penetration tester, it’s probably daily. We’ve all been through the song and dance of documenting it, saying it’s bad and that it might have security consequences. I’m sure we’ve all heard every excuse under the sun as well when it comes to why it can’t be fixed. Costs too much, no internal PKI, takes too much time, and some of my favourites… “It’s just a test system”, “nobody except us uses this and we know what cert it has” and the all time classic, “it’s only internal”!

I’m not sure about you, but I don’t have the fingerprints for all the self signed certs I’ve seen in my head… and the over use of them has conditioned many of us to just click YES when prompted. Although this has become a little harder in recent times with new browsers making you click-through more than one menu, it’s still easier than getting up, walking over to an admin and saying “whats up here”. Certs, even self signed ones, expire and are replaced… which leads us to the inevitable result that users, and to some lesser extent administrators, will click-through almost anything as long as the Common Name and Issuer data looks remotely correct.

As part of my SAP Management Console research I began looking at the possibility to automatically create a self signed certificate that impersonates the certificate on a remote system as closely as possible. Not just the same CN, but everything from CN through to Issuer, Extensions… everything. With that in mind I flexed my awesome Ruby skills (note: I have no Ruby skills that I’m aware of) and created a simple Metasploit module that connects to a remote target, reads the SSL certificate and, using all the relevant data from the remote cert, creates a local self signed certificate and private key. Obviously there are some differences as I can’t match the signature (if I could that would be a big problem right ;), but to the general user, things look almost identical.

Putting your “normal user” or even “overworked sysadmin” hat on for a moment, take a look at the below side-by-side comparison.

         Original Certificate       |    Impersonated Certificate

I’m not sure about you, but I know a few people who’d just click that away without a second thought. Even more people if self signed certs are a standard in your company.

Creating an Impersonated SSL certificate the hard way

Go to the site you want to create the impersonation certificate for, export the publicly accessible information, recreate by hand using OpenSSL… good luck with all the fine details… can you set all the options you want??? Scratch your head…. profit (later)

Creating an impersonated SSL certificate the Metasploit way

msf > use auxiliary/gather/impersonate_ssl
msf  auxiliary(impersonate_ssl) > set RHOST www.metasploit.com
RHOST => www.metasploit.com
msf  auxiliary(impersonate_ssl) > run
[*] Connecting to www.metasploit.com:443
[*] Copying certificate /O=metasploit.com/OU=Domain Control Validated/CN=metasploit.com from www.metasploit.com:443
[*] Beginning export of certificate files
[+] Created required files from remote server www.metasploit.com:443
[+] Files stored in ~/.msf3/loot (.key|.crt|.pem)
[*] Auxiliary module execution completed

That’s it… you now have all the files you need (key|crt|pem) in ~/.msf4/loot ready to be used in any other Metasploit module (using ‘set SSLCert’), Apache or whatever your heart desires. Go on, go wild!

Note: The module tries it’s best to match the original certificate 100%, which includes using the same key length and hashing algorithm (MD5, SHA-1, etc…). It also tries to match the serial of the cert as closely as possible (some difference is required to stop certain browsers from displaying an error when it sees a certificate with the same issuer/serial combination using a different signature –> example). You’ll notice in the above screenshots that the serial on both certificates is 00… this threw an error on my Firefox when accessing the real site, followed by the site with the impersonated SSL… hence the fixed version 😉

Even amongst the companies that have an internal CA this kind of impersonation is going to get past most people… for those special cautious people (i.e the security people) I’ve built-in an EXPIRATION option where you can set a date (or specify a shortcut such as ‘now’ or ‘yesterday’) when the impersonated SSL certificate you create will expire. This will also set the logical start date of the certificate to a year before expiration to look logical to people checking the details closely. Using this feature you can add an extra level of depth to social engineering attempts… How many times have you seen internal (or even external) SSL certs expire before people remember to renew them? People that are looking for deception and trickery need something, anything, to prove to them that it isn’t an attack… so lets give it to them. I give you the “Oops our cert expired yesterday” attack 

I don’t claim this to be new, and I’m sure there are thousands of smart enlightened testers out there right now doing this kind of thing on a daily basis… It’s not perfect, but face it, if it was I wouldn’t be blogging about it! I’d be sitting on a beach somewhere with a Mojito and a check from ZDI in my pocket 😉 Still I hope this module will help the layman demonstrate that self signed certs, even within your companies internal network, are an easy target with a little thought, an explainable scenario and a little Ruby!

The impersonate_ssl.rb script isn’t currently in the Metasploit repository, but can be downloaded from my Google Code SVN

Note: The above Metasploit output is based on my interpretation of where impersonate_ssl.rb will be placed (auxiliary/gather)… if it makes it into the Metasploit trunk, it may be located elsewhere –> Metasploit feature #5398

HTTP Strict Transport Security

If you’re a sad geek like me you’ve probably already heard of HSTS (HTTP Strict Transport Security). HSTS is designed to solve an issue where you access a web server using HTTP and are automatically redirected to the HTTPS equivalent (usually through a 301 or 302 response and a new location header).

To most this seems like a perfectly acceptable solution, until you start thinking about the Man in the Middle issues of this kind of redirection. Most users don’t type https://mybank.com after all. They just type mybank.com and expect the browser and server to sort it out themselves…. and to be honest, they should. Users shouldn’t need to understand security to BE secure. It’s something that the server architects, web designers, and programmers of the world need to get together to solve.

So, the first step in securing this hole is finally beginning to be implemented. HSTS is still a way off yet (it’s just been implemented into the Firefox 4 nightly builds, and appears to be supported in Chromium), but it’s already looking promising.

HTTP Strict Transport Security works by allowing servers to return an additional header along with their 301 or 302 redirection. This Strict-Transport-Security: header allows the server to set a max-age (and optionally an includeSubDomains parameter) which is read by a compatible browser (currently limited).

Strict-Transport-Security Header

The browser will then remember the setting and next time it’s asked to connect to the server (even if it’s entered as an http:// address) the browser will request the https:// version.

Type http:// get https://

A couple of issues:

  • An initial HTTP request still needs to be made (opening for MitM)
  • Sub-domains need to be included to ensure everything is secured (addition of the includeSubDomains parameter)
  • How is Private browsing (i.e porn mode) handled? I see 2 possibilities here:
    • HSTS info is deleted along with everything else (reduced security)
    • HSTS info is retained (secure, but breaks privacy)

I’m looking forward to HSTS being implemented across a broader range of browsers, although this is going to take a long time (IE6 has only just started to die after all). Still, anything we can do to solve part of the problem is worthwhile doing.

UPDATE: I looked briefly into the private browsing situation (at least with Firefox 4 nightly) and as I thought, it forgets the HSTS settings. Preferring privacy and protection of your visited sites over the security offered by HSTS. I guess this makes sense… Still, it renders HSTS mute for many of us who run in private browsing mode all the time (for privacy reasons!). I’d like to see an option to retain these. Maybe in the next nightly?


  • Firefox 4: HTTP Strict Transport Security (force HTTPS) –> LINK
  • Firefox nightly builds (with HSTS support) –> LINK
  • HSTS Draft –> LINK
  • Chromium Strict Transport Security –> LINK

Test Sites (sites supporting HSTS):