Inyección SQL en ORACLE
Table of Contents
ToggleIntroducción
Hemos visto diferentes tipos de inyecciones SQL en base de datos, especialmente Mysql. Si bien esta es una de las más usadas y tiene varias similitudes con otras, no es la única. En este apartado estaremos practicando inyección SQL en ORACLE. Ya que esta base de datos suele ser usada por grandes empresas o instituciones, veremos un poco el funcionamiento y las diferencias que existen entre consultas Mysql y ORACLE.
Para esto estaremos haciendo uso del laboratorio SQLI de Portswigger.
Consultas al tipo de base de datos en Oracle
A continuación, tendremos que obtener la base de datos y la versión de la misma, como nos muestra en pantalla (en el cuadro rojo) dicho laboratorio. Pero esta vez para Oracle:
Podemos observar que estamos dentro de un sitio web cuyo contenido son “Food & Drink, Gifts, Pets…” Si le damos click a uno de estos, veremos que dicha información se divide en “category” como muestra la barra del navegador. Por lo tanto, nuestro primer paso será saber si dicho sitio web es vulnerable a SQLI de la siguiente manera:
Hemos agregado una ‘ para verificar esto y, a su vez, obtuvimos un mensaje de “Internal Server Error”. Por tanto, podremos ir probando otras consultas y ver si podemos obtener más información. Por ejemplo, colocando ‘ or 1=1.
Como se muestra en pantalla, con esto ya podemos verificar que es vulnerable a SQLI ya que acepta nuestra consulta y nos devuelve toda la información de dichos campos. Una vez sepamos esto, debemos verificar la cantidad de columnas existentes en dicha base de datos. Recordemos que esto lo hacemos porque, para usar la cláusula UNION, es necesario que sean compatibles las consultas del sitio web con las que le pasemos. Por lo tanto deberemos colocar ‘ unión select null,null … — hasta que encontremos la cantidad exacta.
Como vemos, hemos intentado colocar cinco veces “null” y no hemos tenido resultado. Sin embargo, hay dos cosas que tenemos que tener en cuenta llegado a este punto:
1) Podemos observar que cada sección del sitio web corresponde a un título y a una descripción del mismo. Con lo que podríamos suponer que hay dos campos para cada sección del sitio web.
2) Teniendo en cuenta lo anterior, de igual manera si seguimos colocando “null,null,null…”, no tendremos resultado. Esto se debe a que nos encontramos en una base de datos ORACLE y algunos detalles en las consultas cambian (por ejemplo, para comentar utilizamos solo “—“).
Para saber la versión, a través de una inyección SQL en ORACLE, la consulta puede ser una de las siguientes:
- SELECT banner FROM v$version
- SELECT version FROM v$instance
Entonces, suponiendo que hay dos campos (título y descripción), vamos a utilizar unas de las consultas anteriores:
Si revisamos al final del sitio web, nos ha devuelto la información que buscábamos: Tipo y versión de la base de datos. Por lo tanto, hemos tenido éxito con nuestra consulta.
Consultas al tipo de versión y base de datos con Mysql y microsoft
A modo de ejemplo y comparación, con respecto a la inyección sql en oracle, el laboratorio nos pide lo mismo que lo anterior. Pero esta vez utilizando consultas para base de datos MYSQL y SQL Server (Microsoft)
Debemos saber que tanto para Mysql y Microsoft las consultas para saber la versión pueden ser las siguientes:
- Select null,@@version — –
- Select null,version() — –
Listar el contenido de la base de datos en Oracle
Ahora bien, en este laboratorio tendremos que enumerar el contenido de las bases de datos. Ya vimos cómo reconocer si dicho sitio es vulnerable a inyección sql en oracle, una vez hecho esto, podemos usar la siguiente consulta:
‘ UNION SELECT null,null,… FROM dual —
Como vemos, éste método suele ser utilizado con la cláusula UNION en ORACLE para saber la cantidad de columnas a utilizar. Ahora ya sabemos que dicha cantidad es dos y, por lo tanto, son con las que vamos a estar interactuando.
Dato a saber:
Debemos tener en cuenta lo siguiente a la hora de enumerar bases de datos en ORACLE:
Existe una falta de coincidencia de terminología entre MySQL y ORACLE Database. En términos de arquitectura, Oracle se conforma en “table-> schema-> database”. MySQL tiene simplemente “table-> database”. Por lo tanto, ORACLE se basa en schemas, por lo que las herramientas comúnmente utilizadas se conectan a una instancia de base de datos, y una instancia pertenece a una sola base de datos.
Listar las tablas de la base de datos
Dicho esto, en el caso de querer enumerar todas las tablas en ORACLE podemos usar la siguiente consulta:
‘UNION SELECT null,table_name FROM all_tables —
También podríamos usar la siguiente consulta para listar las cuentas con privilegios:
‘UNION SELECT null,owner FROM all_tables —
Como podemos ver, nos devuelve demasiada información. En este caso, todas las tablas existentes. No obstante, si seguimos bajando veremos que una de las tablas tiene el nombre de “USSERS-NEEPDX”. Por lo tanto, podemos suponer que dicha tabla posee información confidencial acerca de los usuarios del sistema, como sus contraseñas, por ejemplo.
Listar las columnas de la base de datos
Para listar las columnas de dicha tabla en ORACLE, podríamos hacer uso de la siguiente consulta:
‘ UNION SELECT null,column_name FROM all_tab_columns WHERE table_name = ‘name_of_table ’ —
Hecho esto, vemos que nos devuelve dos columnas. Una pertenecientes al nombre de los usuarios y la otra a sus contraseñas. Sabiendo esto, solo queda buscar dicha información a través de la siguiente consulta:
‘ UNION SELECT column-1, column-2 FROM table —
Pero antes de seguir avanzando, recordemos que algunas veces en algunos campos null quizá no podamos colocar información, debido a alguna configuración del sistema. Ahora bien, supongamos que en la primera columna null no nos devuelve información, pero en la segunda sí. Podríamos realizar una consulta colocando primero la columna de usuarios (USERNAME_XWCLCX) para saber los nombres de usuarios y, luego realizar otra consulta colocando la columna de password (password_UKBOEF) para saber las contraseñas de dichos usuarios.
Listar los usuarios y contraseñas de la base de datos
Una forma muy utilizada que hemos mencionado anteriormente, sería hacer uso de group_concat() o también: username||’:’||password todo esto dentro de un mismo campo y de una forma más “amigable”. Veamos cómo quedaría a continuación:
Como resultado, tenemos tres usuarios con sus respectivas contraseñas (separadas por ‘:’). Ahora bien, podemos notar que uno de los usuarios es “administrator”, con lo que podemos suponer que dicho usuario tiene permisos elevados. Por tanto, vamos a intentar ingresar en el sistema con dicho usuario y contraseña en “My account”.
Como vemos en la siguiente imagen, hemos tenido éxito al intentar ingresar con dicho usuario y contraseña