Esempio n. 1
0
def analyse(session: Session, layer: Layer):

    current_creds = session.credentials_being_built

    if hasattr(layer, "request_command"):
        command = layer.request_command

        if hasattr(layer, "request_parameter"):
            parameter = layer.request_parameter

            if command == "AUTH":
                # TODO : handle more types of auth
                if parameter == "PLAIN":
                    session["auth_process_plain"] = True

        elif session["auth_process_plain"]:
            session["auth_process_plain"] = False
            current_creds.username, current_creds.password = utils.parse_sasl_creds(
                command, "PLAIN")

    if current_creds.username and hasattr(layer, "response_indicator"):
        indicator = layer.response_indicator

        if indicator == "+OK":
            logger.found(
                session,
                "credentials found: {} -- {}".format(current_creds.username,
                                                     current_creds.password))
            session.validate_credentials()

        elif indicator == "-ERR":
            session.invalidate_credentials_and_clear_session()
Esempio n. 2
0
def analyse(session: Session, layer: Layer):

    current_creds = session.credentials_being_built

    if hasattr(layer, "response_code"):
        code = int(layer.response_code)

        if code == 230 and current_creds.username:
            logger.found(
                session,
                "credentials found: {} -- {}".format(current_creds.username,
                                                     current_creds.password))
            session.validate_credentials()

        elif code == 430:
            session.invalidate_credentials_and_clear_session()

    elif hasattr(layer, "request_command"):
        command = layer.request_command

        if command == "USER":
            current_creds.username = layer.request_arg

        elif command == "PASS":
            current_creds.password = layer.request_arg
Esempio n. 3
0
def analyse(session: Session, layer: Layer):

    current_creds = session.credentials_being_built

    if hasattr(layer, "request_command"):
        command = layer.request_command

        if command == "LOGIN":
            tokens = layer.request.split('"')
            current_creds.username = tokens[1]
            current_creds.password = tokens[3]

    # Due to an incompatibility with "old" tshark versions, we cannot use response_command :(
    elif hasattr(layer, "response"):
        command = layer.response

        if " LOGIN " in command:
            status = layer.response_status

            if status == "OK":
                logger.found(
                    session, "credentials found: {} -- {}".format(
                        current_creds.username, current_creds.password))
                session.validate_credentials()

            elif status == "NO" or status == "BAD":
                session.invalidate_credentials_and_clear_session()
Esempio n. 4
0
def analyse(session: Session, layer: Layer):

    if not hasattr(layer, "data"):
        return

    current_creds = session.credentials_being_built

    # Sometimes tshark returns multiple Data fields
    data_fields = layer.data.all_fields

    for data in data_fields:

        if session["data_being_built"] is None:
            session["data_being_built"] = ""
            session["user_being_built"] = session["pass_being_built"] = False

        try:
            data = data.binary_value.decode()
        except UnicodeDecodeError:
            continue

        lowered_data = data.lower().strip()

        for username_ask in POTENTIAL_USERNAME_ASK:
            if lowered_data.endswith(username_ask):
                session["user_being_built"] = True
                break

        else:  # Yes for loops have elses ;)
            if lowered_data.endswith("password:"******"pass_being_built"] = True

            elif current_creds.password:
                for auth_success_msg in POTENTIAL_AUTH_SUCCESS:
                    if auth_success_msg in lowered_data:
                        logger.found(
                            session, "credentials found: {} -- {}".format(
                                current_creds.username,
                                current_creds.password))
                        session.validate_credentials()
                        return

                for auth_error_msg in POTENTIAL_AUTH_ERROR:
                    if auth_error_msg in lowered_data:
                        session.invalidate_credentials_and_clear_session()

            else:
                session["data_being_built"] += data

                if "\r" in session["data_being_built"] or "\n" in session[
                        "data_being_built"]:
                    data_being_built = session["data_being_built"].replace("\r", "")\
                                                                  .replace("\n", "")\
                                                                  .replace("\x00", "")

                    if session["user_being_built"]:
                        username = data_being_built

                        if _is_username_duplicated(username):
                            username = "".join([
                                username[i]
                                for i in range(0, len(username), 2)
                            ])

                        current_creds.username = username
                        session["user_being_built"] = False

                    elif session["pass_being_built"]:
                        current_creds.password = data_being_built
                        session["pass_being_built"] = False

                    session["data_being_built"] = ""
Esempio n. 5
0
def analyse(session: Session, layer: Layer):

    current_creds = session.credentials_being_built

    if hasattr(layer, "request_uri"):

        extension = layer.request_uri.split(".")[-1]

        if extension in HTTP_IGNORED_EXTENSIONS:
            return

        # Ignore Certificate Status Protocol
        if hasattr(layer, "request_full_uri"
                   ) and layer.request_full_uri.startswith("http://ocsp."):
            return

        if hasattr(layer, "authorization"):
            tokens = layer.authorization.split(" ")

            if len(tokens) == 2 and tokens[0] == "Basic":
                try:
                    credentials = base64.b64decode(tokens[1]).decode()
                    colon_index = credentials.find(":")
                    current_creds.username = credentials[:colon_index]
                    current_creds.password = credentials[colon_index + 1:]
                    session[
                        "authorization_header_uri"] = layer.request_full_uri
                except UnicodeDecodeError:
                    logger.error("HTTP Basic auth failed: " + tokens)

            elif len(tokens) == 2 and tokens[0] == "NTLM":
                pass  # Already handled by the NTLMSSP module

            else:
                logger.info(
                    session, "Authorization header found: '{}'".format(
                        layer.authorization))

        # POST parameters
        if hasattr(layer, "file_data"):
            post_content = layer.file_data

            if len(post_content) <= HTTP_AUTH_MAX_LOGIN_POST_LENGTH:
                logger.info(session,
                            "POST data found: '{}'".format(post_content))
                post_parameters = parse_qs(post_content)

                # We don't want to interfere with the Authorization header potentially being built
                credentials = Credentials()

                credentials.context["Method"] = "POST"
                credentials.context["URL"] = layer.request_full_uri

                logger.info(session, "context: " + str(credentials.context))

                for parameter in post_parameters:
                    if parameter in HTTP_AUTH_POTENTIAL_USERNAMES:
                        credentials.username = post_parameters[parameter][0]
                    elif parameter in HTTP_AUTH_POTENTIAL_PASSWORDS:
                        credentials.password = post_parameters[parameter][0]

                if credentials.username:
                    logger.found(
                        session, "credentials found: {} -- {}".format(
                            credentials.username, credentials.password))
                    session.credentials_list.append(
                        credentials)  # Don't validate those credentials
                    return

        # GET parameters
        elif hasattr(layer, "request_uri_query"):
            get_parameters = parse_qs(layer.request_uri_query)

            # We don't want to interfere with the Authorization header potentially being built
            credentials = Credentials()

            credentials.context["Method"] = "GET"
            credentials.context["URL"] = layer.request_full_uri

            for parameter in get_parameters:
                if parameter in HTTP_AUTH_POTENTIAL_USERNAMES:
                    credentials.username = get_parameters[parameter][0]
                elif parameter in HTTP_AUTH_POTENTIAL_PASSWORDS:
                    credentials.password = get_parameters[parameter][0]

            if credentials.username:
                logger.found(
                    session, "credentials found: {} -- {}".format(
                        credentials.username, credentials.password))
                logger.info(session, "context: " + str(credentials.context))
                session.credentials_list.append(
                    credentials)  # Don't validate those credentials
                return

    elif hasattr(layer, "response_for_uri"):

        if session["authorization_header_uri"] == layer.response_for_uri:

            # If auth failed + prevent duplicates
            if layer.response_code == "401" or current_creds in session.credentials_list:
                session.invalidate_credentials_and_clear_session()

            else:
                logger.found(
                    session, "basic auth credentials found: {} -- {}".format(
                        current_creds.username, current_creds.password))
                session.validate_credentials()
Esempio n. 6
0
def analyse(session: Session, layer: Layer):

    current_creds = session.credentials_being_built

    if current_creds and hasattr(layer, "nt_status"):
        status = int(layer.nt_status)

        if status == 0:  # LOGON SUCCESS
            logger.found(
                session,
                "{} found: {}".format(current_creds.context["version"],
                                      current_creds.hash))
            session.validate_credentials()

        elif status == 3221225581:  # LOGON FAILED
            session.invalidate_credentials_and_clear_session()

    if hasattr(layer, "ntlmssp_messagetype"):
        message_type = int(layer.ntlmssp_messagetype, 16)

        if message_type == 2:  # Challenge
            session["challenge"] = layer.ntlmssp_ntlmserverchallenge.replace(
                ":", "")

        elif message_type == 3:  # Auth

            username = layer.ntlmssp_auth_username
            domain = layer.ntlmssp_auth_domain
            challenge = session["challenge"]

            if len(username) == 1 or len(domain) == 1:
                username, domain = _fix_tshark_widechar_issue(layer)

            if not challenge:
                challenge = "CHALLENGE_NOT_FOUND"

            if domain == "NULL":
                domain = ""

            if hasattr(layer, "ntlmssp_ntlmv2_response"):
                current_creds.context["version"] = "NETNTLMv2"
                proof = layer.ntlmssp_ntlmv2_response_ntproofstr
                auth_ntresponse = layer.ntlmssp_ntlmv2_response[len(proof) +
                                                                1:]
                proof = proof.replace(":", "")
                auth_ntresponse = auth_ntresponse.replace(":", "")
                current_creds.hash = "{}::{}:{}:{}:{}".format(
                    username, domain, session["challenge"], proof,
                    auth_ntresponse)

            elif hasattr(layer, "ntlmssp_ntlmclientchallenge"):
                current_creds.context["version"] = "NETNTLMv1"
                auth_ntresponse = layer.ntlmssp_auth_ntresponse.replace(
                    ":", "")
                client_challenge = layer.ntlmssp_ntlmclientchallenge.replace(
                    ":", "").ljust(48, "0")
                current_creds.hash = "{}::{}:{}:{}:{}".format(
                    username, domain, client_challenge, auth_ntresponse,
                    challenge)

            else:  # Unsupported NTLM format, investigate ? Found a pcap w/o ntlm client challenge field
                session.invalidate_credentials_and_clear_session()