Skip to content

Commit

Permalink
Merge pull request #49 from fkie-cad/http-proxy-fix
Browse files Browse the repository at this point in the history
http proxy server: don't work as an actual proxy
  • Loading branch information
giga-a authored Jan 19, 2024
2 parents 9293cbe + a0fb6a9 commit 45b1f6b
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 26 deletions.
2 changes: 1 addition & 1 deletion clean-up.logs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Empty file added honeypots/data/__init__.py
Empty file.
15 changes: 15 additions & 0 deletions honeypots/data/dummy_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<title>Example Website</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div>
<h1>Example Website</h1>
<p>This website is for use in dummy HTML responses. You may use this
document without prior coordination or asking for permission.</p>
</div>
</body>
</html>
49 changes: 26 additions & 23 deletions honeypots/http_proxy_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion tests/test_http_proxy_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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"
2 changes: 2 additions & 0 deletions tests/test_telnet_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit 45b1f6b

Please sign in to comment.