MSSQL Injection
Inyección MSSQL
Enumeración de Active Directory
Puede ser posible enumerar usuarios de dominio a través de una inyección SQL dentro de un servidor MSSQL utilizando las siguientes funciones MSSQL:
SELECT DEFAULT_DOMAIN()
: Obtener el nombre de 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á como0x01050000000[...]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 (usualmente este es el ID del primer usuario regular creado). Luego puedes imaginar que puedes hacer fuerza bruta en los IDs de usuario desde 1000 hasta 2000 y probablemente obtener todos los nombres de usuario de los usuarios del dominio. Por ejemplo, utilizando una función como la siguiente:
Vectores de Error Alternativos
Las inyecciones SQL basadas en errores suelen tener construcciones como +AND+1=@@version--
y variantes basadas en el operador «OR». Las consultas que contienen tales expresiones suelen ser bloqueadas por los WAFs. Para evitar esto, concatena una cadena utilizando el carácter %2b con el resultado de llamadas a funciones específicas que desencadenen un error de conversión de tipo de datos en los datos buscados.
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()
:
SSRF
Estos trucos de SSRF fueron tomados de aquí
fn_xe_file_target_read_file
fn_xe_file_target_read_file
Requiere permiso de VIEW SERVER STATE
en el servidor.
fn_get_audit_file
fn_get_audit_file
Requiere el permiso CONTROL SERVER
.
fn_trace_gettabe
fn_trace_gettabe
Requiere el permiso CONTROL SERVER
.
xp_dirtree
, xp_fileexists
, xp_subdirs
xp_dirtree
, xp_fileexists
, xp_subdirs
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 suelen ser utilizados 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 la lectura desde recursos compartidos de red. El uso se demuestra en el script SQL a continuación:
Es importante tener en cuenta 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)
en un Windows Server 2016 Datacenter
con la configuración predeterminada.
Además, existen 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
xp_cmdshell
Obviamente, también se podría utilizar xp_cmdshell
para ejecutar algo que desencadene un SSRF. Para obtener más información, lea la sección relevante en la página:
Función Definida por el Usuario MSSQL - SQLHttp
Crear una UDF CLR (Función Definida por el Usuario de Tiempo de Ejecución de Lenguaje Común), que es código creado en cualquier lenguaje .NET y compilado en un DLL, para ser cargado en MSSQL para ejecutar funciones personalizadas, es un proceso que requiere acceso dbo
. Esto significa que generalmente solo es factible cuando la conexión a la base de datos se realiza como sa
o con un rol de Administrador.
Un proyecto de Visual Studio e instrucciones de instalación se proporcionan en este repositorio de Github para facilitar la carga del binario en MSSQL como un ensamblado CLR, lo que permite la ejecución de solicitudes HTTP GET desde MSSQL.
El núcleo de esta funcionalidad está encapsulado en el archivo http.cs
, que utiliza 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 de SQL para agregar el hash SHA512 del ensamblado a la lista de ensamblados confiables del servidor (visible a través de select * from sys.trusted_assemblies;
):
Después de agregar con éxito la assembly y crear la función, el siguiente código SQL se puede utilizar para realizar solicitudes HTTP:
Explotación Rápida: Recuperación de Todo el Contenido de una Tabla en una Sola Consulta
Un método conciso para extraer todo el contenido de una tabla en una sola consulta implica utilizar la cláusula FOR JSON
. Este enfoque es más conciso 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.
Así es como se puede recuperar el esquema, las tablas y las columnas de la base de datos actual:
Retrieving the Current Query
For users granted the VIEW SERVER STATE
permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm_exec_requests and sys.dm_exec_sql_text:
To check if you have the VIEW SERVER STATE permission, the following query can be used:
MSSQL Injection
Inyección MSSQL
El siguiente es un ejemplo de una inyección MSSQL en una URL:
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
Inyección MSSQL de Union-Based
URL vulnerable:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
URL vulnerable:
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
MSSQL Injection
Inyección MSSQL
El siguiente es un ejemplo de una inyección MSSQL en una URL:
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
Agregando un exec() inútil al final y haciendo que el WAF piense que esto no es una consulta válida
admina'union select 1,'admin','testtest123'exec('select 1')--
Esto será:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123' exec('select 1')--'
Utilizando consultas construidas de manera extraña
admin'exec('update[users]set[password]=''a''')--
Esto será:
SELECT id, username, password FROM users WHERE username = 'admin' exec('update[users]set[password]=''a''')--'
O habilitando xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Esto será
select * from users where username = ' admin' exec('sp_configure''show advanced option'',''1''reconfigure') exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Última actualización