Esempio n. 1
0
def run(args):
    """Execute wrapper using provided arguments."""
    module.LogHandler.setup(msg_prefix="{} - ".format(args["RHOSTS"]))
    if DEPENDENCIES_MISSING:
        logging.error("Module dependency (requests) is missing, cannot continue")
        return

    try:
        cotopaxi_output = common_utils.scrap_output(
            main, [args["RHOSTS"], args["RPORTS"], "-P", "DTLS"]
        )
        module.log(cotopaxi_output, "error")
        start_index = cotopaxi_output.find("Identified issues:")
        end_index = cotopaxi_output.find("Total number", start_index)
        if start_index < 0 or end_index < 0:
            raise Exception("Incorrect format of Cotopaxi response!")
        protocol_services = cotopaxi_output[
            start_index + 2 : end_index - 1
        ].splitlines()[1:]
        for protocol_service in protocol_services:
            name_start = protocol_service.find("Protocol.")
            name_end = protocol_service.find(":", name_start)
            proto_name = protocol_service[name_start + len("Protocol.") : name_end]
            services = protocol_service[name_end + 3 : -1].split(",")
            for service in services:
                service = service.strip(" '")
                service = service.split(":")
                service_ip = service[0]
                service_port = service[1].split(" ")[0]
                vuln_name = service[2]
                transport_proto = (
                    PROTOCOL_TESTERS[getattr(Protocol, proto_name)]
                    .transport_protocol()
                    .__name__
                )
                module.log(
                    "Found service - host: {} port: {} proto: {} over {}".format(
                        service_ip, service_port, proto_name, transport_proto
                    ),
                    "error",
                )
                module.log(
                    "Found vulnerability - host: {} port: {} name: {} ".format(
                        service_ip, service_port, vuln_name
                    ),
                    "error",
                )
                module.report_service(
                    service_ip,
                    proto=transport_proto.lower(),
                    port=service_port,
                    name=proto_name.lower(),
                )
                module.report_vuln(
                    service_ip, name=vuln_name, References="Cotopaxi docs"
                )
    except Exception as exc:
        module.log("Error: {}".format(exc), "error")
        logging.error(traceback.format_exc())
        return
Esempio n. 2
0
def run(args):
    module.log('start exploit')
    ret, data = exploit(args['rhost'], args['username'], args['password'])
    if ret:
        module.log('Sucsessfully added user!')
        module.report_vuln(
            args['rhost'],
            'Add New Administrator User',
            port=args['rport'],
        )
    else:
        module.log('Error! {msg}'.format(msg=data))
Esempio n. 3
0
def report_wproxy(target, response):
    # We don't use the response here, but if we were a banner scraper we could
    # print or report it
    module.report_vuln(target[0], 'wproxy', port=target[0])
Esempio n. 4
0
def run(args):
    if dependencies_missing:
        module.log(
            "Module dependencies (gmpy2 and cryptography python libraries) missing, cannot continue",
            level='error')
        return

    target = (args['rhost'], int(args['rport']))
    timeout = float(args['timeout'])
    cipher_handshake = cipher_handshakes[args['cipher_group']]

    module.log(
        "{}:{} - Scanning host for Bleichenbacher oracle".format(*target),
        level='debug')

    N, e = get_rsa_from_server(target, timeout)

    if not N:
        module.log("{}:{} - Cannot establish SSL connection: {}".format(
            *target, e),
                   level='error')
        return

    modulus_bits = int(math.ceil(math.log(N, 2)))
    modulus_bytes = (modulus_bits + 7) // 8
    module.log("{}:{} - RSA N: {}".format(*target, hex(N)), level='debug')
    module.log("{}:{} - RSA e: {}".format(*target, hex(e)), level='debug')
    module.log("{}:{} - Modulus size: {} bits, {} bytes".format(
        *target, modulus_bits, modulus_bytes),
               level='debug')

    cke_2nd_prefix = bytearray.fromhex(
        "{0:0{1}x}".format(modulus_bytes + 6, 4) + "10" +
        "{0:0{1}x}".format(modulus_bytes + 2, 6) +
        "{0:0{1}x}".format(modulus_bytes, 4))
    # pad_len is length in hex chars, so bytelen * 2
    pad_len = (modulus_bytes - 48 - 3) * 2
    rnd_pad = ("abcd" * (pad_len // 2 + 1))[:pad_len]

    rnd_pms = "aa112233445566778899112233445566778899112233445566778899112233445566778899112233445566778899"
    pms_good_in = int("0002" + rnd_pad + "00" + "0303" + rnd_pms, 16)
    # wrong first two bytes
    pms_bad_in1 = int("4117" + rnd_pad + "00" + "0303" + rnd_pms, 16)
    # 0x00 on a wrong position, also trigger older JSSE bug
    pms_bad_in2 = int("0002" + rnd_pad + "11" + rnd_pms + "0011", 16)
    # no 0x00 in the middle
    pms_bad_in3 = int("0002" + rnd_pad + "11" + "1111" + rnd_pms, 16)
    # wrong version number (according to Klima / Pokorny / Rosa paper)
    pms_bad_in4 = int("0002" + rnd_pad + "00" + "0202" + rnd_pms, 16)

    pms_good = int(gmpy2.powmod(pms_good_in, e, N)).to_bytes(modulus_bytes,
                                                             byteorder="big")
    pms_bad1 = int(gmpy2.powmod(pms_bad_in1, e, N)).to_bytes(modulus_bytes,
                                                             byteorder="big")
    pms_bad2 = int(gmpy2.powmod(pms_bad_in2, e, N)).to_bytes(modulus_bytes,
                                                             byteorder="big")
    pms_bad3 = int(gmpy2.powmod(pms_bad_in3, e, N)).to_bytes(modulus_bytes,
                                                             byteorder="big")
    pms_bad4 = int(gmpy2.powmod(pms_bad_in4, e, N)).to_bytes(modulus_bytes,
                                                             byteorder="big")

    oracle_good = oracle(target,
                         pms_good,
                         cke_2nd_prefix,
                         cipher_handshake,
                         messageflow=False,
                         timeout=timeout)
    oracle_bad1 = oracle(target,
                         pms_bad1,
                         cke_2nd_prefix,
                         cipher_handshake,
                         messageflow=False,
                         timeout=timeout)
    oracle_bad2 = oracle(target,
                         pms_bad2,
                         cke_2nd_prefix,
                         cipher_handshake,
                         messageflow=False,
                         timeout=timeout)
    oracle_bad3 = oracle(target,
                         pms_bad3,
                         cke_2nd_prefix,
                         cipher_handshake,
                         messageflow=False,
                         timeout=timeout)
    oracle_bad4 = oracle(target,
                         pms_bad4,
                         cke_2nd_prefix,
                         cipher_handshake,
                         messageflow=False,
                         timeout=timeout)

    if (oracle_good == oracle_bad1 == oracle_bad2 == oracle_bad3 ==
            oracle_bad4):
        module.log(
            "{}:{} - Identical results ({}), retrying with changed messageflow"
            .format(*target, oracle_good),
            level='info')
        oracle_good = oracle(target,
                             pms_good,
                             cke_2nd_prefix,
                             cipher_handshake,
                             messageflow=True,
                             timeout=timeout)
        oracle_bad1 = oracle(target,
                             pms_bad1,
                             cke_2nd_prefix,
                             cipher_handshake,
                             messageflow=True,
                             timeout=timeout)
        oracle_bad2 = oracle(target,
                             pms_bad2,
                             cke_2nd_prefix,
                             cipher_handshake,
                             messageflow=True,
                             timeout=timeout)
        oracle_bad3 = oracle(target,
                             pms_bad3,
                             cke_2nd_prefix,
                             cipher_handshake,
                             messageflow=True,
                             timeout=timeout)
        oracle_bad4 = oracle(target,
                             pms_bad4,
                             cke_2nd_prefix,
                             cipher_handshake,
                             messageflow=True,
                             timeout=timeout)
        if (oracle_good == oracle_bad1 == oracle_bad2 == oracle_bad3 ==
                oracle_bad4):
            module.log(
                "{}:{} - Identical results ({}), no working oracle found".
                format(*target, oracle_good),
                level='info')
            return
        else:
            flow = True
    else:
        flow = False

    # Re-checking all oracles to avoid unreliable results
    oracle_good_verify = oracle(target,
                                pms_good,
                                cke_2nd_prefix,
                                cipher_handshake,
                                messageflow=flow,
                                timeout=timeout)
    oracle_bad_verify1 = oracle(target,
                                pms_bad1,
                                cke_2nd_prefix,
                                cipher_handshake,
                                messageflow=flow,
                                timeout=timeout)
    oracle_bad_verify2 = oracle(target,
                                pms_bad2,
                                cke_2nd_prefix,
                                cipher_handshake,
                                messageflow=flow,
                                timeout=timeout)
    oracle_bad_verify3 = oracle(target,
                                pms_bad3,
                                cke_2nd_prefix,
                                cipher_handshake,
                                messageflow=flow,
                                timeout=timeout)
    oracle_bad_verify4 = oracle(target,
                                pms_bad4,
                                cke_2nd_prefix,
                                cipher_handshake,
                                messageflow=flow,
                                timeout=timeout)

    if (oracle_good !=
            oracle_good_verify) or (oracle_bad1 != oracle_bad_verify1) or (
                oracle_bad2 != oracle_bad_verify2) or (
                    oracle_bad3 != oracle_bad_verify3) or (oracle_bad4 !=
                                                           oracle_bad_verify4):
        module.log(
            "{}:{} - Getting inconsistent results, skipping".format(*target),
            level='warning')
        return

    # If the response to the invalid PKCS#1 request (oracle_bad1) is equal to both
    # requests starting with 0002, we have a weak oracle. This is because the only
    # case where we can distinguish valid from invalid requests is when we send
    # correctly formatted PKCS#1 message with 0x00 on a correct position. This
    # makes our oracle weak
    if (oracle_bad1 == oracle_bad2 == oracle_bad3):
        oracle_strength = "weak"
    else:
        oracle_strength = "strong"

    if flow:
        flowt = "shortened"
    else:
        flowt = "standard"

    s, cke_version = tls_connect(target, timeout, cipher_handshake)
    s.close()

    if cke_version[0] == 3 and cke_version[1] == 0:
        tlsver = "SSLv3"
    elif cke_version[0] == 3 and cke_version[1] == 1:
        tlsver = "TLSv1.0"
    elif cke_version[0] == 3 and cke_version[1] == 2:
        tlsver = "TLSv1.1"
    elif cke_version[0] == 3 and cke_version[1] == 3:
        tlsver = "TLSv1.2"
    else:
        tlsver = "TLS raw version %i/%i" % (cke_version[0], cke_version[1])

    module.report_vuln(target[0], 'Bleichenbacher Oracle', port=target[1])
    module.log(
        "{}:{} - Vulnerable: ({}) oracle found {} with {} message flow".format(
            *target, oracle_strength, tlsver, flowt),
        level='good')

    module.log(
        "{}:{} - Result of good request:                        {}".format(
            *target, oracle_good),
        level='debug')
    module.log(
        "{}:{} - Result of bad request 1 (wrong first bytes):   {}".format(
            *target, oracle_bad1),
        level='debug')
    module.log(
        "{}:{} - Result of bad request 2 (wrong 0x00 position): {}".format(
            *target, oracle_bad2),
        level='debug')
    module.log(
        "{}:{} - Result of bad request 3 (missing 0x00):        {}".format(
            *target, oracle_bad3),
        level='debug')
    module.log(
        "{}:{} - Result of bad request 4 (bad TLS version):     {}".format(
            *target, oracle_bad4),
        level='debug')
def run(args):
    if dependencies_missing:
        module.log("Module dependencies (gmpy2 and cryptography python libraries) missing, cannot continue", level='error')
        return

    target = (args['rhost'], int(args['rport']))
    timeout = float(args['timeout'])
    cipher_handshake = cipher_handshakes[args['cipher_group']]

    module.log("{}:{} - Scanning host for Bleichenbacher oracle".format(*target), level='debug')

    N, e = get_rsa_from_server(target, timeout)

    if not N:
        module.log("{}:{} - Cannot establish SSL connection: {}".format(*target, e), level='error')
        return

    modulus_bits = int(math.ceil(math.log(N, 2)))
    modulus_bytes = (modulus_bits + 7) // 8
    module.log("{}:{} - RSA N: {}".format(*target, hex(N)), level='debug')
    module.log("{}:{} - RSA e: {}".format(*target, hex(e)), level='debug')
    module.log("{}:{} - Modulus size: {} bits, {} bytes".format(*target, modulus_bits, modulus_bytes), level='debug')

    cke_2nd_prefix = bytearray.fromhex("{0:0{1}x}".format(modulus_bytes + 6, 4) + "10" + "{0:0{1}x}".format(modulus_bytes + 2, 6) + "{0:0{1}x}".format(modulus_bytes, 4))
    # pad_len is length in hex chars, so bytelen * 2
    pad_len = (modulus_bytes - 48 - 3) * 2
    rnd_pad = ("abcd" * (pad_len // 2 + 1))[:pad_len]

    rnd_pms = "aa112233445566778899112233445566778899112233445566778899112233445566778899112233445566778899"
    pms_good_in = int("0002" + rnd_pad + "00" + "0303" + rnd_pms, 16)
    # wrong first two bytes
    pms_bad_in1 = int("4117" + rnd_pad + "00" + "0303" + rnd_pms, 16)
    # 0x00 on a wrong position, also trigger older JSSE bug
    pms_bad_in2 = int("0002" + rnd_pad + "11" + rnd_pms + "0011", 16)
    # no 0x00 in the middle
    pms_bad_in3 = int("0002" + rnd_pad + "11" + "1111" + rnd_pms, 16)
    # wrong version number (according to Klima / Pokorny / Rosa paper)
    pms_bad_in4 = int("0002" + rnd_pad + "00" + "0202" + rnd_pms, 16)

    pms_good = int(gmpy2.powmod(pms_good_in, e, N)).to_bytes(modulus_bytes, byteorder="big")
    pms_bad1 = int(gmpy2.powmod(pms_bad_in1, e, N)).to_bytes(modulus_bytes, byteorder="big")
    pms_bad2 = int(gmpy2.powmod(pms_bad_in2, e, N)).to_bytes(modulus_bytes, byteorder="big")
    pms_bad3 = int(gmpy2.powmod(pms_bad_in3, e, N)).to_bytes(modulus_bytes, byteorder="big")
    pms_bad4 = int(gmpy2.powmod(pms_bad_in4, e, N)).to_bytes(modulus_bytes, byteorder="big")

    oracle_good = oracle(target, pms_good, cke_2nd_prefix, cipher_handshake, messageflow=False, timeout=timeout)
    oracle_bad1 = oracle(target, pms_bad1, cke_2nd_prefix, cipher_handshake, messageflow=False, timeout=timeout)
    oracle_bad2 = oracle(target, pms_bad2, cke_2nd_prefix, cipher_handshake, messageflow=False, timeout=timeout)
    oracle_bad3 = oracle(target, pms_bad3, cke_2nd_prefix, cipher_handshake, messageflow=False, timeout=timeout)
    oracle_bad4 = oracle(target, pms_bad4, cke_2nd_prefix, cipher_handshake, messageflow=False, timeout=timeout)

    if (oracle_good == oracle_bad1 == oracle_bad2 == oracle_bad3 == oracle_bad4):
        module.log("{}:{} - Identical results ({}), retrying with changed messageflow".format(*target, oracle_good), level='info')
        oracle_good = oracle(target, pms_good, cke_2nd_prefix, cipher_handshake, messageflow=True, timeout=timeout)
        oracle_bad1 = oracle(target, pms_bad1, cke_2nd_prefix, cipher_handshake, messageflow=True, timeout=timeout)
        oracle_bad2 = oracle(target, pms_bad2, cke_2nd_prefix, cipher_handshake, messageflow=True, timeout=timeout)
        oracle_bad3 = oracle(target, pms_bad3, cke_2nd_prefix, cipher_handshake, messageflow=True, timeout=timeout)
        oracle_bad4 = oracle(target, pms_bad4, cke_2nd_prefix, cipher_handshake, messageflow=True, timeout=timeout)
        if (oracle_good == oracle_bad1 == oracle_bad2 == oracle_bad3 == oracle_bad4):
            module.log("{}:{} - Identical results ({}), no working oracle found".format(*target, oracle_good), level='info')
            return
        else:
            flow = True
    else:
        flow = False

    # Re-checking all oracles to avoid unreliable results
    oracle_good_verify = oracle(target, pms_good, cke_2nd_prefix, cipher_handshake, messageflow=flow, timeout=timeout)
    oracle_bad_verify1 = oracle(target, pms_bad1, cke_2nd_prefix, cipher_handshake, messageflow=flow, timeout=timeout)
    oracle_bad_verify2 = oracle(target, pms_bad2, cke_2nd_prefix, cipher_handshake, messageflow=flow, timeout=timeout)
    oracle_bad_verify3 = oracle(target, pms_bad3, cke_2nd_prefix, cipher_handshake, messageflow=flow, timeout=timeout)
    oracle_bad_verify4 = oracle(target, pms_bad4, cke_2nd_prefix, cipher_handshake, messageflow=flow, timeout=timeout)

    if (oracle_good != oracle_good_verify) or (oracle_bad1 != oracle_bad_verify1) or (oracle_bad2 != oracle_bad_verify2) or (oracle_bad3 != oracle_bad_verify3) or (oracle_bad4 != oracle_bad_verify4):
        module.log("{}:{} - Getting inconsistent results, skipping".format(*target), level='warning')
        return

    # If the response to the invalid PKCS#1 request (oracle_bad1) is equal to both
    # requests starting with 0002, we have a weak oracle. This is because the only
    # case where we can distinguish valid from invalid requests is when we send
    # correctly formatted PKCS#1 message with 0x00 on a correct position. This
    # makes our oracle weak
    if (oracle_bad1 == oracle_bad2 == oracle_bad3):
        oracle_strength = "weak"
    else:
        oracle_strength = "strong"

    if flow:
        flowt = "shortened"
    else:
        flowt = "standard"

    s, cke_version = tls_connect(target, timeout, cipher_handshake)
    s.close()

    if cke_version[0] == 3 and cke_version[1] == 0:
        tlsver = "SSLv3"
    elif cke_version[0] == 3 and cke_version[1] == 1:
        tlsver = "TLSv1.0"
    elif cke_version[0] == 3 and cke_version[1] == 2:
        tlsver = "TLSv1.1"
    elif cke_version[0] == 3 and cke_version[1] == 3:
        tlsver = "TLSv1.2"
    else:
        tlsver = "TLS raw version %i/%i" % (cke_version[0], cke_version[1])

    module.report_vuln(target[0], 'Bleichenbacher Oracle', port=target[1])
    module.log("{}:{} - Vulnerable: ({}) oracle found {} with {} message flow".format(*target, oracle_strength, tlsver, flowt), level='good')

    module.log("{}:{} - Result of good request:                        {}".format(*target, oracle_good), level='debug')
    module.log("{}:{} - Result of bad request 1 (wrong first bytes):   {}".format(*target, oracle_bad1), level='debug')
    module.log("{}:{} - Result of bad request 2 (wrong 0x00 position): {}".format(*target, oracle_bad2), level='debug')
    module.log("{}:{} - Result of bad request 3 (missing 0x00):        {}".format(*target, oracle_bad3), level='debug')
    module.log("{}:{} - Result of bad request 4 (bad TLS version):     {}".format(*target, oracle_bad4), level='debug')
Esempio n. 6
0
def run(args):
    """Execute wrapper using provided arguments."""
    module.LogHandler.setup(msg_prefix="{} - ".format(args["RHOSTS"]))
    if DEPENDENCIES_MISSING:
        logging.error(
            "Module dependency (requests) is missing, cannot continue")
        return

    try:
        parameters = [
            args["RHOSTS"], args["RPORTS"], "-V", "-P", MODULE_PROTOCOL
        ]
        if "true" == args["IGNORE_PING_CHECK"]:
            parameters += ["--ignore-ping-check"]
        if args["PATH_CORPUS"].strip():
            parameters += ["-C", args["PATH_CORPUS"]]
        cotopaxi_output = common_utils.scrap_output(main, parameters)
        module.log(cotopaxi_output, "error")
        start_index = cotopaxi_output.find("Payloads causing crash:")
        end_index = cotopaxi_output.find("Total number", start_index)
        if start_index < 0 or end_index < 0:
            raise Exception("Incorrect format of Cotopaxi response!")
        protocol_services = cotopaxi_output[start_index + 2:end_index -
                                            1].splitlines()[1:]
        for protocol_service in protocol_services:
            name_start = protocol_service.find("Protocol.")
            name_end = protocol_service.find(":", name_start)
            proto_name = protocol_service[name_start +
                                          len("Protocol."):name_end]
            services = protocol_service[name_end + 3:-1].split(",")
            for service in services:
                service = service.strip(" '")
                service = service.split(":")
                service_ip = service[0]
                service_port = service[1].split(" ")[0]
                payload = service[2]
                transport_proto = (PROTOCOL_TESTERS[getattr(
                    Protocol, proto_name)].transport_protocol().__name__)
                module.log(
                    "Found service - host: {} port: {} proto: {} over {} using {}"
                    .format(
                        service_ip,
                        service_port,
                        proto_name,
                        transport_proto,
                        MODULE_PROTOCOL.lower(),
                    ),
                    "error",
                )
                module.report_service(
                    service_ip,
                    proto=transport_proto.lower(),
                    port=service_port,
                    name=proto_name.lower(),
                    # info="Server: " + service_name,
                )
                module.log(
                    "Found vulnerability - host: {} port: {} name: crash after payload: {} "
                    .format(service_ip, service_port, payload),
                    "error",
                )
                module.report_vuln(
                    service_ip,
                    name="Fuzzer crash - payload {}".format(payload),
                    References="Cotopaxi docs",
                )
    except Exception as exc:
        module.log("Error: {}".format(exc), "error")
        logging.error(traceback.format_exc())
        return
def report_wproxy(target, response):
    # We don't use the response here, but if we were a banner scraper we could
    # print or report it
    module.report_vuln(target[0], 'wproxy', port=target[0])