summaryrefslogtreecommitdiffstats
path: root/iv/orodja/waf/waf.py
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2024-09-01 00:15:18 +0200
committerAnton Luka Šijanec <anton@sijanec.eu>2024-09-01 00:15:18 +0200
commitb94bef6e820fec0ffde7971d3134d5738c1521d1 (patch)
tree2ae275e51629ae9979a7303f5605bb4988b30234 /iv/orodja/waf/waf.py
parenthacker gets hacked, double fdput vuln (diff)
downloadr-b94bef6e820fec0ffde7971d3134d5738c1521d1.tar
r-b94bef6e820fec0ffde7971d3134d5738c1521d1.tar.gz
r-b94bef6e820fec0ffde7971d3134d5738c1521d1.tar.bz2
r-b94bef6e820fec0ffde7971d3134d5738c1521d1.tar.lz
r-b94bef6e820fec0ffde7971d3134d5738c1521d1.tar.xz
r-b94bef6e820fec0ffde7971d3134d5738c1521d1.tar.zst
r-b94bef6e820fec0ffde7971d3134d5738c1521d1.zip
Diffstat (limited to '')
-rw-r--r--iv/orodja/waf/waf.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/iv/orodja/waf/waf.py b/iv/orodja/waf/waf.py
new file mode 100644
index 0000000..701b4dd
--- /dev/null
+++ b/iv/orodja/waf/waf.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python3
+import asyncio
+import os
+import ssl
+import re
+
+def manyregex (string, patterns):
+ for pattern in patterns:
+ if re.search(pattern, string) != None:
+ return True
+ return False
+
+async def cevovod (reader, writer, writer2, compiled):
+ buffer = b''
+ while True:
+ prebral = await reader.read(65536)
+ buffer += prebral
+ if manyregex(buffer, compiled):
+ break ## hacker detected
+ if len(buffer) > 65536:
+ buffer = buffer[-32768:]
+ if len(prebral) == 0:
+ break
+ writer.write(prebral)
+ writer.close()
+ writer2.close()
+
+async def handle_client (reader, writer):
+ try:
+ compiled = []
+ reflags = re.ASCII | re.MULTILINE | re.DOTALL | re.VERBOSE
+ with open(os.getenv("WAF_REGEXES"), "rb") as rulesfile:
+ regexes = rulesfile.read().split(b"\n")
+ for regex in regexes:
+ if len(regex) == 0:
+ continue
+ compiled.append(re.compile(regex, reflags))
+ write_to_backend = b''
+ if os.getenv("WAF_HTTP"):
+ headers = []
+ while True:
+ line = (await reader.readuntil(b'\n')).replace(b'\r', b'').replace(b'\n', b'')
+ if not line.lower().startswith(b"accept-encoding:"):
+ write_to_backend += line + b"\r\n"
+ if len(line) == 0:
+ break
+ headers.append(line)
+ if headers[0].startswith(b"GET /waf HTTP/"):
+ writer.write(b"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nwaf works (: PID " + str(os.getpid()).encode() + b"\r\n")
+ writer.close()
+ return
+ context = None
+ if os.getenv("WAF_TLS"):
+ context = ssl.create_default_context()
+ context.check_hostname = False
+ context.verify_mode = ssl.CERT_NONE
+ backendr, backendw = await asyncio.open_connection(os.getenv("WAF_BACKEND_HOST"), os.getenv("WAF_BACKEND_PORT"), ssl=context)
+ if manyregex(write_to_backend, compiled):
+ writer.write(b'HTTP/1.0 469 Hacking\r\nContent-Type: text/plain\r\n\r\nHacking is illegal according to ZEKom-2.\r\n')
+ backendw.close() ## hacker
+ writer.close()
+ return
+ backendw.write(write_to_backend)
+ except Exception as e:
+ writer.write(b"HTTP/1.0 569 Exception\r\nContent-Type: text/plain\r\n\r\n")
+ writer.write(str(e).encode())
+ writer.write(b"\r\n")
+ backendw.close()
+ writer.close()
+ raise e
+ else:
+ event_loop = asyncio.get_event_loop()
+ event_loop.create_task(cevovod(reader, backendw, writer, compiled))
+ event_loop.create_task(cevovod(backendr, writer, backendw, compiled))
+
+async def run_server ():
+ context = None
+ if os.getenv("WAF_TLS"):
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ context.load_cert_chain(certfile=os.getenv("WAF_TLS"), keyfile=os.getenv("WAF_TLS_KEY"))
+ server = await asyncio.start_server(handle_client, os.getenv("WAF_LISTEN_ADDR"), os.getenv("WAF_LISTEN_PORT"), ssl=context)
+ async with server:
+ await server.serve_forever()
+
+asyncio.run(run_server())