Skip to content

Instantly share code, notes, and snippets.

@kmsec-uk
Created May 22, 2025 15:35
Show Gist options
  • Save kmsec-uk/6aca36813fefec9754616fb27b771c68 to your computer and use it in GitHub Desktop.
Save kmsec-uk/6aca36813fefec9754616fb27b771c68 to your computer and use it in GitHub Desktop.
Get azure info for a given domain (python implementation of azure-osint.kmsec.uk)
class AADInfo:
def __init__(self, domain: str) ->None:
self.domain = domain
self.brand = ""
self.tenant_id = ""
self.region = ""
self.domains = []
self.soap_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:Action soap:mustUnderstand="1">http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation</a:Action>
<a:To soap:mustUnderstand="1">https://autodiscover-s.outlook.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>"""
def to_dict(self):
return {
'brand' : self.brand,
'tenant_id' : self.tenant_id,
'region' : self.region,
'domains' : self.domains
}
async def aad_tenant_info(self) -> dict:
"""
Enriches a domain against AAD. This is used to enrich information for *.onmicrosoft.com domains.
This functionality is drawn from `AccessToken_utils.ps1` in AADInternals.
"""
print(f"enriching {self.domain}")
soap_headers = {
'Content-Type' : 'text/xml; charset=utf-8',
'User-Agent' : 'AutodiscoverClient',
"SOAPAction" : '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"'
}
try:
async with aiohttp.ClientSession(trust_env=True) as session:
async with session.get(f'https://login.microsoftonline.com/{self.domain}/.well-known/openid-configuration') as response:
print(self.domain, "OID enrichment:", response.status)
if response.ok:
j_resp = await response.json()
self.region = j_resp['tenant_region_scope']
self.tenant_id = re.search(tenant_id, j_resp['token_endpoint']).group('tenant_id')
async with session.post('https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc', data=self.soap_body, headers=soap_headers) as response:
print(self.domain, "Autodiscover enrichment:", response.status)
if response.ok:
self.domains = re.findall(domains, await response.text())
async with session.get(f'https://login.microsoftonline.com/GetUserRealm.srf?login=nn@{self.domain}') as response:
print(self.domain, "Brand enrichment:", response.status)
if response.ok:
j_resp = await response.json()
self.brand = j_resp['FederationBrandName']
except Exception as e:
# We don't want exceptions to block execution
print(e)
self.tenant_id = "error_enriching"
pass
return self.to_dict()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment