def __init__( self, target, dtls_version=ENUM_DTLS_VERSIONS.DTLS_1_1, confirm_hello_verify=True, starttls=None, test_params=None, ): """Create empty DTLSClient object.""" last_exception = Exception() self.target = target self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.local_port = get_random_high_port() self._sock.bind((get_local_ip(), self.local_port)) self.cookie = None self.cookie_length = 0 self.test_params = test_params if confirm_hello_verify: pkt = DTLSRecord( version=dtls_version, sequence=0, content_type=TLSContentType.HANDSHAKE) / DTLSHandshakes( handshakes=[ DTLSHandshake(fragment_offset=0) / DTLSClientHello( version=dtls_version, compression_methods=0, cipher_suites=list(range(0xFE))[::-1], ) ]) sent_time = self.test_params.report_sent_packet() self.sendall(pkt) resp = DTLSRecord(self.recv(timeout=1)) self.test_params.report_received_packet(sent_time) print_verbose(self.test_params, "------------- START response --------------") show_verbose(self.test_params, resp) print_verbose(self.test_params, "------------- STOP response --------------") # if resp and resp.haslayer(DTLSRecord) and resp[DTLSRecord].type == # ENUM_DTLS_HANDSHAKE_TYPES.HELLO_VERIFY_REQUEST: if resp and resp.haslayer(DTLSHelloVerify): print_verbose(self.test_params, "Found DTLSHelloVerify") self.cookie = resp[DTLSHelloVerify].cookie self.cookie_length = resp[DTLSHelloVerify].cookie_length # pkt[DTLSClientHello].cookie = dtls_client_hello.cookie # pkt[DTLSClientHello].cookie_length = dtls_client_hello.cookie_length # self.sendall(pkt) # print("------------- START ClientHello with cookie --------------") # pkt.show() # print("------------- STOP ClientHello with cookie --------------") if not self._sock: raise last_exception if starttls: self.sendall(starttls.replace("\\r", "\r").replace("\\n", "\n")) self.recvall(timeout=2)
def xxx_scan_heartbleed( self, target, starttls=None, version=ENUM_DTLS_VERSIONS.DTLS_1_0, test_params=None, ): """Plugin for verifying vulnerability to Heartbleed attack by DTLS server.""" try: client = DTLSClient(target, starttls=starttls, test_params=test_params) pkt = DTLSRecord(version=version) / DTLSHandshakes(handshakes=[ DTLSHandshake() / DTLSClientHello(version=version) ]) sent_time = self.test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=0.5) self.test_params.report_received_packet(sent_time) pkt = DTLSRecord(version=version) / TLSHeartBeat(length=2**14 - 1, data="bleed...") sent_time = self.test_params.report_sent_packet() client.sendall(str(pkt)) resp = client.recvall(timeout=0.5) self.test_params.report_received_packet(sent_time) if resp.haslayer(TLSHeartBeat) and resp[TLSHeartBeat].length > 8: self.report_issue("HEARTBLEED - vulnerable", resp) except socket.error as sock_err: print(repr(sock_err)) return None return resp
def xxx_scan_secure_renegotiation( self, target, starttls=None, version=ENUM_DTLS_VERSIONS.DTLS_1_0, test_params=None, ): """Plugin for verifying vulnerability to Insecure Renegotiations by DTLS server.""" # todo: also test EMPTY_RENEGOTIATION_INFO_SCSV try: client = DTLSClient(target, starttls=starttls, test_params=test_params) pkt = DTLSRecord(version=version) / DTLSHandshakes(handshakes=[ DTLSHandshake() / DTLSClientHello( version=version, extensions=TLSExtension() / TLSExtRenegotiationInfo(), ) ]) sent_time = self.test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=0.5) self.test_params.report_received_packet(sent_time) if resp.haslayer(TLSExtRenegotiationInfo): self.report_issue( "DTLS EXTENSION SECURE RENEGOTIATION - not supported", resp) except socket.error as sock_err: print(repr(sock_err)) return None return resp
def _scan_scsv(self, target, starttls=None, test_params=None): """Verify SCSV support by DTLS server.""" pkt = DTLSRecord(version=ENUM_DTLS_VERSIONS.DTLS_1_1) / DTLSHandshakes( handshakes=[ DTLSHandshake() / DTLSClientHello( version=ENUM_DTLS_VERSIONS.DTLS_1_0, cipher_suites=[TLSCipherSuite.FALLBACK_SCSV] + list(range(0xFE))[::-1], ) ]) try: client = DTLSClient(target, starttls=starttls, test_params=test_params) sent_time = test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=2) test_params.report_received_packet(sent_time) self.capabilities.insert(resp, client=False) if not (resp.haslayer(TLSAlert) and resp[TLSAlert].description == TLSAlertDescription.INAPPROPRIATE_FALLBACK): self.capabilities.report_issue( "DOWNGRADE / POODLE - FALLBACK_SCSV - not honored", resp) except socket.error as sock_err: print(repr(sock_err))
def _check_cipher( target, cipher_id, starttls=None, version=ENUM_DTLS_VERSIONS.DTLS_1_0, test_params=None, ): """Check whether particular cipher is listed.""" pkt = DTLSRecord(sequence=0, content_type=TLSContentType.HANDSHAKE, version=version) / DTLSHandshakes(handshakes=[ DTLSHandshake(fragment_offset=0) / DTLSClientHello(version=version, cipher_suites=[cipher_id], compression_methods=0) ]) try: client = DTLSClient(target, starttls=starttls, test_params=test_params) pkt[DTLSClientHello].cookie = client.cookie pkt[DTLSClientHello].cookie_length = client.cookie_length sent_time = test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=0.5) test_params.report_received_packet(sent_time) except socket.error as sock_err: print(repr(sock_err)) return None return resp
def _scan_compressions(self, target, starttls=None, compression_list=None, test_params=None): """Identify possible compressions in DTLS.""" if not compression_list: compression_list = list(DTLS_COMPRESSION_METHODS.keys()) for comp in compression_list: # prepare pkt pkt = DTLSRecord( sequence=0, content_type=TLSContentType.HANDSHAKE) / DTLSHandshakes( handshakes=[ DTLSHandshake(fragment_offset=0) / DTLSClientHello( version=ENUM_DTLS_VERSIONS.DTLS_1_1, cipher_suites=list(range(0xFE))[::-1], compression_methods=comp, ) ]) try: client = DTLSClient(target, starttls=starttls, test_params=test_params) pkt[DTLSClientHello].cookie = client.cookie pkt[DTLSClientHello].cookie_length = client.cookie_length sent_time = test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=0.5) test_params.report_received_packet(sent_time) self.capabilities.insert(resp, client=False) except socket.error as sock_err: print(repr(sock_err))
def xxx_scan_certificates(self, target, starttls=None, test_params=None): """Plugin for identyfing server certificates in DTLS""" # with open("512b-dsa-example-cert.der", "r") as file_handle: # test_packet = file_handle.read().strip() # print("Test packet = ") # print(test_packet) # print("==============") # test_packet = "123123123" # print("_scan_certificates") pkt_hello = DTLSRecord( sequence=0, content_type=TLSContentType.HANDSHAKE, version=ENUM_DTLS_VERSIONS.DTLS_1_1, ) / DTLSHandshakes( handshakes=[ DTLSHandshake(fragment_offset=0) / DTLSClientHello( version=ENUM_DTLS_VERSIONS.DTLS_1_1, cipher_suites=list(range(0xFE))[::-1], compression_methods=0, ) ] ) pkt = DTLSRecord( sequence=0, content_type=TLSContentType.HANDSHAKE, version=ENUM_DTLS_VERSIONS.DTLS_1_1, ) / DTLSHandshakes( handshakes=[ DTLSHandshake(fragment_offset=0) / TLSCertificateList() / TLS13Certificate( # certificates=[TLSCertificate(data=X509_Cert(test_packet))], length=600 ) ] ) # show_verbose(test_params, pkt) print (pkt) try: client = DTLSClient(target, starttls=starttls, test_params=test_params) pkt_hello[DTLSClientHello].cookie = client.cookie pkt_hello[DTLSClientHello].cookie_length = client.cookie_length sent_time = test_params.report_sent_packet() client.sendall(pkt_hello) resp = client.recvall(timeout=0.1) test_params.report_received_packet(sent_time) sent_time = test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=0.5) test_params.report_received_packet(sent_time) self.capabilities.insert(resp, client=False) except socket.error as sock_err: print (repr(sock_err))
def _scan_supported_protocol_versions( self, target, starttls=None, versionlist=((k, v) for k, v in DTLS_VERSIONS.items() if v.startswith("DTLS_")), test_params=None, ): """Identify possible protocol versions of DTLS server.""" for magic, ___ in versionlist: pkt = DTLSRecord( version=magic, sequence=0, content_type=TLSContentType.HANDSHAKE) / DTLSHandshakes( handshakes=[ DTLSHandshake(fragment_offset=0) / DTLSClientHello( version=magic, compression_methods=0, cipher_suites=list(range(0xFE))[::-1], ) ]) # , # extensions=[TLSExtension() / # TLSExtHeartbeat(mode=TLSHeartbeatMode.PEER_ALLOWED_TO_SEND)])]) # pkt.show() try: client = DTLSClient(target, starttls=starttls, test_params=test_params) sent_time = test_params.report_sent_packet() client.sendall(pkt) resp = client.recvall(timeout=0.5) test_params.report_received_packet(sent_time) self.capabilities.insert(resp, client=False) resp = client.recvall(timeout=0.5) self.capabilities.insert(resp, client=False) except socket.error as sock_err: print(repr(sock_err))