Obteniendo contraseñas via inyección SQL

Iniciado por elshotta, Octubre 13, 2021, 03:23:04 PM

Tema anterior - Siguiente tema

0 Miembros y 2 Visitantes están viendo este tema.

Octubre 13, 2021, 03:23:04 PM Ultima modificación: Octubre 14, 2021, 04:32:20 PM por elshotta
Hola a todos,
Hace unos meses hicimos un proyecto para certificarnos en el instituto, pero aunque sabía de esta vulnerabilidad, no la lograba entender bien, hasta hace poco que estaba realizando los wargames de hackthissite que investigué a fondo para pasar un reto.
Entonces el post lo haré con el proyecto que hice para el instituto.
Bueno, primero se debe buscar una pantalla que cargué información via método GET (URL)

Para saber si es vulnerable a SQLI ponemos una ' al final y si arroja un error significa que si es vulnerable

También en vez de la ' se puede poner AND 1 = 0 (si no carga registros es porque es vulnerable)

Ahora necesitamos saber cuántas columnas tiene la consulta que usa esa tabla.
Para eso vamos a usar un ORDER BY por rangos, osea primero vamos a poner ORDER BY 5, si nos muestra datos pues aumentamos el rango a 10 y así de 5 en 5.

Bueno algo que no he mencionado es que algo así va la consulta que se le envía a la base de datos
SELECT * FROM historial_caddie WHERE id_usurario = 199 ORDER BY 5 ORDER BY fecha ASC;
Como se ve hay dos ORDER BY (el rojo es el que se está insertando en la url), para resolver este problema vamos a poner –- que significa comentario en SQL, y comentara todo lo que le siga después de nuestro ORDER BY insertado en la URL

Entonces ya nos muestra nuevamente la pantalla, ahora seguimos con los rangos
ORDER BY 5-> Sigue mostrando datos
ORDER BY 10-> Sigue mostrando datos
ORDER BY 15 -> Sigue mostrando datos

ORDER BY 20 -> Muestra un error
SQLSTATE[42S22]: Column not found: 1054 Unknown column '20' in 'order clause'
El error puede variar según el tipo de conexión (en mi caso usamos php PDO, pero si usa mysqli sale uno diferente, pero pues siempre dirá algo acerca de las columnas)
Ahora sabemos que el número de columnas que trae la consulta está entre 15 y 20, entonces empezamos a disminuir el número hasta que nos vuelva a mostrar la página sin errores
ORDER BY 19 -> Sigue mostrando el error
ORDER BY 18 -> Sigue mostrando el error

ORDER BY 17 -> Muestra la página nuevamente
Lo siguiente que debemos hacer es usar la sentencia UNION,  lo que permitirá hacer otra consulta dentro de la primera consulta, osea UNION SELECT......
Lo que haremos es poner UNION SELECT y los números consecutivos de las columnas que tiene la base de datos

Pero ahora no me gusta que traiga la información que carga la consulta original, para quitarla vamos a negar la consulta, simplemente poniéndole un - antes del id_usuario

Ahora, los números que muestra la tabla son los que debemos modificar en la url para que traiga datos.
Podemos sacar la versión, reemplazando un número que se muestre por version(), para sacar el nombre de la base de datos reemplazamos un número por database()

Hasta ahora todo bien, lo que sigue es saber los nombres y la cantidad de tablas que hay en la base de datos, para eso reemplazamos un número (por ejemplo el mismo 3) y ponemos TABLE_NAME, al final de la consulta (antes de los --) digitamos FROM information_schema.tables WHERE table_schema = database()

Bueno, para los que no sepan, mysql tiene una base de datos llamada information_schema donde se guardan todas las tablas de todas las bases de datos existentes, podemos quitar el where y traerá todas las tablas existentes, pero lo que nos interesa es solo los de la base de datos que usa este programa.
Noto que hay una tabla llamada rol y una llamada usuarios, entonces reemplazo donde dice TABLE_NAME por COLUMN_NAME y en el information_schema.tables también cambio por information_schema.columns además en el WHERE se debe agregar un AND TABLE_NAME = 'usuarios' ( o la tabla que se quiera consultar)
/sicagolf_php/?controller=master&method=verHistorial&id_usuario=-223 UNION SELECT 1,2,COLUMN_NAME,4,5,6,7,8,9,10,11,12,13,14,15,16,17 FROM information_schema.columns WHERE table_schema = database() AND TABLE_NAME = 'usuarios'—

Después de identificar las columnas de acceso como son correo, password, id_rol se procede a hacer lo siguiente:
1.   Reemplazar los números 3,4,5 (o los que querramos, depende de cada página y cada consulta) por los nombres de la columna
2.   Quitar el todo el WHERE y solo dejar FROM usuarios (porque ya sabemos las columnas de la tabla y no necesitamos el information_schema mas)

Ya se listan los datos de correo y password (cifrados claramente), lo que se necesita saber es cuál es el admin, porque no valdría la pena gastar tiempo decifrando un password y que resulte siendo un usuario sin los privilegios que se desean.
Antes se vio que hay una tabla llamda rol si la consultamos en el information_schema, se nota que tiene dos columnas id_rol y rol donde rol es el nombre del rol.
Esto indica que las tablas están relacionadas, por lo que se procede a hacer un INNER JOIN para saber el rol de los usuarios listados.
Se pone FROM usuarios u INNER JOIN rol r ON You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login_rol = You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login_rol al final de la url (antes del --) y se cambia el número 5 por rol
No voy a explicar sobre INNER JOIN porque se sale del tema del post.

Y bueno, el rol con más privilegios es el Master por la lógica, así que esa es la clave que debemos descifrar, ya esa parte iría en cada quién, como y con que herramienta decifre password, yo la verdad intenté con John The Ripper, pero no se usarlo bien ajajajaajj.
Una cosa más, en mozilla permite el ingreso de espacios en la url, pero en google chrome pone un %20, lo que se debe hacer es reemplazar los espacios por un + para que no se vea tan feo.
Hasta acá llega el Post, espero que les haya gustado.

Octubre 13, 2021, 07:42:30 PM #1 Ultima modificación: Octubre 14, 2021, 11:55:00 PM por AXCESS
Está muy bien hecho!! y explicado.
Buen trabajo!

Gracias por compartirlo.

Buenos Deseos.
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login

Muy buen tutorial @elshotta, didáctico y bien explicado.

Seguro que les resulta muy útil a todos los que están empezando.

Un saludo.



@elshotta

¡Está brutal!

~ DtxdF
PGP :: <D82F366940155CB043147178C4E075FC4403BDDC>

~ DtxdF

Buen post! Es recomendable ir adaptandose a SQL manualmente.

Muy ameno. Deberían recomendar esto como introducción a sqli. Yo haré mi parte.


Agosto 21, 2025, 04:31:14 PM #7 Ultima modificación: Agosto 21, 2025, 04:33:49 PM por Hern@n
pero con solo poner un par de codigos de seguridad en el archivo .htaccess ubicado en el directorio principal, chau "hackers"

#
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#
Options -Indexes

#
<LimitExcept GET POST>
  Deny from all
</LimitExcept>

#
<FilesMatch "\.(htaccess|htpasswd|ini|env|log|sh)$">
  Order allow,deny
  Deny from all
</FilesMatch>

#
<IfModule mod_headers.c>
    # Activar el encabezado X-XSS-Protection
    Header set X-XSS-Protection "1; mode=block"
   </IfModule>

#
RewriteEngine On
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]

#
<IfModule mod_headers.c>
    Header set X-Content-Type-Options: nosniff
</IfModule>

#
<IfModule mod_headers.c>
    Header set Edge-Control "no-cache, no-store"
</IfModule>

<IfModule mod.headers.c>
Header always set Strict-Transport-Security "max-age=5555555; includeSubDomains; preload"
</IfModule>

#
<IfModule mod_headers.c>
    Header set Age "0"
</IfModule>

#
<IfModule mod_headers.c>
    Header set Cache-Control "max-age=11, must-revalidate"
</IfModule>
#

<IfModule mod_headers.c>
Header set X-DNS-Prefetch-Control "on"
</IfModule>

#
Header unset X-Powered-By
@NiveLZ en telegram

aparte... ese tipo de inyeccion sql (que estaba de moda en el 2011) si en el caso de practicarla en una web con muy poca seguridad y todos los huecos de seguridad abiertos (unica forma de que ese tipo de inyeccion sql andaria) en el caso de tener suerte de hallar una pagina para que esa tecnica hacking ande...no se podria ver la constraseña porque todas las contraseñas estan cifradas, en todo caso se hallaria un codigo cifrado del cual luego se podria probar si ese codigo se podria desencriptar, y si el codigo que contiene la contraseña contiene una contraseña larga, alfanumerica y con algun simbolo, seria casi imposible desencriptarla
@NiveLZ en telegram

Agosto 21, 2025, 05:26:05 PM #9 Ultima modificación: Agosto 21, 2025, 05:28:20 PM por The Cid James
You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Loginaparte... ese tipo de inyeccion sql (que estaba de moda en el 2011) si en el caso de practicarla en una web con muy poca seguridad y todos los huecos de seguridad abiertos (unica forma de que ese tipo de inyeccion sql andaria) en el caso de tener suerte de hallar una pagina para que esa tecnica hacking ande...no se podria ver la constraseña porque todas las contraseñas estan cifradas, en todo caso se hallaria un codigo cifrado del cual luego se podria probar si ese codigo se podria desencriptar, y si el codigo que contiene la contraseña contiene una contraseña larga, alfanumerica y con algun simbolo, seria casi imposible desencriptarla

Tal cual pero te sorprenderia la cantidad de sitios que ni se toman la molestia al dia de hoy xD, Ademas es un post de hace 4 años lol

My name is Cid, Master of the Council's Will, General of the Republic's Armies, and loyal servant to the TRUE Force. Disciple of a murdered Master, guardian of a murdered Padawan. And I will find justice, in this life or the next.

Recuerdo hace bastantes años que esto te lo hacía un programa llamado Havij, ya no se si todavía existe o hay algo así pero era TOP