Archive

Posts Tagged ‘python hacking’

XSScrapy para procesos de crawling e identificación de vulnerabilidades

marzo 12, 2015 Deja un comentario

Scrapy es un framework que cuenta con varias utilidades para crear spiders y crawlers, se ha vuelto bastante popular y en cada nueva versión es mucho más estable y robusto. Hace algún tiempo comentaba en un vídeo de la serie de Hacking con Python los elementos que a mi parecer eran los más interesantes de Scrapy y cómo se puede utilizar desde cualquier script en Python. Dado que este tipo de actividades casi siempre suelen ir de la mano con procesos de minería y extracción de datos, a lo mejor no resulta tan llamativo para un pentester/hacker (o si), pero cuando hablamos de ejecutar un proceso de crawling no solo para extraer información, sino para detectar vulnerabilidades en aplicaciones web, seguro que más de uno comienza a ver que se pueden hacer cosas muy interesantes.
Si has visto como funciona un spider y la cantidad de elementos involucrados en un proceso de crawling, casi seguro que alguna vez te habrás preguntado ¿Y cómo puedo utilizar esto para ejecutar tareas de pentesting? Creo que es una pregunta bastante lógica, ya que además de visitar enlaces y analizar la estructura de un sitio web, también estás jugando con cabeceras HTTP, parámetros en el cuerpo de la petición o directamente en la URL, formularios, diferentes tipos de “content-types” y un largo etc. Son muchas las posibilidades que tienes a tu disposición.
Ahora bien, imaginar por un segundo que esto lo aplicamos no solamente a aplicaciones web en Internet, sino también a servicios ocultos del tipo HTTP en la red de TOR. A mi personalmente me ha parecido una idea de lo más interesante y ahora mismo me encuentro desarrollándola para la próxima versión Tortazo, algo de lo que pienso hablaros en un próximo articulo.

Si quieres utilizar Scrapy directamente y realizar pruebas de pentesting contra todos los enlaces encontrados y procesados por un Spider, no hay demasiados impedimentos para hacerlo, sin embargo existe una herramienta que ya lo hace por ti, dicha herramienta es XSScrapy.

  1. Instalación y uso de XSScrapy

XSScrapy es una aplicación fácil de instalar y de usar, como ya os imaginaréis se basa en Scrapy y permite encontrar vulnerabilidades del estilo XSS (tanto reflejado como almacenado) y también vulnerabilidades del tipo SQLi. El proyecto se encuentra alojado en el siguiente repositorio de GitHub https://github.com/DanMcInerney/xsscrapy y para instalarlo basta con utilizar el comando “pip” junto con el fichero de dependencias.

>git clone https://github.com/DanMcInerney/xsscrapy.git && cd xsscrapy

>pip install -r requirements.txt

A continuación se puede comenzar a probar la aplicación, que sobresale por su simplicidad.

>./xsscrapy.py -h

usage: xsscrapy.py [-h] [-u URL] [-l LOGIN] [-p PASSWORD] [-c CONNECTIONS]

[-r RATELIMIT] [–basic]

optional arguments:

-h, –help show this help message and exit

-u URL, –url URL URL to scan; -u http://example.com

-l LOGIN, –login LOGIN

Login name; -l danmcinerney

-p PASSWORD, –password PASSWORD

Password; -p pa$$w0rd

-c CONNECTIONS, –connections CONNECTIONS

Set the max number of simultaneous connections

allowed, default=30

-r RATELIMIT, –ratelimit RATELIMIT

Rate in requests per minute, default=0

–basic Use HTTP Basic Auth to login

Evidentemente la opción que resulta más interesante es en la que se puede definir la URL (-u/–url) del objetivo y a partir de allí, comenzar a ejecutar el procesamiento de enlaces y peticiones/respuestas HTTP. Otra opción interesante es la que permite establecer el número de conexiones simultaneas máximo contra el sitio web en cuestión (-c/–connections) algo que resulta muy practico para evitar que un WAF detecte el ataque y bloquee las peticiones desde la IP donde se realizan. Además, en el caso de que el sitio web requiera autenticación (digest o basic) es posible indicar un usuario y una contraseña con los interruptores -l y -p.
Ahora que tenemos una imagen general del funcionamiento del programa, podemos comenzar a utilizarlo con una aplicación web vulnerable. Existen aplicaciones web para realizar pruebas de penetración de todos los gustos y colores, algunas de ellas ya las he mencionado y explicado en varias ocasiones en este sitio, tales como DOJO InsecureWebApp, Hacme Casino, DVWA (Damn Vulnerable Web Application), WebGoat, etc. En esta ocasión vamos a utilizar Django-Moth, una aplicación web vulnerable escrita en Django que puedes descargar libremente desde aquí: https://github.com/andresriancho/django-moth pero si lo prefieres puedes utilizar cualquier otra, a efectos prácticos da un poco igual.

Después de descargar el proyecto del repositorio GitHub, se puede iniciar la aplicación Django de la siguiente forma:

>python manage runserver 8080

Performing system checks…

System check identified no issues (0 silenced).

February 18, 2015 – 17:05:08

Django version 1.7.1, using settings ‘djmoth.settings’

Starting development server at http://127.0.0.1:8080/

Quit the server with CONTROL-C.

El puerto por defecto es el 8000, pero como se puede apreciar se puede cambiar por cualquier otro. Recordar que se trata de una aplicación web con vulnerabilidades fáciles de explotar, evitar utilizarla en Internet y mucho menos, utilizar un puerto como el 80 que requiere privilegios de root.

Todas las vulnerabilidades de Django Moth se encuentran separadas por secciones, pero aun así, el crawler de XSScrapy, a la fecha de redactar este articulo, no permite establecer reglas para indicar en qué momento debe detenerse el ataque y cuales son los enlaces que se permite visitar. Tal falta de control es un problema a la larga, ya que muchas páginas tienen enlaces a otros dominios y es fácil que el proceso recursivo termine llevando al crawler a sitios que no deberían analizarse, así que hay que estar atentos a las trazas que arroja el programa en todo momento. Ahora se puede ejecutar algo como lo siguiente:

./xsscrapy.py -u http://localhost:8080/audit/os_commanding/blind_osc.py?cmd=ls

Se podrán ver varias trazas y los elementos que la herramienta va analizando en cada iteración. En el caso de interrumpir el proceso manualmente o que termine debido a que ya se han recorrido todos los enlaces, se genera automáticamente un fichero con nombre: “xsscrapy-vulns.txt” el cual contiene todos los resultados encontrados. Incluye cosas como las vulnerabilidades encontradas, puntos de inyección, parámetros utilizados, la petición y respuesta del servidor, etc.

Una herramienta interesante con mucho potencial y aunque a mi juicio se puede explotar mucho más el framework de Scrapy, puede resultar muy instructiva para aprender detalles avanzados del framework, eso si, solamente si estas dispuesto a ver el código y entender cómo funciona, algo que desde luego te recomendaría ya que tiene detalles técnicos muy valiosos y que te ayudarán a aprender ciertos “trucos” a la hora de crear tus propias herramientas.

Un saludo y Happy Hack!
Adastra.

Procesamiento del lenguaje natural con NLTK para Ingeniería social automatizada

febrero 17, 2015 3 comentarios

En una entrada anterior os hablaba de un proyecto que llevo estudiando desde hace algún tiempo para el análisis de emociones, dicho proyecto es “wefeelfine” y tal como os comentaba, cuenta con una API Rest que permite realizar varios tipos de consultas para obtener un listado de sentimientos recolectados en Internet. La recolección de datos que realiza dicha plataforma se basa en la ejecución de varios procesos de crawling para extraer y almacenar información de múltiples sitios en Internet, sin embargo, una de las cosas que más me ha llamado la atención es el procesamiento de los textos y las funciones utilizadas para determinar la polaridad de dichas palabras. La complejidad de un proceso de “stemming” (derivación y combinaciones de palabras) sobre el lenguaje natural no es una tarea sencilla, especialmente cuando hablamos de las características propias de cada lenguaje, al final ocurre que solamente nos podemos centrar en un conjunto limitado de lenguajes, tal como ocurre en “wefeelfine” que solo procesa los textos escritos en ingles y en castellano, aunque este último con bastantes deficiencias. Si estás pensando en desarrollar un proceso de minería de datos sobre alguna red social como Twitter, Facebook o cualquier otro sitio web en Internet, lo más probable es que te interese también extraer información útil a la que posteriormente le puedas aplicar algún tipo de análisis estadístico sobre marcas, tendencias o de carácter histórico/evolutivo. En cualquier caso, es necesario aplicar técnicas de “Procesamiento del lenguaje Natural” o NLP (Natural Lenguage Processing) por sus siglas en ingles, las cuales permiten aplicar patrones a un texto concreto y extraer información de interés (no confundir con NLP: Neuro-Linguistic Programming). Antes de continuar, viene bien explicar en qué consiste NLP y cómo se puede utilizar la librería NLTK en Python.

¿Qué es NLP?

Se trata de un conjunto de técnicas que permiten el análisis y manipulación del lenguaje natural. Dada la complejidad intrínseca que acompaña cualquier proceso de NLP, muchas de las técnicas automatizadas están relacionadas con el uso de la IA (Inteligencia Artificial) y las ciencias cognitivas. Para aplicar las técnicas más comunes en NLP, la librería NLTK (Natural Language Tool Kit) permite que cualquier programa escrito en lenguaje Python pueda invocar a un amplio conjunto de algoritmos que sustentan las principales técnicas de NLP para la generación de métricas, frecuencia de términos, polaridad negativa/positiva de frases y textos, entre otras muchas técnicas.
Existen algunos
términos comunes en NLP que se deben comprender antes de poder aplicar cualquier técnica y entender los resultados que arrojan, dichos términos resultarán de lo más lógicos, pero si no se tienen en cuenta a la hora de programar, pueden resultar confusas las funciones y resultados arrojados por NLTK.

Token: Se trata de la unidad más simple de procesamiento y representa una palabra en el texto.
Sentencia: Secuencia ordenada de tokens.
Tokenización: Se trata del proceso de segmentar una sentencia en cada uno de los tokens que la componen. Aunque puede ser un proceso simple para textos escritos en algunas lenguas, especialmente en el caso de las románicas cuyo token separador es un espacio, en otras lenguas como las altaicas, extraer los tokens de una sentencia es un proceso mucho más complejo debido a la sintaxis y semántica de los escritos en dichas lenguas.
Corpus: Cuerpo del mensaje que se encuentra compuesto por un conjunto de sentencias.
Part-of-speech (POS): Dependiendo de la semántica del lenguaje, cada token que compone una sentencia puede ser un verbo, un adjetivo, un pronombre, un articulo, etc. Un POS es simplemente una clasificación para cada token dentro de una sentencia, de esta forma es posible identificar el significado de cada token y las partes clave de cada sentencia.
Árbol: Todos los textos están compuestos por varias sentencias y cada sentencia tiene varios tokens con sus respectivos POS. Un árbol parseado incluye cada una de las dependencias de las sentencias y cada parte del texto. Es una forma de ordenar cada uno de los elementos del “corpus” de una forma que sea fácil de consultar.

Ahora que se ha expuesto la terminología básica, lo siguiente es conocer las principales técnicas definidas en un proceso NLP.

Etiquetado de POS: Una de las principales labores en un proceso de NLP, es identificar cada una una de las sentencias de un texto y clasificar cada uno de los tokens con sus correspondientes POS. Un “POS Tagger” es una rutina que se encarga de crear un diccionario con cada uno de dichos tokens y sus correspondientes POS. Por ejemplo, si la sentencia “El coche es rojo” es procesada por un POS Tagger el resultado es el siguiente: {“El” : AT , “coche” : NN , “es” : VB, “rojo” : JJ}
Donde cada POS asume los siguientes valores:
AT : Artículo
NN : Sustantivo
VB: Verbo
JJ: Adjetivo.

Parsers:
Un parser se encarga de producir un árbol de tokens con sus correspondientes POS partiendo de una sentencia determinada. Muchos de estos parsers depende un POS Tagger antes de poder generar un árbol.

Morfología:
Consiste en el proceso de catalogar cada token de una sentencia y extraer sus “morfemas” y “
raíces” para posterior análisis. Para comprender lo anterior, es necesario saber que cada token tiene una morfología que determina la estructura interna de la palabra. La morfología de una palabra puede dar lugar a nuevas palabras a partir de su morfema base y en todo caso, es importante diferenciar la morfología de la sintaxis de una palabra, ya que la morfología intenta determinar la estructura interna de las palabras, mientras que la sintaxis explica las normas para crear oraciones y textos.

Traductor:
Se trata de unas las principales aplicaciones de NLP, en la que partiendo de un texto escrito en un lenguaje determinado, es posible conseguir su traducción en otro lenguaje. Es una tarea compleja y requiere que el texto origen se encuentre correctamente
construido y cada bloque semántico del “corpus” se encuentre perfectamente redactado para conseguir una traducción legible en otro lenguaje. Google Traductor es uno de los servicios más completos y mejor implementados (que conozco) que utiliza parsers y POS Taggers avanzados para conseguir la traducción más exacta posible.

Instalación y uso básico de NLTK

La instalación del proyecto NLTK puede realizarse fácilmente utilizando PIP o easy_install.

sudo pip install -U nltk

Una dependencia opcional que también puede instalarse con PIP es numpy. Para verificar que ha quedado correctamente instalada, basta con importar el módulo ntlk y si no se aprecia ningún error, se puede asumir que el proceso de instalación ha ido bien.

Por otro lado, además de la librería también es necesario instalar una serie de ficheros y diccionarios con patrones para varios tipos de estructuras gramaticales llamados “corporas”, dichos ficheros se instalan de forma independiente por medio de un gestor de descargas que puede iniciarse utilizando el modulo nltk

>python
>>>import nltk
>>>nltk.download()


Invocando a “download” se abre una ventana en la que se pueden gestionar todos los ficheros “corpora” en diferentes
categorías. Si es la primera vez que se utiliza nltk, se realizará la descarga de dichos ficheros.
Los corpus principal
es que se suelen utilizar en el procesamiento de texto son conocidos como “gutenberg”, el cual incluye una selección de 18 textos del proyecto Gutenberg (http://www.gutenberg.org/) y contiene más de 1.5 millones de palabras. Para consultar los textos de gutenberg incluidos en el corpus de NLTK, se pueden ejecutar las siguientes instrucciones.

>>>from nltk.corpus import gutenberg

>>>print gutenberg.fileids()

['austen-emma.txt',

'austen-persuasion.txt',

'austen-sense.txt',

'bible-kjv.txt',

'blake-poems.txt',

'bryant-stories.txt',

'burgess-busterbrown.txt',

'carroll-alice.txt',

'chesterton-ball.txt',

'chesterton-brown.txt',

'chesterton-thursday.txt',

'edgeworth-parents.txt',

'melville-moby_dick.txt',

'milton-paradise.txt',

'shakespeare-caesar.txt',

'shakespeare-hamlet.txt',

'shakespeare-macbeth.txt',

'whitman-leaves.txt']

Ahora es el momento de comenzar a utilizar la librería y para ello, se puede utilizar el siguiente script, el cual se encarga de pintar por pantalla cada uno de los textos del proyecto gutenberg, el número de caracteres, el número de tokens, el número de sentencias y el número de veces que un item del vocabulario aparece en una sentencia.

from nltk.corpus import gutenberg
for fileid in gutenberg.fileids():
    num_chars = len(gutenberg.raw(fileid))
    num_tokens = len(gutenberg.words(fileid))
    num_sents = len(gutenberg.sents(fileid))
    num_vocab = len(set(w.lower() for w in gutenberg.words(fileid)))
    print str(num_chars) + " - " + str(num_tokens) + " - " + str(num_sents) + " - " + str(num_vocab)

Aunque se ha utilizado un corpus que se encuentra implementado en NLTK, también es posible utilizar uno propio y de hecho, es lo más común para realizar diferentes tipos de análisis sobre los datos de un texto. Para ello se pueden utilizar las clases PlaintextCorpusReader o BracketParseCorpusReader.

from nltk.corpus import PlaintextCorpusReader
import nltk
wordlists = PlaintextCorpusReader("/home/adastra/Escritorio/textos", '.*')
wordlists.words('prueba.txt')
print "Sentences: "+str(len(wordlists.sents()))
for sentence in wordlists.sents():
    tokens = nltk.word_tokenize(str(sentence))
    tagged_tokens = nltk.pos_tag(tokens)
    verbs = 0
    for tagged in tagged_tokens:
        token, tag = tagged
        if tag == 'VBP' or tag == 'VB':
            verbs += 1
    print "Tokens: "+str(len(tokens)) + " - Verbs: "+str(verbs)</td>

El script anterior lee el fichero “prueba.txt” que se encuentra en el directorio “/home/adastra/Escritorio/textos” y se encarga de contar el número de sentencias, el número de tokens por sentencia y los verbos de cada sentencia, los cuales están marcados con el tag “VBP” o “VB”.

Estas son solamente algunas de las características incluidas en NLTK y me dejo muchas, muchísimas cosas que se pueden hacer con esta librería y que entran en el campo de la lingüística y el análisis de datos.
Antes de terminar con este articulo, os indico brevemente un proyecto que utilizan NLTK y que cuenta con algunos servicios que pueden utilizarse por medio de peticiones HTTP planas. Dicho proyecto es “text-processing”. Desde la URL http://text-processing.com/demo/ pueden apreciarse 4 ejemplos del procesamiento de texto en lenguaje natural, siendo el más interesante, desde mi punto de vista, el que corresponde con el análisis de sentimientos. Como comentaba antes, dicho servicio se puede invocar directamente por medio de una petición HTTP utilizando el método POST, algo que se puede hacer con cualquier lenguaje de programación e infinidad de herramientas, entre las que se incluyen wget y curl.

>curl -d “text=spain is different” http://text-processing.com/api/sentiment/

{“probability”: {“neg”: 0.38781650900239895, “neutral”: 0.59783687451926548, “pos”: 0.61218349099760105}, “label”: “neutral”}

Como se puede apreciar, el parámetro “text” es el que incluye el texto que la plataforma debe procesar y el resultado es una estructura JSON con el porcentaje que indica qué tan “negativa”, “positiva” o “neutral” es la frase. En este caso, se ha enviado el texto “spain is different” y como se puede apreciar en el resultado, la plataforma determina que el texto es neutral, aunque el porcentaje de “positivismo” es del 61% frente a un 38% de “negatividad”. Al parecer, ni la plataforma, ni NLTK son capaces de distinguir la ironía.

Todo esto puede ser muy interesante para procesos automatizados de ingeniería social que permitan recolectar información de sitios en internet como Twitter o Facebook y determinen la polaridad de los mensajes de ciertas cuentas y además, determinar si las condiciones climáticas en la hora y lugar desde donde se publico el tweet han podido tener algún tipo de influencia.
Esta y otras ideas, se desarrollarán en mayor detalle en próximos artículos.

Un saludo y Happy Hack!
Adastra.

Tornado para rutinas de red asincronas y no bloqueantes

noviembre 27, 2014 1 comentario

“Tornado” es una librería para programas escritos en Python que permite crear sistemas asíncronos y no bloqueantes para operaciones de red, en donde cada petición ejecutada por los clientes puede ser asíncrona. La forma en la que se encuentra implementada la librería, permite escalar a varios miles de conexiones abiertas, algo que resulta ideal para aplicaciones que requieren conexiones con un tiempo de vida largo. Tornado no es una librería simple, de hecho es todo un framework para diferentes tipos de elementos de red, muy similar a Twisted, pero con la diferencia de que Tornado se centra en el desarrollo de componentes de red asíncronos y no bloqueantes y Twisted es un framework reactivo, centrado en el desarrollo de componentes de red que se activan ante diferentes eventos.
El modelo tradicional para crear aplicaciones tales como servidores web que soportan varios clientes de forma concurrente, se basa en un sistema “multi-hilo”, en el que se crea un nuevo hilo por cada cliente que se conecta al servicio. Esto da como resultado un consumo bastante alto de recursos del sistema y problemas de rendimiento que pueden ser bastante serios.
Un sistema “no-bloqueante” se basa en la ejecución de un único hilo de forma continua y que responde a las peticiones de cada cliente de forma asíncrona, de esta forma, el efecto de “bloqueo” de cada función se ve muy disminuido, ya que una función asíncrona retorna antes de finalizar. Por otro lado, últimamente se ha vuelto bastante popular el uso de librerías como Tornado o AsyncIO (de la que se hablará en una próxima entrada) no solamente en Python, sino en muchos otros lenguajes como Java, PHP o Javascript para implementar rutinas asíncronas y sistemas no bloqueantes. Es un modelo que ha ido cobrando fuerza por los beneficios que aporta un sistema que consume pocos recursos comparado con los sistemas clásicos, los cuales para manejar la concurrencia crean un nuevo hilo de ejecución por cada cliente.

Para instalar Tornado, basta con ejecutar el comando “pip install tornado” o descargar la última versión disponible en el repositorio GitHub (https://github.com/tornadoweb/tornado) e instalar manualmente con el script “setup.py”.
Uno de los ejemplos más básicos a la hora de usar Tornado, consiste en crear una aplicación web, para lo cual es necesario utilizar como mínimo tres elementos: una o varias clases del tipo “RequestHandler” para el procesamiento de las peticiones, uno o varios objetos del tipo “Application” para gestionar y enrutar adecuadamente las peticiones entrantes y finalmente, una función “main” que se encargará de iniciar el servidor. El siguiente es un ejemplo muy simple para crear un servidor web que procesa las peticiones “POST” de forma síncrona y las peticiones “GET” de forma asíncrona.

BasicTornadoWebServer.py

from tornado.ioloop import IOLoop
from tornado.web import RequestHandler, Application, url, asynchronous

class HelloHandler(RequestHandler):
    @asynchronous
    def get(self):
        self.write("Hello, world")

    def post(self):
        self.write("Hello, world")    

app = Application([ url(r"/", HelloHandler), ])
app.listen(9090)
IOLoop.current().start()

Como se puede apreciar, la clase “IOLoop” es la encargada de crear el hilo de ejecución que se encargará de procesar cada petición entrante por el puerto “9090”. Por otro lado, por defecto las funciones de una instancia de “RequestHandler” son síncronas, esto quiere decir que el hilo de ejecución principal será bloqueado hasta que la función retorne y en este caso, para implementar una función asíncrona, se debe utilizar el decorador “asynchronous”.
Se trata de un ejemplo muy simple y Tornado implementa muchas clases y funciones que permiten crear aplicaciones web asíncronas y con elementos tan interesantes como autenticación de usuarios, protección a CSRF o cookies seguras. Estos elementos serán analizados con mayor detalle en una próxima entrada, en esta nos centraremos en el uso de las utilidades incluidas en Tornado para networking.
Elementos y utilidades en Tornado para operaciones de red asíncronas
Tal como se ha visto antes la utilidad “tornado.ioloop” es el elemento principal para iniciar el hilo de ejecución en Tornado, no obstante no solamente se puede utilizar para crear un servidor HTTP que permita el procesamiento de peticiones, también es posible crear sockets TCP o UDP y responder a cada cliente de forma asíncrona. El siguiente es un ejemplo de cómo crear un servidor TCP básico con Tornado.


import errno
import functools
import socket
from tornado import ioloop, iostream
def connection(sock, filedes, event):
    while True:
        try:
            connection, address = sock.accept()
        except socket.error, e:
            if e[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
                raise
            return
        connection.setblocking(0)
        stream = iostream.IOStream(connection)
        stream.write("HTTP/1.1 200 OK\r\nHello!\r\n", stream.close)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(0)
sock.bind(("", 8080))
sock.listen(1000)
io_loop = ioloop.IOLoop.instance()
callback = functools.partial(connection, sock)
io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
try:
    io_loop.start()
except KeyboardInterrupt:
    io_loop.stop()
    print "exited cleanly"

Las primeras instrucciones que ejecuta el script anterior resultan bastante comunes para cualquier programador de Python que conoce el uso de los sockets, en este caso se está vinculando el puerto “8080” y posteriormente se utiliza una función de callback que será invocada automáticamente por la utilidad “IOLoop” cuando un cliente realice una petición al puerto 8080. La función de callback encargada de procesar cada conexión es “connection” y como se puede apreciar, recibe como argumento el socket servidor, el “file descriptor” y un listado de eventos producidos durante la conexión. Las primeras instrucciones de la función “connection” resultaran bastante comunes también, ya que lo primero que se hace es aceptar la conexión iniciada por el cliente. Posteriormente, se crea una instancia de la clase “iostream.IOStream” recibiendo como argumento la conexión del cliente. Este elemento de Tornado es lo que hace que este sencillo servidor TCP sea una rutina no bloqueante, ya que se encarga de gestionar de forma asíncrona las respuestas a todos los clientes que se conectan al servidor.

tornado1

La clase “tornado.iostream.IOStream” es una de las clases que extiende de “tornado.iostream.BaseIOStream”, la cual incluye las funciones básicas para leer y escribir datos en sockets no bloqueantes. Existen otras implementaciones tales como “iostream.SSLIOStream” o “iostream.PipeIOStream” que implementan características extendidas.

Por otro lado, el modulo “tornado.netutil” incluye varias funciones que son bastante útiles tanto para clientes como servidores. El uso de algunas de dichas funciones se enseña a continuación.

>>> from tornado import netutil
>>> sockets = netutil.bind_sockets(8000)
sockets [<socket._socketobject object at 0x7f067a1bf670>, <socket._socketobject object at 0x7f067a1bf6e0>]
>>> netutil.is_valid_ip('') False
>>> netutil.is_valid_ip('192.168.1.2') True
>>> netutil.is_valid_ip('192.168.1.999') False
>>> netutil.is_valid_ip('fe80::fe15:b4ff:fefc:f808') True
>>> netutil.is_valid_ip('aas10::fe15:b4ff:fefc:f808') False
>>> resDNS = netutil.Resolver()
>>> resDNS.configure('tornado.netutil.BlockingResolver')
>>> resDNS.resolve('www.google.com',80) <tornado.concurrent.Future object at 0x7f0679b01bd0> >>> dir(_)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_callbacks', '_check_done', '_done', '_exc_info', '_exception', '_result', '_set_done', 'add_done_callback', 'cancel', 'cancelled', 'done', 'exc_info', 'exception', 'result', 'running', 'set_exc_info', 'set_exception', 'set_result']

La función “bind_sockets” se encarga de crear los sockets en todas las interfaces de red disponibles y devuelve un listado con cada una de las referencias creadas.
La función “is_valid_ip” se encarga de validar si una dirección IPv4 o IPv6 es válida y finalmente, la clase “Resolver” permite configurar varios de tipos de “resolvers” para peticiones DNS bloqueantes y no bloqueantes.
Para mayor información sobre más utilidades disponibles en Tornado, se recomienda revisar la documentación: http://tornado.readthedocs.org/en/latest/netutil.html

Finalmente, Tornado incluye un servidor TCP que puede ser utilizado como un envoltorio de la utilidad “IOLoop” descrita anteriormente. Dicho servidor incluido en Tornado tiene la ventaja de que se encarga de gestionar automáticamente el estado del bucle iniciado por “IOLoop”.
Existen 3 mecanismos que se pueden implementar con la utilidad TCPServer.
1. Un único proceso en ejecución.

>>> from tornado import tcpserver >>> server = tcpserver.TCPServer() >>> server.listen(8080) >>> from tornado import ioloop
>>> ioloop.IOLoop.instance().start()

2. Multi-proceso simple con las funciones estandar “bind” y “start”

>>> from tornado import tcpserver
>>> server = tcpserver.TCPServer()
>>> server.bind(8080)
>>> server.start(8080)
>>> from tornado import ioloop
>>> ioloop.IOLoop.instance().start()

3. Multi-proceso avanzado utilizando la funcion “add_sockets”

>>> from tornado import tcpserver
>>> from tornado import ioloop
>>> from tornado import netutil
>>> from tornado import process
>>> sockets = netutil.bind_sockets(8000)
>>> process.fork_processes(0)
>>>server = tcpserver.TCPServer()
>>>server.add_sockets(sockets)
>>>IOLoop.instance().start()

Este ha sido el uso básico de Tornado, sin embargo hay que aclarar que existen otras librerías que son bastante robustas y que permiten conseguir los mismos objetivos, como es el caso de AsyncIO o incluso algunos módulos de Twisted. En el caso de AsyncIO, se encuentra incluida por defecto en las últimas versiones de Python 3, concretamente a partir de la versión 3.4. De dicha librería se hablará más adelante en otro artículo.
Saludos y Happy Hack!

Hacking con Python Parte 34 – Examinando servicios SNMP con PySNMP

septiembre 30, 2014 Deja un comentario

Uso de PySNMP para controlar agentes SNMP en un segmento de red local.

simpleSNMPTest.py:    https://github.com/Adastra-thw/pyHacks/blob/master/simpleSNMPTest.py
simpleSNMPTestOIDs.py:    https://github.com/Adastra-thw/pyHacks/blob/master/simpleSNMPTestOIDs.py
snmpBruter.py:    https://github.com/Adastra-thw/pyHacks/blob/master/snmpBruter.py


Repositorio GIT de la serie:

https://github.com/Adastra-thw/pyHacks.git


Make a Donation Button

Hacking con Python Parte 33 – Peticiones HTTP contra TOR utilizando requests y requesocks

septiembre 16, 2014 Deja un comentario

Uso de las librerías requesocks y socks para ejecutar scripts utilizando el proxy socks de TOR.

AnonBrowser.py:    https://github.com/Adastra-thw/pyHacks/blob/master/AnonBrowser.py
SimpleTorConnect.py:   https://github.com/Adastra-thw/pyHacks/blob/master/SimpleTorConnect.py
SimpleTorConnectRequests.py:   https://github.com/Adastra-thw/pyHacks/blob/master/SimpleTorConnectRequests.py

Repositorio GIT de la serie:

https://github.com/Adastra-thw/pyHacks.git


Make a Donation Button

Hacking con Python Parte 32 – Uso de Fabric sobre servicios SSH

septiembre 9, 2014 1 comentario

Uso de la librería Fabric para administrar paralelamente múltiples servidores SSH. Puede ser útil para crear una botnet sobre servidores SSH vulnerables o con contraseñas débiles.

fabfile.py:   https://github.com/Adastra-thw/pyHacks/blob/master/fabfile.py

SimpleFabricAdmin.py:   https://github.com/Adastra-thw/pyHacks/blob/master/SimpleFabricAdmin.py


Repositorio GIT de la serie:

https://github.com/Adastra-thw/pyHacks.git


Make a Donation Button

Hacking con Python Parte 31 – Examinando programas y librerías con pefile y pydasm

septiembre 2, 2014 2 comentarios

Usando PEFile y PyDASM para inspeccionar y desensamblar ficheros en formato Portable Executable (PE) en sistemas windows.

 

disassemblerDemo.py:   https://github.com/Adastra-thw/pyHacks/blob/master/disassemblerDemo.py

Repositorio GIT de la serie:

https://github.com/Adastra-thw/pyHacks.git


Make a Donation Button

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 1.356 seguidores

A %d blogueros les gusta esto: