From 274caabe4be323148316f290137d6af305c93283 Mon Sep 17 00:00:00 2001 From: gdesmar <75089569+gdesmar@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:11:57 +0000 Subject: [PATCH] Handle low-digit username as FP url masquerading --- tests/test_url_analysis.py | 26 ++++++++++++++++---------- urlcreator/network.py | 7 ++++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/tests/test_url_analysis.py b/tests/test_url_analysis.py index ae5ab86..57469df 100644 --- a/tests/test_url_analysis.py +++ b/tests/test_url_analysis.py @@ -10,7 +10,7 @@ def test_unicode_characters(): url = "https://hello:world@écoute.com/" res_section, network_iocs = url_analysis(url) assert network_iocs == {"uri": ["https://écoute.com/"], "domain": ["écoute.com"], "ip": []} - assert '"OBFUSCATION": "Embedded credentials"' in res_section.body + assert "embedded_credentials" in res_section.heuristic.signatures def test_embedded_base64(): @@ -67,40 +67,46 @@ def test_phishing(): # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://bad.com/malicious.zip?evil=true"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "URL masquerade"' in res_section.body + assert "url_masquerade" in res_section.heuristic.signatures url = "https://username@adobe.com@bad.com/malicious.zip" res_section, network_iocs = url_analysis(url) # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://bad.com/malicious.zip"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "URL masquerade"' in res_section.body + assert "url_masquerade" in res_section.heuristic.signatures url = "https://adobe.com@bad.com/malicious.zip" res_section, network_iocs = url_analysis(url) # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://bad.com/malicious.zip"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "URL masquerade"' in res_section.body + assert "url_masquerade" in res_section.heuristic.signatures url = "https://something@not-a-url-with-tld@bad.com/malicious.zip" res_section, network_iocs = url_analysis(url) # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://bad.com/malicious.zip"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "URL masquerade"' not in res_section.body + assert "url_masquerade" not in res_section.heuristic.signatures url = "https://username@bad.com/" res_section, network_iocs = url_analysis(url) assert network_iocs["uri"] == ["https://bad.com/"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "Embedded username"' in res_section.body + assert "embedded_username" in res_section.heuristic.signatures url = "https://username:password@bad.com/" res_section, network_iocs = url_analysis(url) assert network_iocs["uri"] == ["https://bad.com/"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "Embedded credentials"' in res_section.body + assert "embedded_credentials" in res_section.heuristic.signatures + + url = "https://123:xyz@example.com/" + res_section, network_iocs = url_analysis(url) + assert network_iocs["uri"] == ["https://example.com/"] + assert network_iocs["domain"] == ["example.com"] + assert "url_masquerade" not in res_section.heuristic.signatures def test_ascii_decode_handling(): @@ -126,7 +132,7 @@ def lookup_safelist(qhash): # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://bad.com/malicious.zip"] assert network_iocs["domain"] == ["bad.com"] - assert '"OBFUSCATION": "URL masquerade"' in res_section.body + assert "url_masquerade" in res_section.heuristic.signatures assert res_section.heuristic.score == 500 url = "https://adobe.com@safelistedenabled.com/malicious.zip" @@ -134,7 +140,7 @@ def lookup_safelist(qhash): # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://safelistedenabled.com/malicious.zip"] assert network_iocs["domain"] == ["safelistedenabled.com"] - assert '"OBFUSCATION": "URL masquerade"' in res_section.body + assert "url_masquerade" in res_section.heuristic.signatures assert res_section.heuristic.score == 0 url = "https://adobe.com@safelisteddisabled.com/malicious.zip" @@ -142,5 +148,5 @@ def lookup_safelist(qhash): # Should reveal the true target URL for reputation checking assert network_iocs["uri"] == ["https://safelisteddisabled.com/malicious.zip"] assert network_iocs["domain"] == ["safelisteddisabled.com"] - assert '"OBFUSCATION": "URL masquerade"' in res_section.body + assert "url_masquerade" in res_section.heuristic.signatures assert res_section.heuristic.score == 500 diff --git a/urlcreator/network.py b/urlcreator/network.py index 6536041..ac82fba 100644 --- a/urlcreator/network.py +++ b/urlcreator/network.py @@ -139,9 +139,10 @@ def add_MD_results_to_table(result: Node): try: username_url = make_bytes(scheme) + b"://" + username.value username_as_url = parse_url(username_url) - username_host = ( - [node for node in username_as_url if node.type in ["network.ip", "network.domain"]] + [None] - )[0] + # We usually look for 'network.ip' or 'network.domain' but we can assume that + # any URL masquerading would be done using a domain only. + # This also reduce false positives of having a number-only username being treated like an IP. + username_host = ([node for node in username_as_url if node.type == "network.domain"] + [None])[0] except Exception: username_host = None