Publicado el 9 de Junio del 2018
1.013 visualizaciones desde el 9 de Junio del 2018
1,9 MB
57 paginas
Creado hace 11a (05/05/2012)
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Entendamos y Practiquemos
MySQL Injection
By RevangelyonX
1
Entendamos y Practiquemos MySQL Injection - RevangelyonX
IMPORTANTE:
Si ya te has leído el documento y buscas algo en el índice; o bien ya sabes de que va el tema,
perfecto se presenta a continuación.
Si no te has leído el documento, te propongo que lo leas ignorando el índice
ÍNDICE:
02
02
02
02
08
14
19
29
37
40
49
INTRODUCCION
NIVEL DEL DOCUMENTO
BASE
EJEMPLO 1
EJEMPLO 2
EJEMPLO 3
EJEMPLO 4
EJEMPLO 5 – PRUEBA REAL
BLIND SQL INJECTION
EVADIENDO FILTROS
EJEMPLO 6 – PRUEBA REAL, BLIND SQL INJECTION
2
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Introducción:
Después de mucho tiempo, he decidido escribir un documento base referente a los ataques
SQL Injection, aún sabiendo que hay muchísima información en internet sobre esto.
Lo que haré será darle un enfoque progresivo.
Nivel del documento:
En este documento se tratará de tocar varios niveles, desde lo básico, hasta algo más
avanzado.
Base:
No voy a entrar en una teoría profunda referente al tema, doy por entendido, que la gente
sabe qué es SQL y para qué sirve.
De todos modos, para poder realizar ataques SQL Injection, hay que conocer una base
referente al lenguaje SQL y algún lenguaje de programación web como PHP.
En este documento, realizaré todos los ataques en local (preparando mis propias páginas
vulnerables) y quizá, conforme escriba, acabe haciendo alguna práctica real.
¿Cómo funciona este ataque?
La mayoría tendréis una mínima idea, este ataque, tal y como lo indica su nombre, se basa en
inyectar una sentencia SQL nuestra, para que la ejecute el servidor objetivo. Entenderemos la
funcionalidad según pase el documento.
EJEMPLO 1
Programación base:
Hagamos una prueba muy rápida de cómo funcionan las consultas:
3
Entendamos y Practiquemos MySQL Injection - RevangelyonX
<?php
?>
/*script PHP para pruebas sql*/
$buscar=@$_GET['buscar'];
if (!empty($buscar)){
} else {
}
mysql_connect("localhost","root","");
mysql_select_db("test1");
$sentenciaSql="SELECT * FROM diccionario WHERE termino LIKE '%".$buscar."%'";
$query = mysql_query($sentenciaSql);
while ($resultado=mysql_fetch_assoc($query)){
}
echo $resultado['Termino']."=".$resultado['Definicion']."<br/>";
echo "<form action='' method='get'>
";
</form>
Palabra: <input type='text' name='buscar'/><br/>
<input type='submit' value='Buscar Palabra'/>
Explicación base del script en PHP:
El script recupera por GET (mal hablando: URL) una variable “buscar”.
Si está vacía, significa que no hemos buscado ninguna palabra y por lo tanto muestro el
formulario (el else del código) en cambio, si no está vacía, hacemos una query:
SELECT * FROM diccionario WHERE termino LIKE ‘%variableEscrita%’;
Si analizáis el código PHP, veréis que hago un mysql_fetch_assoc(), esto crea un array con el
resultado de la query, donde el índice sea el nombre del campo de la base de datos
$resultado[‘Termino’]
$resultado[‘Descripcion’]
4
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Ejemplo:
Y si escribimos wo:
Modificaremos el script PHP para ver la query que hace contra la base de datos para ver que
fallos podríamos encontrar.
Añadimos esta parte.
echo $resultado['Termino']."=".$resultado['Definicion']."<br/>";
De modo que al hacer otra consulta podemos ver lo siguiente.
$query = mysql_query($sentenciaSql);
echo "<br/>Realizando la query: ".$sentenciaSql.": <br/>";
while ($resultado=mysql_fetch_assoc($query)){
}
Hasta aquí perfecto.
Entendemos entonces, que parte de la sentencia SQL la creamos nosotros (con la variable
$buscar) y por lo tanto, la manipulación del ataque consiste en escribir parte de código SQL en
esta variable (en el input del formulario o bien en la URL).
5
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Si buscáis documentos de SQL Injection, veréis las SQL típicas:
1 or 1=1/*
…
Bien, veamos que ocurre en este caso con una inyección típica (por comodidad, he modificado
un poco el script PHP para tener más visibildad de la respuesta, etc.):
En este caso no nos muestra resultados pero tampoco un error.
Si observamos la query que genera (el “#” es un comentario SQL) es normal que no nos
muestre ningún dato, puesto a que no hay ningún termino en la tabla diccionario con esos
“caracteres”. Quizá podría funcionar con otro tipo de sentencia (siendo un id, y “=” y no un
“LIKE”) pero de todos modos, no significa que no sea vulnerable.
¿Cómo saber si es vulnerable?
Bien, intentemos cortar la sentencia añadiendo una comilla simple:
6
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Al añadir la comilla simple, la query queda xxxxxxxx like ‘%’%’
Y esto, realmente es un error de SQL ya que no es correcto a nivel sintáctico. De hecho, si
añadimos al script PHP que nos muestre los errores MySQL veremos el problema:
El error es el número 1064, este es un error de sintaxis, quiere decir que nos hemos
“equivocado” lanzando la query contra la base de datos.
Es muy importante entender este concepto.
Bien, vamos a intentar que nos muestre dos resultados.
Para que ocurra esto, sabemos que la query debe de quedar así:
7
Entendamos y Practiquemos MySQL Injection - RevangelyonX
SELECT * FROM diccionario WHERE termino LIKE ‘%wo%’ or termino LIKE ‘%ex%’;
Por lo tanto, nosotros deberíamos de inyectar algo parecido a:
wo%’ or termino LIKE ‘%ex
De esta manera, al “unirlo” con la parte predefinida por el script, la query quedará como
deseamos. Hagamos la prueba:
Nota: Me estoy dando cuenta que si copiáis literalmente las sentencias del documento, no funcionará porque las
comillas simples me las transforma a un acento, así que lo escribís a mano y todo ok ;).
Bien, como podéis ver, hemos inyectado perfectamente la SQL.
Esta es la base de una inyección (no el ejemplo, pero sí la teoría) y es estrictamente necesaria
entenderla para poder seguir hacia delante
EJEMPLO 2
A continuación, haré un ejemplo de un login. No todas las SQL Injections se basan en un login,
pero también es interesante conocer está opción.
Me preparo un script en PHP que tenga un login.
8
Entendamos y Practiquemos MySQL Injection - RevangelyonX
/*script PHP para pruebas sql*/
$username=@$_GET['username'];
$password=@$_GET['password'];
if (!empty($password) and !empty($username)){
mysql_connect("localhost","root","");
mysql_select_db("test1");
<?php
password='".$password."'";
".$resultado['password']."<br/><br/>";
?>
}
}
$sentenciaSql="SELECT username,password FROM user WHERE username='".$username."' AND
echo "<hr/><h2>Errores Mysql: </h2><br/>";
echo "<u>".mysql_errno().": ".mysql_error()."</u><hr/>";
$query = mysql_query($sentenciaSql);
/*añadimos que nos muestre los errores Mysql*/
if (mysql_errno()!=0){
}
echo "<br/>Realizando la query: ".$sentenciaSql.": <br/><br/><br/>";
echo "<h2>Resultado de la búsqueda: </h2>";
while ($resultado=mysql_fetch_assoc($query)){
echo "Hola ".$resultado['username']." tu password es
echo "<form action='' method='get'>
";
</form>
Username: <input type='text' name='username'/><br/>
Password: <input type='text' name='password'/><br/>
<input type='submit' value='Login'/>
Básicamente lo que hace este script, es recuperar el username y el password escrito el en
form, si alguno de los dos no se ha escrito, vuelve a mostrar el formulario. Si se han
completado los datos correctamente en el formulario, entonces vamos a buscar el username y
el password que coincidan con el escrito a la base de datos:
9
Entendamos y Practiquemos MySQL Injection - RevangelyonX
He creado un usuario invitado de prueba, sólo para que podáis ver cual es el resultado y cual
es la query que realiza.
Veamos aquí, si inyectamos una de las famosas easy injection de tutoriales básicos:
1’ or ‘1’=’1
Pero, porque? Bien fijaros en la query arriba, la condición es:
Where username=’1’ or ‘1’=’1’ and password=’1’ or ‘1’=’1’
Si sabéis algo de los tipos booleanos, esto viene a decir:
10
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Where falso or true and falso or true
Al ser una disyunción lógica, siempre que haya un true, el valor será true y por lo tanto queda:
Where falso or true or true, lo que viene a ser:
Select username, password from user where true
Esta query, ejecutada en la base de datos directamente:
De hecho, podríamos inyectar lo siguiente:
De manera que nos devuelve esto:
11
Entendamos y Practiquemos MySQL Injection - RevangelyonX
Fijaros en la query:
Select………. Where username=’1’ or true#’xxxxxxx
El hecho que ponga un “#” implica que el MySQL ignorará lo que vaya después (puesto que lo
estamos comentando) así que la query queda: (Dependiendo de la versión Mysql puede variar
“/*”,” --“ por ejemplo)
SELECT…… where username=’1’ or true
Al tener un valor lógico true, la query devolverá en realidad.
Select username,password from user;
Por lo tanto se nos listan todos los usuarios (esto es debido a una mala programación
PHP(while), luego veremos porqué).
MEJORANDO NUESTRO CÓDIGO
¿Pero siempre es tan fácil?
En realidad, el nivel de facilidad en explotar una vulnerabilidad, es proporcional al nivel de
conocimientos de programación y de pre
Comentarios de: Entendamos y Practiquemos MySQL Injection (0)
No hay comentarios