HeartBleed python test script

VilleLipponen picture VilleLipponen · Apr 12, 2014 · Viewed 11.2k times · Source

I came across this Python script that tests the server for the HeartBleed vulnerability:

Would someone be able to explain the content of the "hello", what is being sent and how was this content constructed?

I am not trying to use this script maliciously. I was asked to test a Tomcat 7.0.2 server for the vulnerability: I verified that tcnative-1.dll does use openssl 1.0.1d, but a few of the standalone test tools that I tried testing the server with report that it is not vulnerable.

Answer

Martijn Pieters picture Martijn Pieters · Apr 12, 2014

hello and hb define bytestrings in a more readable fashion.

The h2bin(x) function does all the work:

def h2bin(x):
    return x.replace(' ', '').replace('\n', '').decode('hex')

so the string of hex digits has all whitespace removed, then is decoded from hex to bytes:

>>> '16 03 02 00 dc'.replace(' ', '')
'16030200dc'
>>> '16 03 02 00 '.replace(' ', '').decode('hex')
'\x16\x03\x02\x00\xdc'

It's just a compact way to specify a series of bytes using hexadecimal notation and extra whitespace.

The hex data itself is just a normal heartbeat protocol message, in raw bytes. The hello string contains a TLS 1.1 record message, identified by the first byte (16 hex, 22 decimal) as a handshake record, sending a client_hello (sixth byte is 01). This is just setting up a TLS session, telling the server what kind of ciphers the client supports. It doesn't really matter what's contained in this, other than that it tells the server the client supports the Heartbeat extension (a 00 0f byte pair at the end of the message).

It is the hb message that is interesting one, really:

hb = h2bin(''' 
18 03 02 00 03
01 40 00
''')

18 is the heartbeat content type record, 03 02 identifies the TLS 1.1 protocol version. The 00 03 denotes how large the payload of the message is; 3 bytes, or all of the second line.

The 3 bytes of the message itself consists of the heartbeat type (01, or 'request'), and the message length (40 00, 16384 bytes), followed by no actual message. This causes a broken SSL server to send back a heartbeat response containing 16kb of memory; the non-existing 0-length request message is echoed plus the memory to make up the request length.