diff --git a/clean-up.logs b/clean-up.logs index 78c486c..0c9e99b 100644 --- a/clean-up.logs +++ b/clean-up.logs @@ -1,4 +1,4 @@ -Wed Jan 17 16:42:05 UTC 2024 +Fri Jan 19 13:37:48 UTC 2024 [X] honeypots [X] installing python3, python3-pip, autopep8 & jq [X] installing the pip package diff --git a/honeypots/data/__init__.py b/honeypots/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/honeypots/data/dummy_page.html b/honeypots/data/dummy_page.html new file mode 100644 index 0000000..37ad6c2 --- /dev/null +++ b/honeypots/data/dummy_page.html @@ -0,0 +1,15 @@ + + + + Example Website + + + + +
+

Example Website

+

This website is for use in dummy HTML responses. You may use this + document without prior coordination or asking for permission.

+
+ + diff --git a/honeypots/http_proxy_server.py b/honeypots/http_proxy_server.py index 3edaceb..59cac7d 100644 --- a/honeypots/http_proxy_server.py +++ b/honeypots/http_proxy_server.py @@ -9,13 +9,14 @@ // contributors list qeeqbox/honeypots/graphs/contributors // ------------------------------------------------------------- ''' - +from pathlib import Path from warnings import filterwarnings + filterwarnings(action='ignore', module='.*OpenSSL.*') from dns.resolver import query as dsnquery from twisted.internet import reactor -from twisted.internet.protocol import Protocol, ClientFactory, Factory +from twisted.internet.protocol import Protocol, Factory from twisted.python import log as tlog from subprocess import Popen from email.parser import BytesParser @@ -25,6 +26,9 @@ from contextlib import suppress +DUMMY_TEMPLATE = (Path(__file__).parent / "data" / "dummy_page.html").read_text() + + class QHTTPProxyServer(): def __init__(self, **kwargs): self.auto_disabled = None @@ -62,31 +66,20 @@ def resolve_domain(self, request_string): def dataReceived(self, data): _q_s.logs.info({'server': 'http_proxy_server', 'action': 'connection', 'src_ip': self.transport.getPeer().host, 'src_port': self.transport.getPeer().port, 'dest_ip': _q_s.ip, 'dest_port': _q_s.port}) - with suppress(Exception): - ip = self.resolve_domain(data) - if ip: - factory = ClientFactory() - factory.CustomProtocolParent_ = self - factory.protocol = CustomProtocolChild - reactor.connectTCP(ip, 80, factory) - else: - self.transport.loseConnection() - - if self.client: - self.client.write(data) - else: - self.buffer = data + ip = self.resolve_domain(data) + if ip: + self.write(_create_dummy_response(DUMMY_TEMPLATE)) + else: + self.transport.loseConnection() + + if self.client: + self.client.write(data) + else: + self.buffer = data def write(self, data): self.transport.write(data) - class CustomProtocolChild(Protocol): - def connectionMade(self): - self.write(self.factory.CustomProtocolParent_.buffer) - - def dataReceived(self, data): - self.factory.CustomProtocolParent_.write(data) - def write(self, data): self.transport.write(data) @@ -139,6 +132,16 @@ def test_server(self, ip=None, port=None, domain=None): get(_domain, proxies={'http': 'http://{}:{}'.format(_ip, _port)}).text.encode('ascii', 'ignore') +def _create_dummy_response(content: str) -> bytes: + response = [ + "HTTP/1.1 200 OK", + f"Content-Length: {len(content)}", + "", + f"{content}", + ] + return "\r\n".join(response).encode() + + if __name__ == '__main__': parsed = server_arguments() if parsed.docker or parsed.aws or parsed.custom: diff --git a/setup.py b/setup.py index 4d7afde..da9d446 100644 --- a/setup.py +++ b/setup.py @@ -13,9 +13,10 @@ license="AGPL-3.0", license_files=("LICENSE"), url="https://github.com/qeeqbox/honeypots", - packages=["honeypots"], + packages=["honeypots", "honeypots.data"], entry_points={"console_scripts": ["honeypots=honeypots.__main__:main_logic"]}, include_package_data=True, + package_data={"honeypots.data": ["*.html"]}, install_requires=[ "twisted==21.7.0", "psutil==5.9.0", diff --git a/tests/test_http_proxy_server.py b/tests/test_http_proxy_server.py index f22d9c4..f968134 100644 --- a/tests/test_http_proxy_server.py +++ b/tests/test_http_proxy_server.py @@ -30,7 +30,7 @@ def test_http_proxy_server(server_logs): sleep(1) # give the server some time to start - response = requests.get("http://example.com/", proxies={"http": f"http://{IP}:{PORT}"}) + response = requests.get("http://example.com/", proxies={"http": f"http://{IP}:{PORT}"}, timeout=2) sleep(1) # give the server process some time to write logs @@ -42,3 +42,6 @@ def test_http_proxy_server(server_logs): assert query["data"] == "example.com" assert query["action"] == "query" + + assert response.ok + assert "Example Website" in response.text, "dummy response is missing" diff --git a/tests/test_telnet_server.py b/tests/test_telnet_server.py index a21d339..98073b6 100644 --- a/tests/test_telnet_server.py +++ b/tests/test_telnet_server.py @@ -24,6 +24,8 @@ indirect=True, ) def test_telnet_server(server_logs): + sleep(1) # give the server some time to start + telnet_client = Telnet(IP, int(PORT)) telnet_client.read_until(b"login: ") telnet_client.write(USERNAME.encode() + b"\n")