MSSQL Injection
Last updated
Last updated
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Puede ser posible enumerar usuarios de dominio a través de inyección SQL dentro de un servidor MSSQL utilizando las siguientes funciones MSSQL:
SELECT DEFAULT_DOMAIN()
: Obtener el nombre del dominio actual.
master.dbo.fn_varbintohexstr(SUSER_SID('DOMINIO\Administrador'))
: Si conoces el nombre del dominio (DOMINIO en este ejemplo) esta función devolverá el SID del usuario Administrador en formato hexadecimal. Esto se verá como 0x01050000000[...]0000f401
, nota cómo los últimos 4 bytes son el número 500 en formato big endian, que es el ID común del usuario administrador.
Esta función te permitirá conocer el ID del dominio (todos los bytes excepto los últimos 4).
SUSER_SNAME(0x01050000000[...]0000e803)
: Esta función devolverá el nombre de usuario del ID indicado (si existe), en este caso 0000e803 en big endian == 1000 (normalmente este es el ID del primer usuario regular creado). Luego puedes imaginar que puedes hacer un ataque de fuerza bruta a los IDs de usuario del 1000 al 2000 y probablemente obtener todos los nombres de usuario de los usuarios del dominio. Por ejemplo, utilizando una función como la siguiente:
Las inyecciones SQL basadas en errores típicamente se asemejan a construcciones como +AND+1=@@version--
y variantes basadas en el operador «OR». Las consultas que contienen tales expresiones suelen ser bloqueadas por los WAF. Como una forma de eludir esto, concatena una cadena utilizando el carácter %2b con el resultado de llamadas a funciones específicas que desencadenan un error de conversión de tipo de datos en los datos deseados.
Algunos ejemplos de tales funciones:
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
Ejemplo de uso de la función USER_NAME()
:
Estos trucos de SSRF fueron tomados de aquí
fn_xe_file_target_read_file
Requiere permiso de VIEW SERVER STATE
en el servidor.
fn_get_audit_file
Requiere el permiso CONTROL SERVER
.
fn_trace_gettabe
Requiere el permiso CONTROL SERVER
.
xp_dirtree
, xp_fileexists
, xp_subdirs
Los procedimientos almacenados como xp_dirtree
, aunque no están documentados oficialmente por Microsoft, han sido descritos por otros en línea debido a su utilidad en operaciones de red dentro de MSSQL. Estos procedimientos se utilizan a menudo en la exfiltración de datos fuera de banda, como se muestra en varios ejemplos y publicaciones.
El procedimiento almacenado xp_dirtree
, por ejemplo, se utiliza para realizar solicitudes de red, pero está limitado solo al puerto TCP 445. El número de puerto no es modificable, pero permite leer desde recursos compartidos en la red. El uso se demuestra en el script SQL a continuación:
Es notable que este método puede no funcionar en todas las configuraciones del sistema, como en Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
ejecutándose en un Windows Server 2016 Datacenter
con configuraciones predeterminadas.
Además, hay procedimientos almacenados alternativos como master..xp_fileexist
y xp_subdirs
que pueden lograr resultados similares. Más detalles sobre xp_fileexist
se pueden encontrar en este artículo de TechNet.
xp_cmdshell
Obviamente, también podrías usar xp_cmdshell
para ejecutar algo que desencadene un SSRF. Para más información lee la sección relevante en la página:
Crear una UDF CLR (Función Definida por el Usuario en el Entorno de Ejecución de Lenguaje Común), que es código escrito en cualquier lenguaje .NET y compilado en un DLL, para ser cargado dentro de MSSQL para ejecutar funciones personalizadas, es un proceso que requiere acceso dbo
. Esto significa que generalmente es factible solo cuando la conexión a la base de datos se realiza como sa
o con un rol de Administrador.
Un proyecto de Visual Studio y las instrucciones de instalación se proporcionan en este repositorio de Github para facilitar la carga del binario en MSSQL como una asamblea CLR, permitiendo así la ejecución de solicitudes HTTP GET desde dentro de MSSQL.
El núcleo de esta funcionalidad está encapsulado en el archivo http.cs
, que emplea la clase WebClient
para ejecutar una solicitud GET y recuperar contenido como se ilustra a continuación:
Antes de ejecutar el comando SQL CREATE ASSEMBLY
, se recomienda ejecutar el siguiente fragmento SQL para agregar el hash SHA512 de la asamblea a la lista de asambleas de confianza del servidor (visible a través de select * from sys.trusted_assemblies;
):
Después de agregar la asamblea con éxito y crear la función, se puede utilizar el siguiente código SQL para realizar solicitudes HTTP:
Un método conciso para extraer el contenido completo de una tabla en una sola consulta implica utilizar la cláusula FOR JSON
. Este enfoque es más sucinto que usar la cláusula FOR XML
, que requiere un modo específico como "raw". La cláusula FOR JSON
es preferida por su brevedad.
Aquí se explica cómo recuperar el esquema, las tablas y las columnas de la base de datos actual:
Non-standard whitespace characters: %C2%85 или %C2%A0:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
So for example, multiple queries such as:
Can be reduced to:
Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)