Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
 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))
Exemplo n.º 4
0
 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
Exemplo n.º 5
0
 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))
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
 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))
Exemplo n.º 8
0
def scrap_response(test_params, packet):
    """Scraps text description of DTLS packet"""
    try:
        in_data = packet[Raw].load
        response = DTLSRecord(in_data)
        print_verbose(
            test_params, "Received packet DTLS type {}".format(response.content_type)
        )
        show_verbose(test_params, response)
        return response
    except (struct.error, TypeError, IndexError):
        print_verbose(test_params, "Parsing of DTLS message failed!")
    return None
Exemplo n.º 9
0
def udp_send(test_params, data):
    """Send data using UDP protocol."""
    dst_ip = IPY_IP(test_params.dst_endpoint.ip_addr)
    if dst_ip.version() == 4:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    elif dst_ip.version() == 6:
        sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    sock.settimeout(test_params.timeout_sec)

    request_size = len(data)
    # response_size = 0
    print_verbose(
        test_params,
        "src_ip: {} src_port: {} nr_retries: {}".format(
            test_params.src_endpoint.ip_addr,
            test_params.src_endpoint.port,
            test_params.nr_retries,
        ),
    )

    sock.sendto(
        data,
        (test_params.dst_endpoint.ip_addr, test_params.dst_endpoint.port))

    try:
        in_data, server_addr = sock.recvfrom(INPUT_BUFFER_SIZE)
    except socket.timeout:
        print_verbose(test_params, "Timeout")
        print_verbose(test_params, "Request size = {}".format(request_size))
        return None

    response_size = len(in_data)
    print_verbose(
        test_params,
        "Received packet size {} from {}".format(len(in_data), server_addr))

    try:
        response = DTLSRecord(in_data)
    except struct.error:
        print_verbose(test_params, "Parsing of DTLS message failed!")
        print_verbose(test_params, "Request size = {}".format(request_size))
        print_verbose(test_params, "Response size = {}".format(response_size))
        return in_data

    print_verbose(test_params,
                  "Received packet DTLS type {}".format(response.content_type))
    show_verbose(test_params, response)
    return response
Exemplo n.º 10
0
 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))
Exemplo n.º 11
0
def prepare_dtls_test_packets():
    """Prepares list of packets to perform server fingerprinting."""
    test_packets = [
        DTLS_1_0_CLIENT_KEY_EXCHANGE_MBED_CLIENT,
        DTLS_1_0_CLIENT_APP_DATA_MBED_CLIENT,
        DTLS_1_0_CLIENT_ENCRYPTED_ALERT_MBED_CLIENT,
        DTLS_1_0_CERT_FRAGMENT,
    ]

    # malformed packets based on DTLS_1_0
    data = codecs.decode(DTLS_1_0_HELLO_NMAP, "hex")
    # dtls_1_0_hello = DTLSRecord(data)
    # dtls_1_2_hello.version = 0xfefd # DTLS 1.2

    dtls_hello_malformed_version = DTLSRecord(data)
    dtls_hello_malformed_version.version = 0x0000  # malformed DTLS version
    dtls_hello_malformed_version[
        DTLSClientHello
    ].version = 0x0000  # malformed DTLS version
    # dtls_hello_malformed_version.show()
    test_packets.append(dtls_hello_malformed_version)

    dtls_1_0_hello_malformed_ctype = DTLSRecord(data)
    dtls_1_0_hello_malformed_ctype.content_type = 0xFF  # malformed content type
    # dtls_1_0_hello_malformed_ctype.show()
    test_packets.append(dtls_1_0_hello_malformed_ctype)

    dtls_1_0_hello_malformed_epoch = DTLSRecord(data)
    dtls_1_0_hello_malformed_epoch.epoch = 0xFF  # malformed epoch
    # dtls_1_0_hello_malformed_epoch.show()
    test_packets.append(dtls_1_0_hello_malformed_epoch)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    dtls_1_0_hello_malformed.sequence = 0xFF  # malformed sequence
    # dtls_1_0_hello_malformed.show()
    test_packets.append(dtls_1_0_hello_malformed)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    # dtls_1_0_hello_malformed[DTLSClientHello].cookie = '010000000000'
    dtls_1_0_hello_malformed[
        DTLSClientHello
    ].cookie_length = 0x0002  # malformed cookie len
    # dtls_1_0_hello_malformed.show()
    test_packets.append(dtls_1_0_hello_malformed)

    # malformed packets based on DTLS_1_0

    data = codecs.decode(DTLS_1_2_HELLO_OPENSSL_CLIENT, "hex")
    dtls_1_2_hello = DTLSRecord(data)
    dtls_1_2_hello.version = 0xFEFD  # DTLS 1.2
    data = str(dtls_1_2_hello)
    # dtls_1_2_hello.show()
    # test_packets.append(dtls_1_2_hello)

    dtls_hello_malformed_version = DTLSRecord(data)
    dtls_hello_malformed_version.version = 0xFEFD  # DTLS 1.2
    dtls_hello_malformed_version[
        DTLSClientHello
    ].version = 0x0000  # malformed DTLS version
    # dtls_hello_malformed_version.show()
    test_packets.append(dtls_hello_malformed_version)

    dtls_1_0_hello_malformed_ctype = DTLSRecord(data)
    dtls_1_0_hello_malformed_ctype.content_type = 0xFF  # malformed content type
    # dtls_1_0_hello_malformed_ctype.show()
    test_packets.append(dtls_1_0_hello_malformed_ctype)

    dtls_1_0_hello_malformed_epoch = DTLSRecord(data)
    dtls_1_0_hello_malformed_epoch.epoch = 0xFF  # malformed epoch
    # dtls_1_0_hello_malformed_epoch.show()
    test_packets.append(dtls_1_0_hello_malformed_epoch)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    dtls_1_0_hello_malformed.sequence = 0xFF  # malformed sequence
    # dtls_1_0_hello_malformed.show()
    test_packets.append(dtls_1_0_hello_malformed)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    # dtls_1_0_hello_malformed[DTLSClientHello].cookie = '010000000000'
    dtls_1_0_hello_malformed[
        DTLSClientHello
    ].cookie_length = 0x0002  # malformed cookie len
    # dtls_1_0_hello_malformed.show()
    test_packets.append(dtls_1_0_hello_malformed)
    encoded = [codecs.encode(str(packet), "hex") for packet in test_packets]
    return encoded
Exemplo n.º 12
0
def show_dtls_packet(packet):
    """"Displays DTLS packet."""
    if packet.getlayer(Raw):
        dtls = DTLSRecord(packet[Raw].load)
        print (dtls)
Exemplo n.º 13
0
def prepare_dtls_test_packets():
    """Prepare list of packets to perform server fingerprinting."""
    test_packets = [
        DTLS_1_0_CLIENT_KEY_EXCHANGE_MBED_CLIENT,
        DTLS_1_0_CLIENT_APP_DATA_MBED_CLIENT,
        DTLS_1_0_CLIENT_ENCRYPTED_ALERT_MBED_CLIENT,
        DTLS_1_0_CERT_FRAGMENT,
    ]

    # malformed packets based on DTLS_1_0
    data = codecs.decode(DTLS_1_0_HELLO_NMAP, "hex")
    # dtls_1_0_hello = DTLSRecord(data)
    # dtls_1_2_hello.version = 0xfefd # DTLS 1.2

    dtls_hello_malformed_version = DTLSRecord(data)
    dtls_hello_malformed_version.version = 0x0000  # malformed DTLS version
    dtls_hello_malformed_version[
        DTLSClientHello
    ].version = 0x0000  # malformed DTLS version
    # dtls_hello_malformed_version.show()
    # 1
    test_packets.append(dtls_hello_malformed_version)

    dtls_1_0_hello_malformed_ctype = DTLSRecord(data)
    dtls_1_0_hello_malformed_ctype.content_type = 0xFF  # malformed content type
    # dtls_1_0_hello_malformed_ctype.show()
    # 2
    test_packets.append(dtls_1_0_hello_malformed_ctype)

    dtls_1_0_hello_malformed_epoch = DTLSRecord(data)
    dtls_1_0_hello_malformed_epoch.epoch = 0xFF  # malformed epoch
    # dtls_1_0_hello_malformed_epoch.show()
    # 3
    test_packets.append(dtls_1_0_hello_malformed_epoch)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    dtls_1_0_hello_malformed.sequence = 0xFF  # malformed sequence
    # dtls_1_0_hello_malformed.show()
    # 4
    test_packets.append(dtls_1_0_hello_malformed)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    # dtls_1_0_hello_malformed[DTLSClientHello].cookie = '010000000000'
    dtls_1_0_hello_malformed[
        DTLSClientHello
    ].cookie_length = 0x0002  # malformed cookie len
    # dtls_1_0_hello_malformed.show()
    # 5
    test_packets.append(dtls_1_0_hello_malformed)
    # test_packets.append(dtls_1_0_hello_malformed_ctype) # UWAGA - podmiana!!!!

    # malformed packets based on DTLS_1_0

    data = codecs.decode(DTLS_1_2_HELLO_OPENSSL_CLIENT, "hex")
    dtls_1_2_hello = DTLSRecord(data)
    dtls_1_2_hello.version = 0xFEFD  # DTLS 1.2
    data = str(dtls_1_2_hello)
    # dtls_1_2_hello.show()
    # test_packets.append(dtls_1_2_hello)

    with open(
        FINGERPRINTING_DIR + "dtls_hello_malformed_version.raw", "rb"
    ) as file_handle:
        dtls_hello_malformed_version = file_handle.read()
    test_packets.append(dtls_hello_malformed_version)

    dtls_1_0_hello_malformed_ctype = DTLSRecord(data)
    dtls_1_0_hello_malformed_ctype.content_type = 0xFF  # malformed content type
    # dtls_1_0_hello_malformed_ctype.show()
    test_packets.append(dtls_1_0_hello_malformed_ctype)

    dtls_1_0_hello_malformed_epoch = DTLSRecord(data)
    dtls_1_0_hello_malformed_epoch.epoch = 0xFF  # malformed epoch
    # dtls_1_0_hello_malformed_epoch.show()
    test_packets.append(dtls_1_0_hello_malformed_epoch)

    dtls_1_0_hello_malformed = DTLSRecord(data)
    dtls_1_0_hello_malformed.sequence = 0xFF  # malformed sequence
    # dtls_1_0_hello_malformed.show()
    test_packets.append(dtls_1_0_hello_malformed)

    with open(FINGERPRINTING_DIR + "dtls_1_0_hello_malformed.raw", "rb") as file_handle:
        dtls_1_0_hello_malformed = file_handle.read()
    test_packets.append(dtls_1_0_hello_malformed)

    # packet_nr = 0
    # for packet in test_packets:
        # print(packet_nr)
        # print("Packet size = {}".format(len(str(packet))))
        # print(packet)
        # print("-")
        # print(bytes(str(packet), encoding='ascii'))
        # print("-")

        # P2.7
        # print("encoded.append('" + codecs.encode(bytes(packet), "hex") + "')")
        # encoded.append(codecs.encode(bytes(packet), "hex"))
        # with open(dtls_finger_file_format.format(packet_nr), "w") as file_handle:
        #    file_handle.write(bytes(packet))

        # P3.6
        # print(codecs.encode(bytes(str(packet), encoding='utf-8'), "hex"))
        # encoded.append(codecs.encode(bytes(str(packet), encoding='utf-8'), "hex"))
        # packet_nr += 1

    encoded = [codecs.encode(bytes(packet), "hex") for packet in test_packets]
    return encoded