domingo, 25 de enero de 2015

Python, Basic http authentication y un ejemplo útil.

Basic HTTP authentication es un método mediante el cual nos autenticamos en un servidor web usando usuario y contraseña, siendo está enviada en las cabeceras HTTP. Viene especificado en el RFC 2617 http://tools.ietf.org/html/rfc2617


El funcionamiento es el siguiente, accedemos a una página web, en la respuesta del servidor añade la cabecera: 
                            WWW-Authenticate: Basic realm=""




posteriormente el cliente deberá incluir en la cabecera HTTP:
                 Authorization: Basic dXNlcmVqZW1wbG86cGFzc3dvcmRlamVtcGxv
Siendo dXNlcmVqZW1wbG86cGFzc3dvcmRlamVtcGxv el usuario:contraseña codificado en base64. Obviamente, este es un sistema de autenticación muy básico, el cual no se recomienda usar a día de hoy. Un atacante mediante un ataque MITM podría obtener las credenciales del usuario que se esta autenticando en el sistema fácilmente. Simplemente decodificando la cadena en base64, obtendría su contraseña.

Bien, el ejemplo que he realizado, es para autenticarnos de esta forma en un router de Movistar, que usa este sistema de autenticacón. La herramienta en cuestión esta creada para que además de autenticarse, cambie la IP pública actual que tenemos, osea, nos desconectará de la Red y nos volverá a conectar, obteniendo una nueva dirección IP (siempre y cuando tengamos una IP dinámica, obviamente).


#!/usr/bin/env python

import requests
from requests.auth import HTTPBasicAuth
from bs4 import BeautifulSoup
import time

class RouterMovistar:
 def __init__(self,user,password):
  self.user = user
  self.password = password

 def getActualIp(self):
  req = requests.get('http://192.168.1.1/admin/status.asp', auth=HTTPBasicAuth(self.user, self.password))
  soup = BeautifulSoup(req.text)
  tabla = soup.find('table',width=600).find_all('tr')
  data = []
  for i in tabla:
          tds = i.find_all('td')
          for x in tds:
                  test = x.text
                  data.append(test)
  return data[19]

        def getActualGateway(self):
                req = requests.get('http://192.168.1.1/admin/status.asp', auth=HTTPBasicAuth(self.user, self.password))
                soup = BeautifulSoup(req.text)
                tabla = soup.find('table',width=600).find_all('tr')
                data = []
                for i in tabla:
                        tds = i.find_all('td')
                        for x in tds:
                                test = x.text
                                data.append(test)
                return data[20] 

 def disconnectIp(self):
  payload = { 'submitppp0':'Disconnect',
        'submit-url':'/admin/status.asp'}
  headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain","User-Agent": 'Sinkmanu :)'}
  req = requests.post('http://192.168.1.1/goform/admin/formStatus',auth=HTTPBasicAuth(self.user, self.password),headers=headers,data=payload)
  

        def connectIp(self):
                payload = { 'submitppp0':'Connect',
                             'submit-url':'/admin/status.asp'}
                headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain","User-Agent": 'Sinkmanu :)'}
                req = requests.post('http://192.168.1.1/goform/admin/formStatus',auth=HTTPBasicAuth(self.user, self.password),headers=headers,data=payload)
                

  


# Main 

test = RouterMovistar('adsl','realtek') # set username and password (by default. WTF)

actualIP = test.getActualIp()
print "[*] IP Actual: \t\t",actualIP
print "[*] Gateway: \t\t",test.getActualGateway()
print "[*] Discconecting..."
test.disconnectIp()
print "[*] Connecting..."
test.connectIp()
newIP = test.getActualIp()
time.sleep(2)
while actualIP == newIP:
 test.disconnectIp()
 print "[*] Refreshing.."
 time.sleep(2)
 test.connectIp()
 newIP = test.getActualIp()
print "[*] New IP: \t\t",test.getActualIp()
print "[*] New Gateway: \t",test.getActualGateway()

 



 
:-)