1

first post here so be gentle please!

I understand the Heartbleed vulnerability concept, and I have a general grasp of Python. I'm struggling to understand the PoC Python code though, so was after a bit of code dissection :)

Particularly the two sections where it defines the 'hello' and'hb' message? I watched the messages going across the wire in Wireshark and can clearly see the hex going back and forth. Then comparing this to a normal SSL connection it's fairly similar.

So I'm guessing the content of that hex is setting up the SSL connection and heartbeat request? But can anyone explain the hex involved, or more specifically what this is derived from?

I've seen the RFC that defines the heartbleed extension, but for some reason I can't translate that into how this hex has been derived. Am I being stupid or just missing something?!

TimC
  • 552
  • 5
  • 12
  • It looks as if I didn't explain myself clearly enough!! Basically what I'm asking is, in the ssltest.py script why that specific sequence of hex characters? The RFC talks in very general terms about how an SSL server should respond and gives a lot of C code to show a kind of implementation. Nowhere in it can I find what format it expects the message in, or anything that indicates why those particular hex digits are used... – TimC Apr 16 '14 at 08:54

1 Answers1

2

I guess you are referring to ssltest.py that is circulating in the wild. The Client Hello was probably just copied from another packet capture. It is part of the SSL handshake:

  Client                                               Server

  ClientHello                  -------->
                                                  ServerHello
                                                 Certificate*
                                           ServerKeyExchange*
                                          CertificateRequest*
                               <--------      ServerHelloDone
  Certificate*
  ClientKeyExchange
  CertificateVerify*
  [ChangeCipherSpec]
  Finished                     -------->
                                           [ChangeCipherSpec]
                               <--------             Finished
  Application Data             <------->     Application Data

OpenSSL allows heartbeats to be received during the handshake. Because the client has not yet sent a ChangeCipherSpec message, the Heartbeat request is not encrypted. For an explanation of the heartbeat request and response format, see this answer. It also shows why the exploit is happening, the payload length is too large and the payload + padding is omitted.

The format of the SSL packets are described as TLSPlaintext in Appendix A of RFC 5246 (TLS 1.2). The "fragment" would be the ClientHello handshake message and the Heartbeat request starting at the type and payload length.

I think that the comments in my implementation of the Heartbleed server PoC will help you understand it better.

Lekensteyn
  • 5,958
  • 5
  • 38
  • 62
  • Thank you, I think that other answer you linked to explains it - that gives each of the hex characters and what they mean. Where did the authors find this information though? Also in your code (which is clearer btw), and also in ssltest.py, it translates the message from a string to a byte array, is this because of the format the SSL server is expecting it in? One thing I don't understand about your code though is that there is no 18 in the hex, I thought this was necessary to indicate that the message is a heartbeat? – TimC Apr 16 '14 at 08:49
  • My `heartbleed.py` imports code from pacemaker, see https://github.com/Lekensteyn/pacemaker/blob/master/pacemaker.py#L57. I followed the TLS 1.2 and Heartbeat extension RFC and packet capture to build these packets. And `00 03 01` looks prettier than `b'\x00\x03\x01'`, don't you think? That's why I use hex strings and then convert them to a bytearray (as the wire expects bytes, not some hex string...) – Lekensteyn Apr 16 '14 at 09:04