
Ruby OpenSSL private key spoofing? - borski
http://seclists.org/fulldisclosure/2014/Apr/231
======
reedloden
Can anybody explain what exactly is happening? The PoC is really hard to read
and understand.

~~~
steveklabnik
I don't fully get it either, but I think it has to do with what happens when
you call PKey::RSA.to_pem: [http://ruby-
doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/P...](http://ruby-
doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-to_pem)

I think that it'll calculate the private key, which you can then smuggle out
to another file before you're supposed to be able to?

The CVE number is just reserved at the time I'm posting this:
[http://cve.mitre.org/cgi-
bin/cvename.cgi?name=2014-2734](http://cve.mitre.org/cgi-
bin/cvename.cgi?name=2014-2734)

Maybe in a few hours we'll have more information.

------
jvdh
As far as I understand it this has very little impact on the security of
OpenSSL and can only be abused by someone with access to a signing system (and
then you have more problems anyway).

What happens is that during the signing phase the certificate up the chain is
read and checked, then during the generation this root certificate can be
swapped out form underneath the process, and the generation proceeds as if
nothing happened.

This means that the newly inserted root certificate is inserted into the chain
of trust, while it was not explicitly added.

------
adrienthebo
I have a couple realizations from this.

First off, at some point I became the person that would dig into a PoC for
Ruby/OpenSSL/X509 bugs for hours. I've become a monster.

Secondly, I think that this is entirely wrong.

Standard disclaimer: I'm not a professional cryptographer. I have had to beat
my head against ruby and the OpenSSL x509 bindings, so I know enough to
probably make some very wrong statements.

That being said, the PoC is full of glaring errors. The ctx and cipher objects
are created but never used. the Extension Factory is created and then entirely
ignored because it's only used for the #issuer_certificate method. In
addition, x509v3 extensions aren't used in any way during this PoC, so it has
no reason to be there. And that's just the beginning.

I went through and picked apart the code in small bits to remove obfuscation
and unnecessary actions while preserving the displayed output. Here's the
massively cleaned up version:

    
    
      #!/usr/bin/env ruby
      
      require 'openssl'
      
      key = OpenSSL::PKey::RSA.new(2048)
      puts "Spoof must be in PEM format and saved as ca.pem"
      raw = File.read "ca.pem"
      ca_cert = OpenSSL::X509::Certificate.new raw
      
      puts "before we sign the cert: #{ca_cert.verify(key)}"
      ca_cert.sign(key, OpenSSL::Digest::SHA1.new)
      puts "after we sign the cert: #{ca_cert.verify(key)}"
      
      puts "Hijacked Certificate with chainloaded key saved  @ #{ca_cert.serial}.pem"
      printf "Verifying Keys Intergity: "
      puts  ca_cert.verify(key)
    

This removes all the variable duplications, doesn't write files because they
have absolutely no impact on the behavior, and still displays the same output
as the given PoC.

With a few final modifications it looks like this:

    
    
      #!/usr/bin/env ruby
      
      require 'openssl'
      
      key = OpenSSL::PKey::RSA.new(2048)
      ca_cert = OpenSSL::X509::Certificate.new(File.read("ca.pem"))
      
      puts "before we sign the cert: #{ca_cert.verify(key)}"
      ca_cert.sign(key, OpenSSL::Digest::SHA1.new)
      puts "after we sign the cert: #{ca_cert.verify(key)}"
    

So what we've managed to demonstrate is that you can as a matter of fact sign
SSL certificates with a private key.

Once again I may have _entirely_ missed the point on this and deleted a subtle
line that had a major effect on the code. However with the sheer number of
lines that were purely cargo culted for SSL implementations, I really think
that this isn't an issue. I have an entire history of how I started with the
original PoC and how I converted it to the above examples at
[https://github.com/adrienthebo/cve-2014-2734](https://github.com/adrienthebo/cve-2014-2734)
; please check it out if you think I made a mistake in my work.

