def test_pgsql(self): credentials_list = process_pcap( "samples/pgsql.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials("oryx", hash="ceffc01dcde7541829deef6b5e9c9142", context={ "salt": "ad44ff54", "auth_type": "md5", "database": "mailstore" }) in credentials_list) self.assertTrue( Credentials("oryx", hash="f8f8b884b4ef7cc9ee95e69868cdfa5e", context={ "salt": "f211a3ed", "auth_type": "md5", "database": "mailstore" }) in credentials_list) self.assertTrue(len(credentials_list) == 2) credentials_list = process_pcap( "samples/pgsql-nopassword.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials("user", context={"database": "dbdb"}) in credentials_list) self.assertTrue(len(credentials_list) == 1)
def test_telnet(self): credentials_list = process_pcap( "samples/telnet-cooked.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(Credentials('fake', 'user') in credentials_list) self.assertTrue(len(credentials_list) == 1) credentials_list = process_pcap( "samples/telnet-raw.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(Credentials('fake', 'user') in credentials_list) self.assertTrue(len(credentials_list) == 1) credentials_list = process_pcap( "samples/telnet-raw2.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('Administrator', 'napier') in credentials_list) self.assertTrue(len(credentials_list) == 1) credentials_list = process_pcap( "samples/telnet.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('shellcode', 'shellcode') in credentials_list) self.assertTrue(len(credentials_list) == 1)
def test_http_basic_auth(self): credentials_list = process_pcap( "samples/http-basic-auth.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(Credentials('test', 'test') in credentials_list) self.assertFalse(Credentials('test', 'fail') in credentials_list) self.assertFalse(Credentials('test', 'fail2') in credentials_list) self.assertFalse(Credentials('test', 'fail3') in credentials_list) self.assertTrue(len(credentials_list) == 6)
def test_ldap(self): credentials_list = process_pcap( "samples/ldap-simpleauth.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials("*****@*****.**", "passwor8d1") in credentials_list) self.assertTrue( Credentials( "CN=xxxxxxxx,OU=Users,OU=Accounts,DC=xx," "DC=xxx,DC=xxxxx,DC=net", "/dev/rdsk/c0t0d0s0") in credentials_list) self.assertTrue(len(credentials_list) == 2)
def test_snmp(self): credentials_list = process_pcap( "samples/snmp-v1.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(Credentials(password="******") in credentials_list) self.assertTrue(len(credentials_list) == 1) credentials_list = process_pcap( "samples/snmp-v3.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(Credentials(username="******") in credentials_list) self.assertTrue(Credentials(username="******") in credentials_list) self.assertTrue(Credentials(username="******") in credentials_list) self.assertTrue(Credentials(username="******") in credentials_list) self.assertTrue(len(credentials_list) == 4)
def test_imap(self): credentials_list = process_pcap( "samples/imap.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('neulingern', 'XXXXXX') in credentials_list) self.assertTrue(len(credentials_list) == 1)
def test_ftp(self): credentials_list = process_pcap( "samples/ftp.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('anonymous', '*****@*****.**') in credentials_list) self.assertTrue(len(credentials_list) == 1)
def test_http_post_auth(self): credentials_list = process_pcap( "samples/http-post-auth.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('toto', 'Str0ngP4ssw0rd') in credentials_list) self.assertTrue(len(credentials_list) == 1)
def test_pop(self): credentials_list = process_pcap( "samples/pop3.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('*****@*****.**', 'napier123') in credentials_list) self.assertTrue(len(credentials_list) == 2)
def test_smtp(self): credentials_list = process_pcap( "samples/smtp.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials('*****@*****.**', 'punjab@123') in credentials_list) self.assertTrue(len(credentials_list) == 1)
def invalidate_credentials_and_clear_session(self): """ At some point, a CredSLayer parser should be able to identify that an unsuccessful authentication has been made, to tell CredSLayer the `credentials_being_built` are invalid and what it contains must be discarded, this method must be called. This will create a new instance of `Credentials` in order to build new potential incoming credentials of the same session. """ self.clear() self.credentials_being_built = Credentials()
def test_protocol_decode_as(self): from credslayer.core import manager credentials_list = manager.process_pcap( "samples/telnet-hidden.pcap", decode_as={ "tcp.port==1337": "telnet" }).get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials("shellcode", "shellcode") in credentials_list)
def validate_credentials(self): """ At some point, a CredSLayer parser should be able to identify that a successful authentication has been made, to tell CredSLayer the `credentials_being_built` are valid, this method must be called. This will create a new instance of `Credentials` in order to build new potential incoming credentials of the same session. """ self.credentials_list.append(self.credentials_being_built) if Session.creds_found_callback: Session.creds_found_callback(self.credentials_being_built) self.credentials_being_built = Credentials()
def test_mysql(self): credentials_list = process_pcap( "samples/mysql.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials("tfoerste", hash="eefd6d5562851bc5966a0b41236ae3f2315efcc4", context={ "salt": ">~$4uth,", "salt2": ">612IWZ>fhWX" }) in credentials_list) self.assertTrue(len(credentials_list) == 1) credentials_list = process_pcap( "samples/mysql2.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue( Credentials("user10", hash="55ee72f0c6694cbb3a104eb97f8ee32a6a91f8b1", context={ "salt": "]E!r<uX8", "salt2": "Of2c!tIM)\"n'" }) in credentials_list) self.assertTrue(len(credentials_list) == 1)
def __init__(self, packet: Packet): super().__init__() if "ipv6" in packet: ip_type = "ipv6" proto_id = int(getattr(packet, ip_type).nxt) elif "ip" in packet: ip_type = "ip" proto_id = int(getattr(packet, ip_type).proto) else: raise SessionException("IP layer not found") if proto_id == 6: self.protocol = "tcp" src = "{}:{}".format(packet[ip_type].src, packet.tcp.srcport) dst = "{}:{}".format(packet[ip_type].dst, packet.tcp.dstport) elif proto_id == 17: self.protocol = "udp" # We don't track UDP "sessions" using port because client's port changes every time... src = packet[ip_type].src dst = packet[ip_type].dst else: raise SessionException("Unsupported protocol id: " + str(proto_id)) if packet[self.protocol].srcport == packet[self.protocol].dstport: # Alphabetic ordering on IP addresses if ports are the same if packet[ip_type].src < packet[ip_type].dst: self._session_string_representation = src + " <-> " + dst else: self._session_string_representation = dst + " <-> " + src # Ordering based on port number elif int(packet[self.protocol].srcport) > int(packet[self.protocol].dstport): self._session_string_representation = src + " <-> " + dst else: self._session_string_representation = dst + " <-> " + src self._session_identifier = "{} {}".format(self.protocol.upper(), self._session_string_representation) self._last_seen_time = time.time() self.credentials_being_built = Credentials() self.credentials_list = [] # type: List[Credentials]
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()
def test_http_get_auth(self): credentials_list = process_pcap( "samples/http-get-auth.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(Credentials('admin', 'qwerty1234') in credentials_list) self.assertTrue(len(credentials_list) == 1)
def test_ntlmssp(self): credentials_list = process_pcap( "samples/smb-ntlm.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(credentials_list == [ Credentials( context={'version': 'NETNTLMv2'}, hash="Willi Wireshark::DESKTOP-2AEFM7G:78f8f6206e882559:8149b0" "b2a73a191141bda07d1ed18434:01010000000000000bd7d7878527d" "201146f94347775321c0000000002001e004400450053004b0054004" "f0050002d00560031004600410030005500510001001e00440045005" "3004b0054004f0050002d00560031004600410030005500510004001" "e004400450053004b0054004f0050002d00560031004600410030005" "500510003001e004400450053004b0054004f0050002d00560031004" "6004100300055005100070008000bd7d7878527d2010600040002000" "0000800300030000000000000000100000000200000ad865b6d08a95" "d0e76a94e2ca013ab3f69c4fd945cca01b277700fd2b305ca010a001" "00000000000000000000000000000000000090028006300690066007" "3002f003100390032002e003100360038002e003100390039002e003" "10033003300000000000000000000000000") ]) credentials_list = process_pcap( "samples/smb-ntlm2.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(credentials_list == [ Credentials( context={'version': 'NETNTLMv2'}, hash="administrator:::26de2c0b3abaaa1c:711d6cb05614bc240ca7e2a" "38568ff85:0101000000000000e652e41aa7b4d401dac9a62e4db292" "6b000000000200060046004f004f000100100044004600530052004f" "004f00540031000400100066006f006f002e00740065007300740003" "00220064006600730072006f006f00740031002e0066006f006f002e" "0074006500730074000500100066006f006f002e0074006500730074" "0007000800e652e41aa7b4d40100000000") ]) credentials_list = process_pcap( "samples/smb-ntlm3.pcap").get_list_of_all_credentials() print(credentials_list) self.assertTrue(credentials_list == [ Credentials( context={'version': 'NETNTLMv1'}, hash="administrator::VNET3:42c09b264cbc46690000000000000000000" "0000000000000:9cd7e4af2d7e934adc9b307231a958539b3d2c368b" "964cea:28a3a326a53fa6f5") ]) remaining_credentials = process_pcap( "samples/http-ntlm.pcap").get_remaining_content() remaining_credentials = [c[1] for c in remaining_credentials ] # Only get Credentials from the tuple print(remaining_credentials) self.assertTrue(len(remaining_credentials) == 6) self.assertTrue( Credentials( hash= "administrator::example:ea46e3a07ea448d200000000000000000000000000000000:" "4d626ea83a02eee710571a2b84241788bd21e3a66ddbf4a5" ":CHALLENGE_NOT_FOUND") in remaining_credentials)