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")