Un poco de código para extraer información mediante un script en python , algo básico, para empezar a familiarizarme con las librerías disponibles en Kali.
Las librerías usadas:
- urllib2 para descargar el código html de una pagina web
- beutifulsoup para extraer los enlaces que contiene
- urlparse para validar que los enlaces sean validos y extraer el hostname
- finalmente, la libreria dns para extraer la IP de los nombres de dominios obtenidos
url_extractor.py
# pylint: disable-msg=C0301 ''' apt-get install html5lib apt-get install python-beautifulsoup apt-get install python-lxml apt-get install python-pyquery http://yuji.wordpress.com/2008/05/14/python-basics-of-python-dictionary-and-looping-through-them/ http://stackoverflow.com/questions/493819/python-join-why-is-it-string-joinlist-instead-of-list-joinstring ''' from utils import utils def main(): ''' para que pylint no muestre tantos mensajes =) http://stackoverflow.com/questions/709490/python-code-convention-using-pylint ''' url = "www.google.com" html = utils.HtmlExtractor(url) #aseguramos que url siempre comienze por http:// o https:// url = html.get_url() #print html.get_body() data_extractor = utils.DataExtractor(html.get_body(), url, only_href = True) urls = data_extractor.get_urls() print "URLS: " for temp in urls: print temp domains = data_extractor.get_domains(urls) print "Dominios: " for temp in domains: print temp ips = data_extractor.get_ips_for_domains(domains) for key in ips.iterkeys(): print key, ": ", " ".join(ips[key]) if __name__ == "__main__": main()
utils/utils.py
''' http://docs.python.org/library/urlparse.html http://docs.python.org/tutorial/errors.html http://docs.python.org/library/urllib2.html http://docs.python.org/library/urllib2.html#urllib2.Request http://www.crummy.com/software/BeautifulSoup/documentation.html http://blog.elcodiguero.com/python/23-eliminar-duplicados-lista.html http://www.mail-archive.com/dnspython-users@dnspython.org/msg00006.html http://www.dnspython.org/examples.html http://docs.python.org/release/2.5.2/lib/typesmapping.html ''' from urlparse import urlparse import urllib2 import BeautifulSoup import dns.resolver def valida_url(url): ''' @param url: @type url: ''' #si la url no empieza por http temp https lo anexa al inicio if url[:7].lower() != "http://" or url[:8].lower() != "https://": url = "http://" + url #verificamos que es una url completa, es decir, contiene al hostname temp = urlparse(url) if temp.hostname is None: url = None return url # pylint: disable-msg=W0232 class _MyRedirects(urllib2.HTTPRedirectHandler): ''' Clase de redireccion ''' # pylint: disable-msg=C0301,R0913,C0111 def http_error_301(self, req, fpc, code, msg, headers): print code, " http_error_301 ", headers['Location'] return urllib2.HTTPRedirectHandler.http_error_301(self, req, fpc, code, msg, headers) # pylint: disable-msg=C0301,R0913,C0111 def http_error_302(self, req, fpc, code, msg, headers): print code, " http_error_302 ", headers['Location'] return urllib2.HTTPRedirectHandler.http_error_302(self, req, fpc, code, msg, headers) # pylint: disable-msg=C0301,R0913,C0111 def http_error_303(self, req, fpc, code, msg, headers): print code, " http_error_303 ", headers['Location'] return urllib2.HTTPRedirectHandler.http_error_303(self, req, fpc, code, msg, headers) # pylint: disable-msg=C0301,R0913,C0111 def http_error_307(self, req, fpc, code, msg, headers): print code, " http_error_304 ", headers['Location'] return urllib2.HTTPRedirectHandler.http_error_307(self, req, fpc, code, msg, headers) class HtmlExtractor(object): ''' Clase que extrae el codigo HTML de un origen. ''' def __init__(self, url): ''' @param url: URL completa, no acepta rutas relativas o absolutas @type url: string ''' self.follow_redirects = False self.html_body = None self.url = valida_url(url) if self.url is None: raise ValueError("URL No valida") def get_url(self): ''' retorna la url parseada, por ejemplo: para www.google.com.pe retorna http://www.google.com.pe ''' return self.url def get_body(self, follow_redirects = False): ''' Retorna el html resultante de la peticion. @param follow_redirects: En caso de estar seteado a verdadero, interpreta los mensajes HTTP 301, 302 @type follow_redirects: boolean ''' self.follow_redirects = follow_redirects request = urllib2.Request(self.url) opener = urllib2.build_opener(_MyRedirects()) content = opener.open(request) self.html_body = content.read() return self.html_body class DataExtractor(object): ''' Clase para extraer Datos de un html. url -- direccion desde la cual se extrajo el html, opcional si se desea que se interpreten las rutas relativas o absolutas que se puedan encontrar en el html only_href -- Solamente devuelve el contenido de los href, el texto entre las etiquetas no necesariamente puede coincidir con el valor ''' def __init__(self, html_body, url = None, only_href = False): self.html_body = html_body self.url = url self.only_href = only_href self.urls = [] self.domains = [] self.domain_ips = {} def get_urls(self): ''' devuelve todas las URL encontradas en el html analizado ''' result = BeautifulSoup.BeautifulSoup(self.html_body) lst_tag = result.findAll("a") for c_url in lst_tag: self.urls.append(c_url["href"]) return self.urls def get_domains(self, urls = None): ''' @param urls: Listado de urls a extraer los dominios, es la informacion devuelta por get_urls() @type urls: list ''' if urls is None: self.urls = self.get_urls() for url in urls: temp = urlparse(url) if temp.hostname is None: continue self.domains.append(temp.hostname) return dict.fromkeys(self.domains).keys() def get_ips_for_domains(self, domains = None): ''' @param domains: Listado de dominios a extraer los IP, es la informacion devuelta por get_domains() @type domains: list ''' if domains is None: self.domains = self.get_domains() for domain in domains: answer = dns.resolver.query(domain, 'A') temp = [] for rdata in answer: temp.append(rdata.address) self.domain_ips[domain] = temp return self.domain_ips
No hay comentarios.:
Publicar un comentario