From f6c566510af1dbe0316546953c8967defc801a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Glauber=20Magalh=C3=A3es?= Date: Sat, 13 Jan 2024 18:32:50 -0300 Subject: [PATCH] add tests --- .gitignore | 7 ++++- setup.py | 2 +- src/evilurl.py | 12 +++++---- tests/__init__.py | 0 tests/tests.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/tests.py diff --git a/.gitignore b/.gitignore index 531e76b..5937978 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ venv/ evilurl.egg-info/ dist/ -.eggs/ \ No newline at end of file +.eggs/ +__pycache__/ +*.pyc +*.pyo +*.pyd +*.so \ No newline at end of file diff --git a/setup.py b/setup.py index ae00d01..03e07d8 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name='evilurl', - version='0.0.11', + version='0.0.12', packages=['src'], package_data={'src': ['unicode_combinations.json']}, setup_requires=['wheel'], diff --git a/src/evilurl.py b/src/evilurl.py index 0e1bda8..8649430 100644 --- a/src/evilurl.py +++ b/src/evilurl.py @@ -66,11 +66,11 @@ def analyze_domain(self, domain): domains = [] for combination in product(*combinations): - new_domain = ''.join(combination) + '.' + domain_parts[1] + new_domain = ''.join(combination) + '.' + '.'.join(domain_parts[1:]) domains.append(new_domain) if len(domains) <= 1: - print(f"IDN homograph attack is not possible for this domain") + return print(f"IDN homograph attack is not possible for this domain with the current character set") if not self.show_domains_only: print(header) @@ -82,11 +82,13 @@ def analyze_domain(self, domain): print(new_domain) else: for index, new_domain in enumerate(domains[1:]): - print(f"\n{index + 1} -------------------------------") - dns = self.check_domain_registration(new_domain) punycode_encoded_domain = self.convert_to_punycode(new_domain) - + + if new_domain == punycode_encoded_domain: + continue + + print(f"\n{index + 1} -------------------------------") print(f"homograph domain: {new_domain}") print(f"punycode: {punycode_encoded_domain}") if dns: diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/tests.py b/tests/tests.py new file mode 100644 index 0000000..804c3d3 --- /dev/null +++ b/tests/tests.py @@ -0,0 +1,68 @@ +import unittest +from unittest.mock import patch + +from src.evilurl import (HomographAnalyzer, load_unicode_combinations_from_file, main) + + +class TestHomographAnalyzer(unittest.TestCase): + + def setUp(self): + unicode_combinations = [ + {"latin": "a", "similar": ["а", "ɑ"]}, + {"latin": "c", "similar": ["ϲ", "с", "ƈ"]}, + {"latin": "e", "similar": ["е"]}, + {"latin": "o", "similar": ["о", "ο", "o", "օ"]}, + {"latin": "p", "similar": ["р"]}, + {"latin": "s", "similar": ["ѕ"]}, + {"latin": "i", "similar": ["і"]}, + {"latin": "d", "similar": ["ԁ"]}, + {"latin": "l", "similar": ["ɩ"]}, + {"latin": "g", "similar": ["ɡ"]}, + {"latin": "n", "similar": ["ո"]}, + {"latin": "u", "similar": ["ս"]}, + {"latin": "k", "similar": ["κ"]}, + {"latin": "h", "similar": ["һ"]}, + {"latin": "x", "similar": ["х"]}, + {"latin": "y", "similar": ["у"]} + ] + self.analyzer = HomographAnalyzer(unicode_combinations, show_domains_only=False) + + def test_convert_to_punycode(self): + punycode = self.analyzer.convert_to_punycode("gіtһսb.com") + self.assertEqual(punycode, "xn--gtb-jhd02cr1b.com") + + @patch('socket.gethostbyname') + def test_check_domain_registration(self, mock_gethostbyname): + mock_gethostbyname.return_value = "127.0.0.1" + result = self.analyzer.check_domain_registration("example.com") + self.assertEqual(result, "127.0.0.1") + + def test_extract_domain_parts(self): + url = "example.com" + result = self.analyzer.extract_domain_parts(url) + self.assertEqual(result, ['example', 'com']) + + def test_generate_combinations(self): + result = self.analyzer.generate_combinations('x') + self.assertEqual(result, ([['x', 'х']], ['х'])) + + @patch('builtins.print') + def test_analyze_domain(self, mock_print): + domain = "r.com" + self.analyzer.analyze_domain(domain) + mock_print.assert_called_with("IDN homograph attack is not possible for this domain with the current character set") + + def test_load_unicode_combinations_from_file(self): + with patch('builtins.open', create=True) as mock_open: + mock_open.return_value.__enter__.return_value.read.return_value = '[{"latin": "a", "similar": ["а", "ɑ"]}]' + result = load_unicode_combinations_from_file("fake_file.json") + self.assertEqual(result, [{"latin": "a", "similar": ["а", "ɑ"]}]) + + def test_main(self): + with patch('sys.argv', ['src.evilurl.py', 'example.com']): + with patch('src.evilurl.HomographAnalyzer.analyze_domain') as mock_analyze_domain: + main() + mock_analyze_domain.assert_called_with('example.com') + +if __name__ == '__main__': + unittest.main()