TL;DR
- Cosa imparerai: Come funziona il device code phishing combinato con vishing, come rilevarlo nei log di Entra ID, e i 3 controlli da abilitare subito nel tuo tenant.
- Tempo richiesto: 30-45 minuti per la configurazione, 15 per la verifica.
- Difficoltà: Media — serve ruolo Global Admin o Conditional Access Admin sul tenant Azure/Entra.
Il Problema
Nei sign-in logs del tuo tenant Entra ID hai visto autenticazioni via "Device Code Flow" che non corrispondono a nessun dispositivo che conosci? Oppure, scenario peggiore: un utente ti ha appena chiamato dicendo che "un tecnico Microsoft" lo ha contattato e gli ha chiesto di andare su microsoft.com/devicelogin per inserire un codice.
Congratulazioni: stai incontrando una delle campagne più attive del momento. I threat actor stanno prendendo di mira organizzazioni tech, manifatturiere e finanziarie con attacchi ibridi che combinano device code phishing e vishing (voice phishing, telefonate di ingegneria sociale) per abusare dell'OAuth 2.0 Device Authorization Flow di Microsoft.
Ecco il flusso dell'attacco passo per passo:
- L'attaccante chiama l'utente fingendosi supporto IT interno o assistenza Microsoft
- Genera una richiesta OAuth Device Authorization Flow verso Microsoft — ottiene un
device_code e un user_code
- Passa il
user_code (tipo ABCD-1234) all'utente telefonicamente, dicendo di andare su microsoft.com/devicelogin e inserire il codice per "completare la verifica"
- L'utente, convinto di fare una cosa legittima, inserisce il codice sul sito reale di Microsoft
- L'attaccante riceve un access token + refresh token persistente — senza conoscere la password, senza toccare MFA
Perché MFA non aiuta? Perché nel Device Authorization Flow è l'utente che si autentica (con le proprie credenziali e MFA), ma l'applicazione che riceve il token è quella dell'attaccante. Il token rimane valido per settimane o mesi, dando accesso persistente a Microsoft 365, Teams, SharePoint e alla posta elettronica.
Il Device Authorization Flow esiste per buone ragioni — smart TV, dispositivi IoT, Azure CLI, VS Code. Il problema è che Microsoft lo espone per qualsiasi applicazione OAuth registrata, e i token emessi via questo flusso spesso bypassano le Conditional Access policy perché il dispositivo "richiedente" non è managed. Risultato: compromissione silenziosa, zero alert nei log standard.
Prerequisiti
Per seguire questa guida ti serve:
- Ruolo: Global Administrator o Security Administrator nel tenant Entra ID
- Licenze: Entra ID P1 o P2 per le Conditional Access policy (P2 per Identity Protection e risk-based access)
- Accesso: Azure Portal (
portal.azure.com) o Microsoft Entra admin center (entra.microsoft.com)
- Log Analytics (opzionale): necessario per le query KQL su SigninLogs
- Tempo: 30-45 minuti per configurazione, 15 per verifica
Se non hai P1/P2, leggi comunque — più avanti ti dico cosa puoi fare anche con licenze base.
Step-by-Step
Step 1 — Rileva se il Device Code Flow è già stato usato nel tuo tenant
Prima di bloccare, capisci cosa c'è. Vai su Entra ID > Monitoring > Sign-in logs e filtra per Authentication protocol: deviceCode.
Con Log Analytics o Microsoft Sentinel, usa questa query KQL:
SigninLogs
| where AuthenticationProtocol == "deviceCode"
| where TimeGenerated > ago(30d)
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress, Location, Status
| sort by TimeGenerated desc
Segnali di allarme da cercare:
- IP geolocalizzati in paesi inattesi (Russia, Nigeria, Cina, o exit node VPN/Tor)
- Applicazioni come "Microsoft Azure CLI" su utenti che non fanno DevOps
- Autenticazioni riuscite (
Status.errorCode == 0) da dispositivi non registrati in AAD
- Orari anomali: notte, weekend, fuori orario aziendale
Se trovi qualcosa di sospetto, documenta prima di bloccare. Servirà per l'incident response e per evitare di perdere evidenze.
Step 2 — Blocca il Device Code Flow con Conditional Access
Questa è la mossa principale. Crea una policy CA che blocchi esplicitamente il Device Code Flow.
Percorso: Entra ID > Protection > Conditional Access > New policy
Nome: Block - Device Code Flow
Assignments:
Users: All users
ESCLUDI: break-glass accounts (obbligatorio)
ESCLUDI: gruppo SVC-DeviceCode-Allowed (se serve, vedi Step 3)
Cloud apps: All cloud apps
Conditions:
Authentication flows: Device Code Flow ✓
Grant:
Block access
Enable policy: Report-only (prima!)
Critico: Metti la policy in Report-only per almeno 48-72 ore. Vai su Sign-in logs e filtra per la tua policy — la colonna "Conditional Access" mostrerà "Report-only: Failure" per i tentativi che verrebbero bloccati. Verifica che non stai rompendo workflow legittimi prima di attivare.
Step 3 — Gestisci le eccezioni legittime
Se hai DevOps che usano Azure CLI, VS Code con estensioni Azure, o dispositivi IoT che si autenticano via device code, devi gestirli prima di attivare il blocco.
Crea un gruppo di sicurezza AAD chiamato SVC-DeviceCode-Allowed e aggiungici solo gli utenti che ne hanno genuinamente bisogno. Poi escludili dalla policy di blocco — in Conditional Access il blocco vince sempre, devi usare le esclusioni nella policy esistente, non creare una policy separata di "permetti".
Per dispositivi fisici (sale riunioni, smart TV aziendali), crea una Named Location con gli IP interni:
Percorso: Entra ID > Security > Named locations > New IP ranges location
Nome: Rete-Interna-HQ
IP ranges: 10.0.0.0/8, 192.168.0.0/16 (adatta alla tua rete)
Mark as trusted location: ✓
Aggiungi questa Named Location come esclusione nella policy sotto Conditions > Locations.
Step 4 — Revoca i token già emessi per gli account sospetti
Se hai trovato autenticazioni sospette nello Step 1, i token sono già nell'ambiente. Bisogna revocarli subito.
# Connettiti al Microsoft Graph
Connect-MgGraph -Scopes "User.ReadWrite.All"
# Revoca tutti i refresh token per l'utente compromesso
Revoke-MgUserSignInSession -UserId "utente@azienda.com"
# Verifica le app OAuth autorizzate dall'utente
Get-MgUserOauth2PermissionGrant -UserId "utente@azienda.com" |
Select-Object ClientId, Scope, ConsentType |
Format-Table -AutoSize
Per ogni grant sospetto trovato, rimuovilo:
# Rimuovi un grant specifico (usa il ClientId trovato sopra)
Remove-MgUserOauth2PermissionGrant -UserId "utente@azienda.com" -OAuth2PermissionGrantId "<grant-id>"
Dopo la revoca: reset password forzato e re-enrollment MFA per l'utente interessato.
Step 5 — Abilita le detection in Entra ID Identity Protection
Con licenze P2, configura le risk policies:
Percorso: Entra ID > Protection > Identity Protection
- User risk policy: Medium and above → Require password change
- Sign-in risk policy: Medium and above → Require MFA
Entra ID Identity Protection include detection specifica per token anomali e autenticazioni da IP anonimi. Verifica che i log vengano inviati al workspace Log Analytics:
Percorso: Entra ID > Diagnostic settings
Assicurati che SignInLogs, AuditLogs e RiskyUsers siano tutti configurati e instradati correttamente al tuo workspace. Se questo passaggio manca, le detection non partono.
Nessun controllo tecnico copre tutto. Il vettore principale di questo attacco è umano. Una regola sola che devi comunicare a tutti, con qualsiasi mezzo disponibile:
> Microsoft non chiama mai gli utenti per chiedere di inserire codici su siti web.
Nessuna eccezione. Se qualcuno chiama e chiede di andare su microsoft.com/devicelogin, è un attacco — anche se il numero sembra italiano, anche se il chiamante conosce il nome del tuo responsabile IT o del tuo fornitore di riferimento.
Manda una comunicazione interna oggi. Fai un phishing simulation test se hai KnowBe4, Proofpoint Security Awareness Training o strumenti simili — molti hanno template specifici per device code phishing.
Verifica
Dopo aver attivato la policy (da Report-only a On), verifica con questa query:
SigninLogs
| where AuthenticationProtocol == "deviceCode"
| where TimeGenerated > ago(7d)
| summarize Tentativi=count() by
ErrorCode=tostring(Status.errorCode),
Giorno=bin(TimeGenerated, 1d)
| sort by Giorno desc
Post-attivazione, dovresti vedere quasi esclusivamente errorCode 53003 (blocked by Conditional Access) per tutti i device code flow. Se appare ancora errorCode 0 (successo), c'è un'eccezione non coperta — indaga quale utente o servizio sta passando attraverso.
Verifica anche i risk events per token anomali:
AADUserRiskEvents
| where TimeGenerated > ago(30d)
| where RiskEventType in ("anonymizedIPAddress", "unfamiliarFeatures", "anomalousToken")
| project TimeGenerated, UserPrincipalName, RiskEventType, RiskLevel, AdditionalInfo
| sort by TimeGenerated desc
anomalousToken è il risk event più rilevante per questo attacco — tende a crescere nei giorni successivi a una compromissione se il token viene usato da posizioni o dispositivi nuovi rispetto al comportamento storico dell'utente.
Troubleshooting
"Ho bloccato il Device Code Flow e ora Azure CLI non funziona per i DevOps"
Devi aggiungere quegli utenti al gruppo escluso dalla policy (Step 3). Se non hai creato il gruppo in anticipo, fallo ora: crea SVC-DeviceCode-Allowed, aggiungi gli utenti interessati, aggiorna l'esclusione nella CA policy. I log in Report-only mostravano già questo scenario nei 48-72 ore precedenti all'attivazione — è esattamente per questo che si testa prima di attivare.
"La query KQL non trova nulla su SigninLogs"
I log di Entra non vengono instradati a Log Analytics automaticamente. Vai su Entra ID > Diagnostic settings e verifica la configurazione. Se non hai Log Analytics, usa i filtri nativi nel portale Entra admin center. Alternativa valida: Defender XDR > Advanced Hunting con la tabella AADSignInEventsBeta.
"L'utente dice di non aver inserito nessun codice ma il log mostra un device code flow riuscito"
Due possibilità: l'utente non ricorda o non ha capito cosa ha fatto, oppure l'account era già compromesso in precedenza con sessione attiva. In entrambi i casi: revoca token immediata (Step 4), reset password, analisi completa dell'attività nelle ultime settimane:
AuditLogs
| where InitiatedBy.user.userPrincipalName == "utente@azienda.com"
| where TimeGenerated > ago(30d)
| project TimeGenerated, OperationName, Result, TargetResources
| sort by TimeGenerated desc
"Non ho licenze P1/P2 — che faccio?"
Per il blocco CA del Device Code Flow ti serve almeno P1. Senza licenze Premium puoi comunque: monitorare manualmente i sign-in logs nel portale Entra, disabilitare il Device Code Flow a livello di singole app registrate nel tenant (campo isFallbackPublicClient: false nelle app registration), e puntare forte sulla formazione utenti. Non è lo stesso, ma riduce la superficie d'attacco in modo significativo.
Conclusione
Il device code phishing è uno di quegli attacchi che fanno capire perché il modello "perimetro sicuro" è finito. Non ci sono link malevoli, non ci sono allegati sospetti, non c'è nulla che un filtro tradizionale possa intercettare. C'è solo una telefonata e un codice alfanumerico.
La Conditional Access policy che blocca il Device Code Flow è probabilmente una delle configurazioni con il miglior rapporto effort/impatto in tutto il panorama di hardening Microsoft 365: 30 minuti di lavoro per chiudere un vettore d'attacco reale, attivo, e in crescita.
Attivala in Report-only oggi, analizza i log per 72 ore, poi passa a On. Nel frattempo, scopri come funziona l'analisi del traffico email in tempo reale — il vishing spesso arriva preceduto da un'email di preparazione che un buon filtro può intercettare prima che l'utente riceva la chiamata. Per una copertura email gestita che blocca le comunicazioni di pre-attacco, valuta i piani disponibili su MailSniper.