Tu pensais que le phishing passait par des formulaires moisis et des fautes dâorthographe ? RĂ©veille-toi. Le device code phishing est lâarnaque qui te fait cliquer sur « Autoriser » pendant que lâattaquant rĂ©colte un jeton valable. Pas de mot de passe. Pas de craquage. Juste toi, qui crois bien faire.
Pendant ce temps, les attaquants piochent aussi dans un vivier plus discret mais tout aussi meurtrier : les tokens dâAPI/OAuth â ces clĂ©s quâon laisse vivre Ă©ternellement dans des scripts, pipelines ou comptes abandonnĂ©s. Si tu veux comprendre pourquoi ça sent pas bon, lis ce dossier sur les tokens et les fuites SaaS. secuslice – blog cybersĂ©curitĂ©
đ Le scĂ©nario en clair â Ă©lĂ©gant, propre, efficace
- Lâattaquant tâenvoie un message ou tâouvre une page qui te demande un code Ă quatre/six chiffres.
- Tu copies-colles le code depuis le mail/Teams/Slack vers une page qui ressemble Ă celle de ton IdP.
- Le flux OAuth Ă©change ce code contre un token. Lâattaquant lâobtient, et toi tu repars boire ton cafĂ©.
RĂ©sultat : accĂšs lĂ©gitime Ă tes mails, fichiers, API. Lâauthentification est respectĂ©e dans les logs. Tu nâas rien Ă te reprocher. Câest tragique. Et magnifique pour lâattaquant.
đą Pourquoi ça marche si bien en entreprise
- Parce que lâutilisateur est programmĂ© Ă obĂ©ir aux workflows.
- Parce que beaucoup dâorganisations nâont pas inventorier ni verrouillĂ© les flows OAuth (device flow inclus).
- Parce que les tokens / refresh tokens ne dĂ©clenchent pas de MFA ni dâalarme standard.
- Parce que lâautomatisation (CI/CD) et les devs fatiguĂ©s distribuent des tokens comme des Post-it.
Si ton instance SaaS ressemble à un grand open-bar, félicitations : tu es attractif pour les voleurs de jetons.
đ Azure vs Google : nuances, pas miracles
Microsoft et Google ont des comportements diffĂ©rents sur lâexpĂ©rience consentement et la visibilitĂ© des logs. Azure, flexible, peut aussi ĂȘtre permissif si tu laisses les paramĂštres par dĂ©faut; Google impose un peu plus de friction sur les scopes et les apps tierces. Cela dit, aucune des deux plateformes nâest immunisĂ©e : la dĂ©fense repose sur configurationet gouvernance, pas seulement sur le fournisseur.
đĄïž La checklist SecuSlice (actionnable tout de suite)
- DĂ©sactiver le device code flow si personne ne sâen sert rĂ©ellement.
- Whitelist des applications OAuth approuvĂ©es : pas dâinscription libre dâapps.
- Consent policies : exiger lâapprobation admin pour les scopes sensibles.
- TTL courts pour les tokens et rotation automatique (scripts/cron/CI).
- Inventaire centralisé des tokens/clients et attribution claire dâun propriĂ©taire.
- SIEM : ingĂ©rer les logs API/OAuth et alerter sur consentements suivis dâaccĂšs API.
- Secrets management : Vault, Secrets Manager â pas de tokens en clair dans les repos.
- Sensibilisation : phrase simple et répétée : « on ne colle pas de code sur un site non officiel. »
đ DĂ©tection : quoi surveiller dans le SIEM
- Consentement OAuth pour unÂ
client_id inconnu suivi immĂ©diatement dâun accĂšs Graph/IMAP/API. RefreshToken actif pour un compte inactif ou un ex-collaborateur.- Connexions API depuis des IPs anonymisantes ou pays non habituels.
- Apparition dâun nouveauÂ
client_id qui demande des scopes larges.
Alerter vite, rĂ©voquer les tokens, bloquer lâapp, et lancer lâinvestigation.
đ©ș Playbook dâurgence (3 gestes qui sauvent la baraque)
- Révoquer immédiatement les refresh tokens et sessions du compte compromis.
- DĂ©sactiver lâapplication OAuth suspecte (admin console).
- Auditer logs dâaccĂšs, API utilisĂ©s, et rechercher propagation via CI/CD.
Puis huiler la roue de la gouvernance pour que ça nâarrive plus (ou moins souvent).
đ„ Message court Ă diffuser (prĂȘt Ă copier/coller)
Objet : Alerte â nouvelle forme de phishing (code Ă coller)
Corps : Ne collez JAMAIS de code reçu par message sur une page non officielle. En cas de doute, contactez [email protected]. Si vous avez collé un code, signalez-le immédiatement.
Simple, clair, pas culpabilisant. Câest ce quâil faut.
đŻ Conclusion : OAuth nâest pas une baguette magique
OAuth et les tokens sont indispensables. Ils sont aussi dangereux quand on les laisse vivre sans garde-fou. Le device code phishing expose la faiblesse humaine; les tokens exposĂ©s rĂ©vĂšlent la faiblesse organisationnelle. Les deux ensemble, câest la recette pour une compromission silencieuse.
đŻ Le bonus
Deux rĂšgles prĂȘtes Ă coller, KQL (Microsoft Sentinel) et ELK (Elastic DSL), pour dĂ©tecter un cas typique de device code phishing : un consentement OAuth inhabituel suivi dâactivitĂ© API.
Objectif : spotter
- un nouvelÂ
client_id OAuth (non approuvé), - accord de consentement,
- puis accĂšs Graph / IMAP / Gmail API similaire,
- dans les minutes/heures qui suivent.
Ces rĂšgles sont un socle. Tu pourras les durcir ensuite selon ton contexte.
đŠ KQL â Microsoft Sentinel
DĂ©tection dâapp OAuth inconnue + obtention token + activitĂ© Graph dans la foulĂ©e
let timeframe = 1h;
let trustedApps = dynamic([
"00000003-0000-0000-c000-000000000000", // Microsoft Graph
"00000002-0000-0000-c000-000000000000" // Office 365 Exchange Online
]);
let SuspiciousConsent = AuditLogs
| where TimeGenerated > ago(timeframe)
| where ActivityDisplayName in ("Consent to application", "Add OAuth2PermissionGrant")
| extend AppId = tostring(parse_json(InitiatedBy).app.appId)
| where AppId !in (trustedApps)
| project TimeGenerated, UserId=tostring(TargetResources[0].id), AppId, AppName=TargetResources[0].displayName;
let OAuthTokenIssued = AADSignInLogs
| where TimeGenerated > ago(timeframe)
| where TokenIssuerType == "AzureAD"
| project TimeGenerated, UserPrincipalName, AppId, IPAddress, ClientAppUsed;
let GraphCalls = AADSignInLogs
| where TimeGenerated > ago(timeframe)
| where ResourceDisplayName contains "Microsoft Graph"
| project TimeGenerated, UserPrincipalName, IPAddress;
SuspiciousConsent
| join kind=inner OAuthTokenIssued on AppId
| join kind=inner GraphCalls on UserPrincipalName
| where GraphCalls.TimeGenerated > SuspiciousConsent.TimeGenerated
| sort by SuspiciousConsent.TimeGenerated desc
â Ce que ça alerte
- App OAuth non approuvée
- Consentement utilisateur
- Token émis
- Appel API Graph derriĂšre
Le combo gagnant pour du device code phishing.
đ§ ELK â Elastic Query DSL (Elasticsearch)
MĂȘme logique : consentement + appel API Graph / Gmail API
{
"query": {
"bool": {
"must": [
{
"range": {
"@timestamp": { "gte": "now-1h" }
}
},
{
"terms": {
"event.action": [
"oauth2-authorization-grant",
"oauth2-consent"
]
}
},
{
"bool": {
"must_not": {
"terms": {
"oauth.client.id": [
"00000003-0000-0000-c000-000000000000",
"00000002-0000-0000-c000-000000000000"
]
}
}
}
}
]
}
}
}
Ajoute ensuite une detection rule ELK pour chainer avec des événements qui matchent :
resource.name: "Microsoft Graph" OR resource.name: "gmail.googleapis.com"
Ou si tu veux pousser le vice :oauth.client.id qui apparaĂźt pour la premiĂšre fois dans les 30 derniers jours dans ton index â bruit minime.
đ§Ș Option bonus â test rapide pour voir si ça remonte
Simule un consentement OAuth Ă la main.
Dans many orgs, les logs OAuth sont silencieux. Tu verras tout de suite si ton pipeline est sec.
đŻ Conseil dâarchi dĂ©fensif malin
Ne fais pas que détecter. Lister les apps OAuth autorisées dans un index Elastic et faire une join check.
Ăa donne une rĂšgle plus robuste :
- App non listée
- Consent
- Token
- API call
Câest littĂ©ralement lâIDS de l’identitĂ©.
đ Conclusion
Tu as maintenant :
- Une rĂšgle KQL solide
- La version ELK équivalente
- Le workflow de dĂ©tection pensĂ© âattaque moderneâ
