Muy bien, ahora veamos lo que es una inyección SQL de tipo UNION, y para eso usaremos la
misma inyección SQL de antes. Y tú dirás, pero si me dijiste que la de antes era de
tipo error. Mientes, me haces daño y luego te arrepientes. Verás compadre, una inyección
SQL de tipo error puede ser explotada de múltiples formas, y por múltiples formas me refiero
a usar diferentes instrucciones de lenguaje SQL y combinarlas entre sí, mientras que
ese coherente viejo funcionará. Y evidentemente, esta inyección SQL de tipo error puede ser
explotada también con la cláusula UNION, pasando así a ser también una inyección SQL de tipo UNION. Y como te digo, este tipo de casos no son aislados, son bastante comunes
Ahora fíjate, como entenderás en este tipo de inyecciones SQL, lo que buscamos es concatenar
la consulta original con otra consulta que nosotros generemos, y esta unión la haremos
a través de la cláusula UNION, para de esta forma poder obtener más información sobre
la base de datos. Pero como sobrás para que una cláusula UNION se ejecute con éxito
debemos seleccionar en el segundo SELECT el mismo número de columnas, que ya están seleccionadas
en el SELECT antes del UNION. Por lo que nosotros viendo el código podemos saber que
en este caso son dos columnas, este siendo el número que podemos usar en el otro UNION
Pero en la vida real tú no sabrás el número de columnas, ¿qué tendrá la consulta original
A menos que te den acceso al código fuente. Pero si por ejemplo haces un pentestín de caja negra no lo vas a tener, o bueno, a priori no
Así que ¿cómo podríamos nosotros determinar el número de columnas, en este tipo de casos
Pues esto es muy simple, podríamos por ejemplo hacer un UNION, para luego llamar a la instrucción
SELECT, y en lugar de seleccionar columnas, por ejemplo, seleccionar valores nulos, que
esto prácticamente no va a seleccionar nada, porque no nos va a retornar ningún valor
pero a nivel de la base de datos se pueden usar, para este contexto puntual
Y simular entre comillas las columnas, que estamos solicitando con SELECT, y digo simular
entre comillas porque NULL no se creó para esto, es un uso que podemos darle pero no
se creó para esto. Por lo que por ejemplo podemos hacer una prueba, digamos un SELECT de 5 NULLS, separados por coma, es decir, en este hipotético caso simular 5 columnas
Si ejecutamos esta consulta veremos que nos arroja este mensaje, diciendo que no coincide el número de columnas, por lo que ya sabemos que por lo menos 5 no tiene, ahora nada más
nos queda probar con infinitos números. Entonces, aquí lo que se suele hacer en este tipo de inyecciones de SQL es partir de un
número de columnas, bueno columnas entre comillas, por ejemplo 5, e ir bajando, hasta
llegar al número de columnas que existen, y que obviamente en este caso partimos desde
5, pero no siempre tiene que ser así, porque digamos que la consulta original, el SELECT
que está antes del UNION, digamos que en otra aplicación web tiene 10 columnas, pues si nosotros intentamos identificar el número y partimos de 5, pues jamás daremos con la
respuesta viejo, eso es obvio. Pero bien, en este caso puntual, aquí ya vemos que con 5 no se puede, podemos probar
con 4, y tampoco, podemos probar con 3, y de igual forma tampoco, pero cuando probamos
con 2, viva la vida, ahí si nos deja. Entonces podemos determinar que hay dos columnas, de la consulta original, que se están seleccionando
con la instrucción SELECT, y que por ende nosotros podemos solicitar información, en
nuestro SELECT, mientras que no nos pasemos de dos argumentos, que es el máximo en este caso
Entonces, con esta información, ¿qué es lo primero que tenemos que identificar? Lo más elemental es la estructura de la base de datos, para saber que otras bases
de datos, tablas y columnas existen en este sistema gestor de bases de datos
Y esto lo podemos hacer consultando la base de datos, InformationSchema, que tú ya sabes
qué es, y que por defecto en MySQL viene ya creada, con toda la información que necesitamos
Y por eso podemos intuir que en este caso ya existe, porque si recuerdas en la clase pasada tuvimos un mensaje de error, cuando rompimos esta consulta, y justamente en ese
error nos decía que el sistema gestor de bases de datos que estaba usando era MySQL
Esto es información que tienes que ir anotando papá. Hay que fijarse en todos los detalles. Ahora, en base a lo que tenemos ya controlado, lo más elemental de todo en este caso es
identificar qué base de datos se está usando ahora mismo, para esta aplicación web
Y para esto, como tú ya sabes, tenemos varias funciones, por ejemplo la función DATABASE
que es cuando se ejecute, precisamente nos va a devolver esto, el nombre de la base de datos actual
Así que en este caso podemos hacer un SELECT de la función DATABASE y de un valor NULL
Y al ejecutar esta consulta, fíjate que por aquí nos la pone. Y podemos determinar que la base de datos usada por la aplicación web en este momento
es de VWA. Ahora, con esta información presente, podemos ejecutar otro SELECT
Y en este caso, basándonos en la estructura de la information schema, podemos solicitar
la columna TABLE NAME y un valor NULL. Desde la base de datos information schema.TABLES, que recordemos que en este caso TABLES no
es una tabla, es una vista. Y le indicamos con un WHERE, que únicamente nos muestra la información de esta columna
donde la columna TABLE SCHEMA sea igual a de VWA, que es la base de datos que nos interesa
Y acto seguido hacemos un comentario, por si quedara todavía código de la consulta original, pues que este no se ejecute
Y recuerda que como estamos en MySQL, podemos comentar con un numeral. O almohadilla, viejo
Y ten en cuenta, por aquí sí debemos referenciar la vista TABLES, indicando concretamente la
base de datos, donde ésta se encuentra. Y tenemos que indicárselo porque la base de datos activa no es ésta, en este caso
es de VWA. Ahora, si ejecutamos esta consulta, veremos que nos arroja dos registros, que son correspondientes
a los nombres de las tablas, dentro de la base de datos de VWA. Y estas dos tablas son GUEST BOOK y USERS
Aquí es evidente, viejo, la más jugosa es USERS. Por lo que vamos a seleccionarla. Para en este caso, por ejemplo, conocer las columnas que estén dentro de esta tabla
y seguir sacando información. Por lo que podríamos hacer una nueva consulta SELECT a través de nuestro UNION
En este caso seleccionando la columna COLUMN NAME y un valor NULL, desde INFORMATION SCHEMA
que es la base de datos, punto COLUMNS. Donde, en este caso, la columna llamada TABLE NAME tenga el valor de USERS, porque es básicamente
lo que queremos, solamente información correspondiente a esta tabla, a la tabla USERS
Y al ejecutar esta consulta, veremos ahora las columnas de dicha tabla. Por lo que repasemos, ya entendemos que hay una base de datos llamada de VWA, que es la
que está usando activamente la aplicación web, y que dentro de esta base de datos hay una tabla llamada USERS, que tiene las siguientes columnas, USER ID, FIRST NAME, LAST NAME
USER PASSWORD, AVATAR, LAST LOGGING y FAILED LOGGING. De estas columnas las que nos enamoran a primera vista son las de USER y PASSWORD, evidentemente
Así que en base a toda esta información ya podríamos generar nuestro payload final
es decir, hacer uso de UNION y seleccionar la columna USER, la columna PASSWORD desde
la tabla USERS. Y ten en cuenta, podríamos especificar la base de datos, ¿o no
En este caso da un poco igual esto, porque la base de datos activa ya es de VWA, y poner
de VWA.USERS es redondar un poco. Y ahora si ejecutamos esta consulta, veremos los registros que pedimos, que en este caso
son los nombres de usuario y sus contraseñas, que en este caso están hasheadas, en MD5
Por lo que así de simple, en base a la information schema, tú puedes obtener información de la base de datos que usa la aplicación web, o de cualquier otra si quisieras, papá
Y te digo, este procedimiento, obviamente cambiando los valores, es de un uso bastante
común, porque simplemente es hacer consultas con lógica, elementos que están dentro del
sistema gestor de bases de datos, para meramente obtener más información. Y como ves, no es magia, es solamente usar la lógica
Así que con esto explicado, vamos ahora si a ver más tipos de inyecciones SQL, de tipo UNION
Aunque te diría, que te repases esta clase, verás que mientras más veces la veas, más vas a entender lo que hicimos, y es importante que este paradigma lo tengas claro, así que
repásate la clase, papá. Y si ya te la repasaste, pues continuemos