Last active
December 29, 2022 19:53
-
-
Save snovvcrash/4e76aaf2a8750922f546eed81aa51438 to your computer and use it in GitHub Desktop.
Send request to the MS Exchange Autodiscover service (MS-OXDSCLI protocol) and parse the response. Hunting for the OABUrl value. Credits to @ptswarm: https://swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/
This file contains 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
#!/usr/bin/env python3 | |
# Usage: python3 oaburl.py MEGACORP/j.doe:'Passw0rd!'@mx.example.com -e [email protected] | |
from xml.dom import minidom | |
from argparse import ArgumentParser | |
from getpass import getpass | |
import requests | |
GN = '\033[0;32m' # GREEN NORMAL | |
GB = '\033[1;32m' # GREEN BOLD | |
NC = '\033[0m' # NO COLOR | |
headers = { | |
'User-Agent': 'Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.10730; Pro)', | |
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', | |
'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3', | |
'Accept-Encoding': 'gzip, deflate', | |
'Content-Type': 'text/xml' | |
} | |
data = """<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>""" | |
def init_args(): | |
parser = ArgumentParser() | |
parser.add_argument('target', help='<<domain/>username[:password]@><targetName_or_address>') | |
parser.add_argument('-e', '--email', required=True, help='any valid email address within the domain') | |
return parser.parse_args() | |
def parse_target(target): | |
creds, hostname = target.rsplit('@', 1) | |
domain, userpass = creds.split('/', 1) | |
try: | |
username, password = userpass.split(':', 1) | |
except ValueError: | |
username = userpass | |
password = getpass() | |
return (domain.upper(), username, password, hostname) | |
def print_node_value(dom, nodename, color=GN): | |
print(f'{color}[+] {nodename}: {dom.getElementsByTagName(nodename)[0].childNodes[0].nodeValue}{NC}') | |
if __name__ == '__main__': | |
args = init_args() | |
domain, username, password, hostname = parse_target(args.target) | |
headers['Host'] = hostname | |
data = data % (args.email,) | |
session = requests.Session() | |
session.auth = (f'{domain}\\{username}', password) | |
resp = session.post(f'https://{hostname}/autodiscover/autodiscover.xml', headers=headers, data=data, verify=False) | |
print(f'[*] Authenticated users\'s SID (X-BackEndCookie): {resp.headers["Set-Cookie"].split("=")[1]}') | |
dom = minidom.parseString(resp.text) | |
dom.normalize() | |
print_node_value(dom, 'DisplayName') | |
#print_node_value(dom, 'LegacyDN') | |
print_node_value(dom, 'Server') | |
#print_node_value(dom, 'ServerDN') | |
print_node_value(dom, 'AD') | |
print_node_value(dom, 'OABUrl', color=GB) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment