Skip to content

Instantly share code, notes, and snippets.

@nullenc0de
Created February 23, 2023 01:37
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save nullenc0de/2981930386c439af08c031622440bc2e to your computer and use it in GitHub Desktop.
Save nullenc0de/2981930386c439af08c031622440bc2e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""
Python script to enumerate valid Microsoft 365 domains, retrieve tenant name, and check for an MDI instance.
Based on: https://github.com/thalpius/Microsoft-Defender-for-Identity-Check-Instance.
Usage: ./check_mdi.py -d <domain>
"""
import argparse
import dns.resolver
import xml.etree.ElementTree as ET
from urllib.request import urlopen, Request
# Get domains
def get_domains(args):
domain = args.domain
# Create a valid HTTP request
# Example from: https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxwsadisc/18fe58cd-3761-49da-9e47-84e7b4db36c2
body = f"""<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:exm="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:ext="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<a:RequestedServerVersion>Exchange2010</a:RequestedServerVersion>
<a:MessageID>urn:uuid:6389558d-9e05-465e-ade9-aae14c4bcd10</a:MessageID>
<a:Action soap:mustUnderstand="1">http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation</a:Action>
<a:To soap:mustUnderstand="1">https://autodiscover.byfcxu-dom.extest.microsoft.com/autodiscover/autodiscover.svc</a:To>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</soap:Header>
<soap:Body>
<GetFederationInformationRequestMessage xmlns="http://schemas.microsoft.com/exchange/2010/Autodiscover">
<Request>
<Domain>{domain}</Domain>
</Request>
</GetFederationInformationRequestMessage>
</soap:Body>
</soap:Envelope>"""
# Including HTTP headers
headers = {
"Content-type": "text/xml; charset=utf-8",
"User-agent": "AutodiscoverClient"
}
# Perform HTTP request
try:
httprequest = Request(
"https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc", headers=headers, data=body.encode())
with urlopen(httprequest) as response:
response = response.read().decode()
except Exception:
print("[-] Unable to execute request. Wrong domain?")
exit()
# Parse XML response
domains = []
tree = ET.fromstring(response)
for elem in tree.iter():
if elem.tag == "{http://schemas.microsoft.com/exchange/2010/Autodiscover}Domain":
domains.append(elem.text)
print(*domains, sep="\n")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Enumerates valid Microsoft 365 domains, retrieves tenant name, and checks for MDI instance")
parser.add_argument(
"-d", "--domain", help="input domain name, example format: example.com", required=True)
args = parser.parse_args()
get_domains(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment