From c124db7880ff645ff24b3b238fbebce9c1bb3985 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 5 Oct 2021 13:51:03 -0400 Subject: [PATCH 1/7] Agent: Use different proxy scheme on Windows --- monkey/infection_monkey/control.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 7b8f46f81..62bd5872a 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -115,7 +115,20 @@ class ControlClient(object): if proxy_find: proxy_address, proxy_port = proxy_find logger.info("Found tunnel at %s:%s" % (proxy_address, proxy_port)) - ControlClient.proxies["https"] = PROXY_SCHEMA % (proxy_address, proxy_port) + from infection_monkey.utils.environment import is_windows_os + + logger.info(f"requests version: {requests.__version__}") + import urllib3 + + logger.info(f"urllib3 version: {urllib3.__version__}") + if is_windows_os(): + ControlClient.proxies["https"] = "https://%s:%s" % ( + proxy_address, + proxy_port, + ) + else: + ControlClient.proxies["https"] = PROXY_SCHEMA % (proxy_address, proxy_port) + logger.info(ControlClient.proxies) return ControlClient.find_server() else: logger.info("No tunnel found") From cafd983622952c63cc7112a207bb5f969ec21c41 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 6 Oct 2021 10:24:41 +0200 Subject: [PATCH 2/7] Agent: Change proxy scheme format to http --- monkey/infection_monkey/control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 62bd5872a..6e956f20b 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -122,7 +122,7 @@ class ControlClient(object): logger.info(f"urllib3 version: {urllib3.__version__}") if is_windows_os(): - ControlClient.proxies["https"] = "https://%s:%s" % ( + ControlClient.proxies["https"] = "http://%s:%s" % ( proxy_address, proxy_port, ) From 87b882cb4537c8fa24b729c416292412adb15231 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 6 Oct 2021 15:13:09 +0200 Subject: [PATCH 3/7] Agent: Set proxy schema for different OS --- monkey/infection_monkey/control.py | 38 +++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 6e956f20b..4252b53c0 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -22,6 +22,7 @@ from infection_monkey.config import GUID, WormConfiguration from infection_monkey.network.info import local_ips from infection_monkey.transport.http import HTTPConnectProxy from infection_monkey.transport.tcp import TcpProxy +from infection_monkey.utils.environment import is_windows_os requests.packages.urllib3.disable_warnings() @@ -113,27 +114,32 @@ class ControlClient(object): logger.info("Starting tunnel lookup...") proxy_find = tunnel.find_tunnel(default=default_tunnel) if proxy_find: - proxy_address, proxy_port = proxy_find - logger.info("Found tunnel at %s:%s" % (proxy_address, proxy_port)) - from infection_monkey.utils.environment import is_windows_os - - logger.info(f"requests version: {requests.__version__}") - import urllib3 - - logger.info(f"urllib3 version: {urllib3.__version__}") - if is_windows_os(): - ControlClient.proxies["https"] = "http://%s:%s" % ( - proxy_address, - proxy_port, - ) - else: - ControlClient.proxies["https"] = PROXY_SCHEMA % (proxy_address, proxy_port) - logger.info(ControlClient.proxies) + ControlClient.set_proxies(proxy_find) return ControlClient.find_server() else: logger.info("No tunnel found") return False + @staticmethod + def set_proxies(proxy_find): + """ + Note: Proxy schema changes! When upgrading to newer python version or + when urllib3 and requests are updated there is possibility that the proxy + schema is changed. + https://github.com/psf/requests/issues/5297 + https://github.com/psf/requests/issues/5855 + """ + proxy_address, proxy_port = proxy_find + logger.info("Found tunnel at %s:%s" % (proxy_address, proxy_port)) + if is_windows_os(): + ControlClient.proxies["https"] = "http://%s:%s" % ( + proxy_address, + proxy_port, + ) + else: + ControlClient.proxies["https"] = PROXY_SCHEMA % (proxy_address, proxy_port) + logger.info(ControlClient.proxies) + @staticmethod def keepalive(): if not WormConfiguration.current_server: From 3f33bc4a414130c3a8fc71f76f372ccc53993ebc Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 6 Oct 2021 18:05:30 +0200 Subject: [PATCH 4/7] Agent: Consistent format string for set proxy --- monkey/infection_monkey/control.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 4252b53c0..ec153f418 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -36,8 +36,6 @@ PBA_FILE_DOWNLOAD = "https://%s/api/pba/download/%s" # elsewhere. TIMEOUT_IN_SECONDS = 15 -PROXY_SCHEMA = "%s:%s" - class ControlClient(object): proxies = {} @@ -132,13 +130,9 @@ class ControlClient(object): proxy_address, proxy_port = proxy_find logger.info("Found tunnel at %s:%s" % (proxy_address, proxy_port)) if is_windows_os(): - ControlClient.proxies["https"] = "http://%s:%s" % ( - proxy_address, - proxy_port, - ) + ControlClient.proxies["https"] = f"http://{proxy_address}:{proxy_port}" else: - ControlClient.proxies["https"] = PROXY_SCHEMA % (proxy_address, proxy_port) - logger.info(ControlClient.proxies) + ControlClient.proxies["https"] = f"{proxy_address}:{proxy_port}" @staticmethod def keepalive(): From a11d1d5f1e424586c944ed85f9ab5a830eaf013a Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 6 Oct 2021 18:10:46 +0200 Subject: [PATCH 5/7] Agent: Changed note message for proxy schema --- monkey/infection_monkey/control.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index ec153f418..f026584ca 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -121,9 +121,12 @@ class ControlClient(object): @staticmethod def set_proxies(proxy_find): """ - Note: Proxy schema changes! When upgrading to newer python version or - when urllib3 and requests are updated there is possibility that the proxy - schema is changed. + Note: Proxy schema changes which causes the machine to not open a tunnel back. + If we get "ValueError: check_hostname requires server_hostname" or + "Proxy URL had not schema, should start with http:// or https://" errors, + the proxy schema needs to be changed. + Keep this in mind when upgrading to newer python version or when urllib3 and + requests are updated there is possibility that the proxy schema is changed. https://github.com/psf/requests/issues/5297 https://github.com/psf/requests/issues/5855 """ From a8182cbb3dc4f3441196d7239b62c11e9e845464 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 7 Oct 2021 10:50:41 +0200 Subject: [PATCH 6/7] UT: Add test for settting agent proxy --- .../infection_monkey/test_control.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 monkey/tests/unit_tests/infection_monkey/test_control.py diff --git a/monkey/tests/unit_tests/infection_monkey/test_control.py b/monkey/tests/unit_tests/infection_monkey/test_control.py new file mode 100644 index 000000000..81cfc93fe --- /dev/null +++ b/monkey/tests/unit_tests/infection_monkey/test_control.py @@ -0,0 +1,18 @@ +import pytest + +from monkey.infection_monkey.control import ControlClient + +PROXY_FOUND = ("8.8.8.8", "45455") + + +@pytest.mark.parametrize("is_windows_os", [True, False]) +def test_control_set_proxies(monkeypatch, is_windows_os): + monkeypatch.setattr("monkey.infection_monkey.control.is_windows_os", lambda: is_windows_os) + control_client = ControlClient() + + control_client.set_proxies(PROXY_FOUND) + + if is_windows_os: + assert control_client.proxies["https"].startswith("http://") + else: + assert control_client.proxies["https"].startswith(PROXY_FOUND[0]) From cd23eb2909eeef5dcb7498089ca938366e8782d8 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 7 Oct 2021 16:18:17 +0200 Subject: [PATCH 7/7] Agent: Reword note in control Rewrite control set proxy UT, fix typo in httpfinger --- monkey/infection_monkey/control.py | 3 ++- monkey/infection_monkey/network/httpfinger.py | 2 +- .../unit_tests/infection_monkey/test_control.py | 16 +++++++--------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index f026584ca..367433cb6 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -121,7 +121,8 @@ class ControlClient(object): @staticmethod def set_proxies(proxy_find): """ - Note: Proxy schema changes which causes the machine to not open a tunnel back. + Note: The proxy schema changes between different versions of requests and urllib3, + which causes the machine to not open a tunnel back. If we get "ValueError: check_hostname requires server_hostname" or "Proxy URL had not schema, should start with http:// or https://" errors, the proxy schema needs to be changed. diff --git a/monkey/infection_monkey/network/httpfinger.py b/monkey/infection_monkey/network/httpfinger.py index f7ffc54e5..3939fc7c6 100644 --- a/monkey/infection_monkey/network/httpfinger.py +++ b/monkey/infection_monkey/network/httpfinger.py @@ -44,7 +44,7 @@ class HTTPFinger(HostFinger): logger.info("Port %d is open on host %s " % (port[0], host)) break # https will be the same on the same port except Timeout: - logger.debug(f"Timout while requesting headers from {url}") + logger.debug(f"Timeout while requesting headers from {url}") except ConnectionError: # Someone doesn't like us logger.debug(f"Connection error while requesting headers from {url}") diff --git a/monkey/tests/unit_tests/infection_monkey/test_control.py b/monkey/tests/unit_tests/infection_monkey/test_control.py index 81cfc93fe..7c2f42d19 100644 --- a/monkey/tests/unit_tests/infection_monkey/test_control.py +++ b/monkey/tests/unit_tests/infection_monkey/test_control.py @@ -2,17 +2,15 @@ import pytest from monkey.infection_monkey.control import ControlClient -PROXY_FOUND = ("8.8.8.8", "45455") - -@pytest.mark.parametrize("is_windows_os", [True, False]) -def test_control_set_proxies(monkeypatch, is_windows_os): +@pytest.mark.parametrize( + "is_windows_os,expected_proxy_string", + [(True, "http://8.8.8.8:45455"), (False, "8.8.8.8:45455")], +) +def test_control_set_proxies(monkeypatch, is_windows_os, expected_proxy_string): monkeypatch.setattr("monkey.infection_monkey.control.is_windows_os", lambda: is_windows_os) control_client = ControlClient() - control_client.set_proxies(PROXY_FOUND) + control_client.set_proxies(("8.8.8.8", "45455")) - if is_windows_os: - assert control_client.proxies["https"].startswith("http://") - else: - assert control_client.proxies["https"].startswith(PROXY_FOUND[0]) + assert control_client.proxies["https"] == expected_proxy_string