Post37 nn

Desarrollo de herramienta Brute Force para aplicaciones web con Python


Perfil
Samuel Esteban

El día de hoy veremos en detalle el poder que tiene el lenguaje de programación Python para desarrollar herramientas de Seguridad. Python es un lenguaje potente, ya que a través de él, podemos desarrollar poderosas herramientas con solo unas pocas líneas de código.

En este documento no veremos “cómo aprender a programar”, si no que realizaremos algunos ejemplos, los que requieren que domines la lógica de la programación.

Python trabaja con módulos, lo cuales permiten importar ciertas funciones quepermiten acelerar procesos y optimizar el desarrollo de herramientas. Algunos de los módulos más importantes para desarrollar herramientas de Seguridad son:


Módulo Requests,  Urllib, Urllib2: Permiten interactuar con aplicaciones web. Trabajar con Métodos GET, POST, etc.

Módulo BeautifulSoup: Permite leer estructuras HTML / XML para extraer datos.

Módulo Re: Permite realizar búsquedas sobre expresiones regulares.

Módulo Socks: Permite realizar conexiones entre Cliente/Servidor.

Módulo Mechanize: Permite emular un browser de forma programática.

Módulo Cookielib: Permite manejar cookies de sesión y de esta manera poder trabajar directamente con la sesión del usuario.

Módulo Selenium: Interactúa con un Browser (Chrome, Firefox) para ejecutar tareas designadas.

Scrapy: Framework escrito en Python, orientado al proceso de descubrimiento de directorios, archivos. (Crawling).      

A través del desarrollo del documento trabajaremos con la versión 2.7 de Python.

Escenario de Pruebas:

Tenemos el siguiente panel de administración de WordPress.

Panel de administración de WordPress


Lo que queremos realizar en este escenario es nuestra propia herramienta automatizada para realizar ataques de fuerza bruta contra este CMS. En primer lugar debemos enumerar los usuarios de WordPress a través de la técnica  http:// 192.168.1.10/comercio/ /?author=n, donde n es un número, 1,2,3….,etc), o podemos utilizar herramientas automatizadas como por ejemplo Wpscan o CMSmap.

En este caso el usuario detectado es backtrackacademy. A continuación necesitamos extraer datos de los campos Username y Password, para ello posicionamos el puntero del mouse en el campo Username, hacemos click derecho y luego click en la opción inspeccionar elemento. Esto nos devolverá lo siguiente:


Datos del formulario de login


Como es posible observar el nombre del campo Username es log, y el nombre del campo Password es pwd. Esto es muy importante para desarrollar una herramienta de fuerza bruta.

En este caso utilizaremos el módulo requests para trabajar.

#!/usr/bin/python
#definimos el módulo
import requests


Ahora lo que necesitamos hacer en primer lugar es capturar la trama del HTTP POST para saber cuál es la URI que necesitaremos para trabajar con los intentos de conexión, para ello utilizaremos el plugin de Firefox Live HTTP Headers. Una vez instalado este plugin lo abrimos y agregamos cualquier credencial en el formulario de WordPress y le damos a Log In.

Trama HTTP POST

Tenemos que nuestra trama POST es http://192.168.1.10/comercio/wp-login.php,  y abajo tenemos las variables que son enviadas en la trama, sin embargo solo necesitaremos las dos variables detectadas con anterioridad.

Ahora siguiendo con el script necesitamos un diccionario, el cual servirá para ir probando palabra por palabra y de esta manera ver si podemos establecer una una sesión válida. Para ello creamos nuestro propio diccionario de forma manual o podemos utilizar la herramienta Cupp, la cual es muy buena para la creación de diccionarios.

#!/usr/bin/python
import requests
#abrimos nuestro diccionario
wordlist = open("wordlist.txt","r")
#creamos un ciclo for para iterar por cada palabra del diccionario
for word in wordlist.readlines():
            #creamos una variable con los datos del POST
data ={
'log':'backtrackacademy',
'pwd':word.strip("\n")
}
           #generamos una conexión por POST con los datos de wordpress
           r = requests.post("http://192.168.1.10/comercio/wp-login.php", data=data, allow_redirects=False)

Y la pregunta que quizás nos hacemos en estos momentos, ¿Cómo detectamos que se logró establecer una sesión exitosa?. Esto lo podemos determinar a través de los códigos HTTP. Un código HTTP corresponde a la respuesta que retorna el servidor en la base a la consulta realizada por el cliente, por ejemplo, cuando realizamos una conexión al sitio web https://www.backtrackacademy.com el servidor nos devuelve un código HTTP 200, ya que se estableció una comunicación de forma correcta con el servidor, cuando generamos una conexión con un recurso inexistente como por ejemplo  https://www.backtrackacademy.com/cualquiercosa ,el servidor nos devuelve un código 403 o 404, por otra parte cuando se generá una redirección el código de respuesta es un 301, 302.

Si llevamos esto a nuestro script, primero sabemos que siempre generaremos una conexión válida contra el servidor, por esto el código que siempre nos devolverá el servidor será un 200 (esto aplicará para todas las conexiónes con credenciales inválidas).  Sin embargo si generamos una conexíon válida con credenciales se producirá un redireccionamiento, ya que lógicamente la conexión válida nos llevará a otro recurso, por ende la lógica de esto es, si se generá un código HTTP 301 o 302, las credenciales serán válidas. Volvamos a nuestro script.


#!/usr/bin/python


import requests


#abrimos nuestro diccionario

wordlist = open("wordlist.txt","r")


#creamos un ciclo for para iterar por cada palabra del diccionario

for word in wordlist.readlines():


            #creamos una variable con los datos del POST

data ={

'log':'backtrackacademy',

'pwd':word.strip("\n")

}


           #generamos una conexión por POST con los datos de wordpress

           r = requests.post("http://192.168.1.10/comercio/wp-login.php", data=data, allow_redirects=False)


          #a continuación crearemos una sentencia if, la cual nos indicará que si el código http de la conexión es 301 o 302 se habrán detectado las credenciales válidas, en caso contrario, que muestre por pantalla un mensaje con las credenciales inválidas, para tener un status del procedimiento.

          if r.status_code in [301,302]:

print "Las credenciales: backtrackacademy y %s son validas" %(word.strip("\n"))

break

else:

print "Las credenciales: backtrackacademy y %s son invalidas" %(word.strip("\n"))




Finalmente probamos nuestro script para ver como funciona, y el resultado es el siguiente:

Script brute force

Como es posible visualizar, el script ha funcionado perfectamente, este script puede ser funciona para TODOS los formularios de login, excepto obviamente si la aplicación posee un captcha, no será posible realizar este ataque, a menos que el captcha se vulnerable a OCR.

Como dato final y para que comprendan más lo del código HTTP ahora estableceremos la conexión a través del intérprete de Python.

Conexión al servidor con credencial inválida

Aquí generamos una conexión al servidor con una credencial inválida, de esta manera el servidor nos devuelve un código HTTP 200. Ahora haremos lo mismo pero con la credencial válida detectada.

Conexión al servidor con credencial válida

Acá podemos visualizar que al generar una conexión con credenciales válidas, nos retorna un código HTTP 302. De esta manera se puede observar de una forma más clara la conexión que tiene la aplicación web con el servidor.




Artículos que te pueden interesar


Hace unos dias los creadores de Kali Linux han lanzado la nueva version de su sistema operativo que podemos encontrar desde el siguiente enlace ... Omar Jacobo Muñoz Veliz


Continuar Leyendo

H-c0n es una de las conferencias mas grandes en españa que reune a los mejores hacker de la región, un lugar donde abunda el compartir conocimie... Omar Jacobo Muñoz Veliz


Continuar Leyendo

Un atacante puede hacer uso de formularios no sanitizados para hacer cargas de Shell, y así poder ejecutar comandos remotos desde su equipo a un... Cristian Jose Acuña Ramirez


Continuar Leyendo