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.
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.
This page explained a lot about that.
const unsigned char good_data_2[] = {
// TLS record
0x16, // Content Type: Handshake
0x03, 0x01, // Version: TLS 1.0
0x00, 0x6c, // Length (use for bounds checking)
// Handshake
0x01, // Handshake Type: Client Hello
0x00, 0x00, 0x68, // Length (use for bounds checking)
0x03, 0x03, // Version: TLS 1.2
// Random (32 bytes fixed length)
0xb6, 0xb2, 0x6a, 0xfb, 0x55, 0x5e, 0x03, 0xd5,
0x65, 0xa3, 0x6a, 0xf0, 0x5e, 0xa5, 0x43, 0x02,
0x93, 0xb9, 0x59, 0xa7, 0x54, 0xc3, 0xdd, 0x78,
0x57, 0x58, 0x34, 0xc5, 0x82, 0xfd, 0x53, 0xd1,
0x00, // Session ID Length (skip past this much)
0x00, 0x04, // Cipher Suites Length (skip past this much)
0x00, 0x01, // NULL-MD5
0x00, 0xff, // RENEGOTIATION INFO SCSV
0x01, // Compression Methods Length (skip past this much)
0x00, // NULL
0x00, 0x3b, // Extensions Length (use for bounds checking)
// Extension
0x00, 0x00, // Extension Type: Server Name (check extension type)
0x00, 0x0e, // Length (use for bounds checking)
0x00, 0x0c, // Server Name Indication Length
0x00, // Server Name Type: host_name (check server name type)
0x00, 0x09, // Length (length of your data)
// "localhost" (data your after)
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
// Extension
0x00, 0x0d, // Extension Type: Signature Algorithms (check extension type)
0x00, 0x20, // Length (skip past since this is the wrong extension)
// Data
0x00, 0x1e, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03,
0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 0x04, 0x01,
0x04, 0x02, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02,
0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03,
// Extension
0x00, 0x0f, // Extension Type: Heart Beat (check extension type)
0x00, 0x01, // Length (skip past since this is the wrong extension)
0x01 // Mode: Peer allows to send requests
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With