Beispiel #1
0
def _fix_tshark_widechar_issue(layer) -> (str, str):
    if hasattr(layer, "authorization") and layer.authorization.startswith("NTLM "):  # HTTP header dirty fix
        ntlm_bytes = base64.b64decode(layer.authorization[5:])
        username_offset = int(layer.ntlmssp_string_offset.all_fields[1].show)
        domain_offset = int(layer.ntlmssp_string_offset.all_fields[0].show)
        username_length = int(layer.ntlmssp_string_length.all_fields[1].show)
        domain_length = int(layer.ntlmssp_string_length.all_fields[0].show)

        username = ntlm_bytes[username_offset:username_offset + username_length].replace(b"\x00", b"").decode()
        domain = ntlm_bytes[domain_offset:domain_offset + domain_length].replace(b"\x00", b"").decode()
        return username, domain

    else:  # Not able to find a fix
        logger.error("The username or domain are only 1 character long, probably because of wide characters, "
                     "investigate manually.")

        return "UNKNOWN", "UNKNOWN"
Beispiel #2
0
def process_pcap(filename: str,
                 must_inspect_strings=False,
                 tshark_filter=None,
                 debug=False,
                 decode_as=None) -> SessionList:

    global _sessions

    logger.DEBUG_MODE = debug
    _sessions = SessionList()

    pcap = pyshark.FileCapture(filename,
                               display_filter=tshark_filter,
                               decode_as=decode_as)
    logger.info("Processing packets in '{}'".format(filename))

    if debug:
        pcap.set_debug()

    start_time = time.time()

    for packet in pcap:
        try:
            _process_packet(packet, must_inspect_strings)

        except MalformedPacketException as e:
            logger.error(str(e) + ", extractor will keep going")

        except Exception:
            traceback.print_exc()
            logger.error(
                "An exception occurred but extractor will keep going.")

    _sessions.process_sessions_remaining_content()

    logger.info("Processed in {0:.3f} seconds.".format(time.time() -
                                                       start_time))
    pcap.close()
    return _sessions
Beispiel #3
0
def active_processing(interface: str,
                      must_inspect_strings=False,
                      tshark_filter=None,
                      debug=False,
                      decode_as=None,
                      pcap_output=None):

    global _sessions

    logger.DEBUG_MODE = debug
    _sessions = SessionList()

    _sessions.manage_outdated_sessions()
    signal.signal(signal.SIGINT, signal_handler)

    live = pyshark.LiveCapture(interface=interface,
                               bpf_filter=tshark_filter,
                               decode_as=decode_as,
                               output_file=pcap_output)
    logger.info("Listening on {}...".format(interface))

    if debug:
        live.set_debug()

    try:
        for packet in live.sniff_continuously():
            try:
                _process_packet(packet, must_inspect_strings)

            except MalformedPacketException as e:
                logger.error(str(e) + ", extractor will keep going")

            except Exception:
                traceback.print_exc()
                logger.error(
                    "An exception occurred but extractor will keep going.")

    except TSharkCrashException:
        logger.error("tshark crashed :( Please report the following error :")
        traceback.print_exc()
        signal_handler(None, None)
Beispiel #4
0
def analyse(session: Session, layer: Layer) -> bool:

    current_creds = session.credentials_being_built

    if hasattr(layer, "request_uri"):

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

        if extension in HTTP_IGNORED_EXTENSIONS:
            return False

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

        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)

                    # We return false to prevent the manager from validating the credentials being built
                    return False

        # 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)

                # We return false to prevent the manager from validating the credentials being built
                return False

    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))
                return True

    return False
Beispiel #5
0
        manager.active_processing(args.listen,
                                  must_inspect_strings=string_inspection,
                                  tshark_filter=ip_filter,
                                  debug=args.debug,
                                  decode_as=decode_map,
                                  pcap_output=args.listen_output)
        exit(0)

    for pcap in args.pcapfiles:

        try:
            manager.process_pcap(pcap,
                                 must_inspect_strings=string_inspection,
                                 tshark_filter=ip_filter,
                                 debug=args.debug,
                                 decode_as=decode_map)

        except Exception as e:
            error_str = str(e)

            if error_str.startswith("[Errno"):  # Clean error message
                errno_end_index = error_str.find("]") + 2
                error_str = error_str[errno_end_index:]
                logger.error(error_str)

            else:
                traceback.print_exc()

    if logger.OUTPUT_FILE:
        logger.OUTPUT_FILE.close()