18 diciembre 2012

Interceptando tráfico SSL en Android con Mallory proxy

Hace poco, y terminando ya un día de trabajo, me di cuenta de que la batería de mi smartphone Android se había drenado en cosa de 8-9 horas, del más absoluto de los idle's, hasta llegar al 0% y morir tras un agónico final sin cargador. Se trata de un Samsung Galaxy S III, que por aquella tenía embebida una versión del popular sistema operativo para smartphones y tablets de google número 4.0.4, también conocida como Ice Cream Sandwich. Tras este agónico final en tan poco tiempo me decidí a echar un ojo al tráfico que genera el terminal, a ver si se veía algo extraño ya que se ha visto por el market apliaciones fraudulentas que poco más que hacían que dar dinero a sus creadores generando tráfico basura desde nuestro Android a diferentes servicios que pagan por "click". 
En este punto, @aramosf me comentó sobre un proxy transparente presentado en la Black Hat de 2010 utilizado precisamente para estos menesteres. Así que me puse a ello.

Mi infraestructura iba a constar de:
  •  Un ordenador de sobremesa
  •  Mi maltrecho móvil
  •  Un router wifi
Ni más ni menos. Si además contamos con un portátil y un par de interfaces wi-fi podemos crear un AP falso para pasearlo por distintas ubicaciones públicas ;) Pero eso será objecto de otra entrada, ya que de momento mi portátil se encuentra fuera de combate.

Yo me decidí a realizar el MITM mediante una VPN, bastante fácil de configurar en Linux y ensucia menos la red que un arpspoof. Si elegimos el segundo método después tendremos que crearnos nuestras propias reglas en iptables, para enrutar el tráfico y que pase por mallory. Pero ese es otro tema, puesto que mallory junto con una VPN nos facilita enormemente la labor en este sentido.

Existe una máquina virtual con mallory pre-instalada, para descargar de su web oficial, yo me decidí a instalarlo directamente en el backtrack que tengo configurado sobre una máquina virtual.

La interfaz de red de mi máquina virtual la tengo configurada como "adaptador puente" o "bridge interface". De esta manera el DHCP del router es capaz de asignarle una dirección tal y como si fuera una interfaz física más dentro de la red.

Vamos a descargar y ejecutar la aplicación pptpd que será la encargada de crear nuestra VPN, y endpoint de nuestro terminal móvil.

root@bt:~/Desktop/mallory/mallory/scripts# apt-get install pptpd

Ahora vamos a configurarlo. Para ello editamos el archivo /etc/pptpd.conf y localizamos las líneas donde se definen la ip local del servidor VPN y las ips remotas que van a ser asignadas a nuestros clientes VPN.


  1. root@bt:~/Desktop/mallory/mallory/scripts# vi /etc/pptpd.conf
  2. ###############################################################################
  3. # $Id: pptpd.conf 4255 2004-10-03 18:44:00Z rene $
  4. #
  5. # Sample Poptop configuration file /etc/pptpd.conf
  6. #
  7. # Changes are effective when pptpd is restarted.
  8. ###############################################################################
  9. localip 192.168.1.22
  10. remoteip 192.168.1.230-240


Si estas dos líneas están comentadas (#) las descomentamos y en localip definimos la ip local del servidor VPN y en remoteip el rango de direcciones ips que queremos que se asignen a los clientes que se van a conectar. El siguiente paso es configurar un par usuario/contraseña para conectarnos. Debemos editar el archivo chap-secrets que se encuentra en /etc/ppp/


  1. root@bt:~/Desktop/mallory/mallory/scripts# vi /etc/ppp/chap-secrets
  2. # Secrets for authentication using CHAP
  3. # client        server  secret                  IP addresses
  4. user pptpd password *


Este archivo contiene las parejas usuario/contraseña válidas para acceder a nuestra red privada virtual. El primer campo será el usuario, el segundo la aplicación que se alimentará de estas credenciales, el tercero la contraseña y el último el rango de direcciones ips autorizadas a acceder a ese recurso.
Guardamos y reiniciamos el servicio pptpd:

root@bt:~/Desktop/mallory/mallory/scripts# /etc/init.d/pptpd restart

Y ya deberíamos ser capaces de conectarnos a través de nuestra recién configurada VPN. En android el proceso es muy sencillo. Aplicaciones -> Ajustes -> En conexiones inalámbrica buscamos Más ajustes -> VPN

Añadimos una red VPN con el usuario y contraseña que acabamos de definir en chap-secrets y con la dirección ip donde se encuentra la máquina servidor. Si todo ha ido bien deberíamos estar conectados ya.


Ahora procederemos a la instalación de mallory.

  1. sudo apt-get install mercurial;
  2. sudo apt-get install python-pyasn1;
  3. sudo apt-get install python-netfilter;
  4. sudo apt-get install libnetfilter-conntrack-dev;
  5. sudo apt-get install python2.6-dev;
  6. sudo apt-get install python-setuptools;
  7. sudo easy_install pynetfilter_conntrack;
  8. sudo apt-get install netfilter-extensions-source;
  9. sudo apt-get install libnetfilter-conntrack3-dbg;
  10. sudo apt-get install python-paramiko;
  11. sudo apt-get install python-imaging;

  12. #If you are installing Mallory on a 32 bit machine
  13. wget http://ubuntu.cs.utah.edu/ubuntu/pool/universe/libn/libnetfilter-conntrack/libnetfilter-conntrack1_0.0.99-1_i386.deb
  14. sudo dpkg -i libnetfilter-conntrack1_0.0.99-1_i386.deb
  15. #endif
  16. #if you are installing Mallory on a 64 bit machine
  17. wget http://ubuntu.cs.utah.edu/ubuntu/pool/universe/libn/libnetfilter-conntrack/libnetfilter-conntrack1_0.0.99-1_amd64.deb
  18. sudo dpkg -i libnetfilter-conntrack1_0.0.99-1_amd64.deb
  19. #endif

Instalamos todas las librerías y dependencias que son necesarias y dependiendo de si nos encontramos en un sistema operativo de 32 ó 64 bits instalaremos el primer o el segundo .deb

Dentro de la ruta de instalación de mallory podemos encontrar tres directorios principales:
  • mallory/db Que contienen las bases de datos sqlite en las que se insertan todos los streams que pasan por mallory
  • mallory/scripts Scripts para la configuración de iptables para realizar el MITM, además de uno para bloquear el spam que entraba hace años por netbios (:?) y por el servicio de windows messenger service. Nosotros no vamos a necesitar estos scripts puesto que vamos a lanzar la interfaz gráfica de mallory, que lo hará por nosotros. Pero para que se sepa deberíamos modificar config_router.sh y config_mallory.sh con las interfaces de entrada y salida.
  • mallory/src Donde se encuentra el core de programa. Los dos ejecutables que necesitamos (mallory.py y launchgui.py) además de un directorio con el certificado y demás ejecutables.
Abrimos un par de terminales y en una ejecutamos el proxy en sí.

  1. root@bt:~/Desktop/mallory/mallory/src# python mallory.py
  2. /root/Desktop/mallory/mallory/src/config_proto.py:3: DeprecationWarning: the sets module is deprecated
  3.   import sets
  4. MALLLLORYYY!!!!!!!!!!
  5. [*] [2012-12-09 19:50:39,404] INFO:Logging setup complete
  6. [*] [2012-12-09 19:50:39,406] INFO:[*] SSHProtocol: Initializing
  7. [*] [2012-12-09 19:50:39,409] INFO:HTTP protocol handler initialized
  8. [*] [2012-12-09 19:50:39,409] DEBUG:SSLProtocol: Initializing
  9. [*] [2012-12-09 19:50:39,410] DEBUG:SSLProtocol: Initializing
  10. [*] [2012-12-09 19:50:39,411] INFO:ConfigRules.init: LOADING RULES.
  11. [*] [2012-12-09 19:50:39,413] INFO:ConfigRules.load_config: Rule Action String is:Debug
  12. [*] [2012-12-09 19:50:39,417] DEBUG:NetfilterTool: Instantiating object.
  13. [*] [2012-12-09 19:50:39,418] INFO:RPCServer: add_remote_obj - adding remote object
  14. [...]
  15. [*] [2012-12-09 19:50:39,445] DEBUG:NetfilterTool: Instantiating object.
  16. [*] [2012-12-09 19:50:39,446] DEBUG:UDPProtocol[m]: Waiting for data

Ahora deberemos arrancar la interfaz gráfica que se conecta a través de un servidor xmlrpc a mallory.

root@bt:~/Desktop/mallory/mallory/src# python launchgui.py 

Y la interfaz gráfica arrancará. Si os da un warning acerca de una librería no instalada instaladla si vais a utilizar la interfaz del programa sobre la base de datos. Luego veremos cómo.

Ahora lo primero es realizar el MITM. Lo primero que se nos abre es la pestaña de interfaces en la que vamos a escoger la interfaz por la que "entra" el tráfico que queremos analizar y la interfaz por la que "sale" hacia internet. Y es tan sencillo cómo seleccionarlas mediante botones:


En mi caso he seleccionado la interfaz ppp0 (la del único cliente que tengo conectado a la VPN, recordemos que con cada cliente conectado el demonio crea un nuevo adaptador virtual punto a punto) como interfaz de "entrada" o donde mallory lo etiqueta como Perform MITM y eth0 como interfaz de "salida", o etiquetado tal cual está en mallory Outbound interface. Una vez hecho esto sólo tenemos que hacer click en Apply Configuration y la aplicación solita se encarga de agregar las reglas a iptables que son necesarias como podremos ver si ponemos en primer plano la terminal de la que cuelga la interfaz gráfica de mallory.


Lo que hacen estas reglas básicamente es redirigir todo el tráfico tanto tcp como udp que llega por ppp0 hacia el puerto de escucha de mallory, el 20755. Además añade un MASQUERADE en la interfaz de salida y activa el ip_forwarding.

Ahora nos vamos a la pestaña protocols, dónde podemos ver los protocolos y puertos que queremos interceptar.


Tan sólo tenemos que quitar los comentarios (;) del principio de línea de la definición de protocolos y puertos y clickear en Apply para activar la intercepción de estos protocolos y puertos. Por el momento tenemos disponibles tres, que son ssh, ssl y http.
Podemos añadir fácilmente tráfico en otro puerto, por ejemplo:

miproto:sslproto.SSLProtocol:5222

La pestaña rules es un potente modificador de tráfico, que nos permitirá automatizar el proceso de modificación de tráfico mediante patrones y reglas, aunque también podemos hacer modificaciones manualmente en "tiempo real".

La pestaña rules contiene la salsa de la aplicación, dónde en tiempo real, se muestra todo el tráfico que la aplicación está capturando, en base a los protocolos que hemos definido en la pestaña protocols. Debemos activar el botón de Intercept para que la aplicación muestre el tráfico y lo guarde en la base de datos y Auto-send si de momento sólo queremos mirar y no modificar nada. Casi inmediatamente y si tenemos nuestro terminal conectado a la vpn deberíamos empezar a ver trazas yendo y viniendo de aquí para allá, puesto que nuestros smartphones sabéis que están constantemente sincronizando y enviando otro tipo de datos a diferentes servicios. Por ejemplo, yo me di cuenta de que al abrir Chrome en mi android está casi continuamente mandando información contra un servidor de google para sincronizar las pestañas abiertas en los diferentes dispositivos que tenemos enlazados con nuestra cuenta de google.
¿Pero y qué ocurre si intentamos acceder a una web mediante https? Esto:


Chrome además de avisarnos de que el certificado no es válido, ni siquiera nos permite proseguir aceptando los riesgos. ¿Cómo se comportan este tipo de proxies cuando accedemos a un recurso mediante SSL? Tienen una ca interna que genera certificados autofirmados para cada web que visitemos. Además de todo esto, las aplicaciones que utilizan SSL para comunicarse con sus servidores ni siquiera funcionarán. Así que para solucionar este entuerto instalaremos el .cer en el terminal que nos permitirá salvar esta situación.

En algún sitio había leído que era un lío instalar un certificado en android, así que busqué y encontré un método en el que necesitábamos root en el teléfono y una shell en éste mediante el SDK de Android. Android posee un contenedor de certificados en /system/etc/security/cacerts/ donde se almacenan todos los instalados en el télefono. El nombre de los certificados es un hash del subject del certificado, seguido de un .0 ó .1, .2... si existen colisiones. Así que el directorio nos queda tal que así:


  1. shell@android:/system/etc/security/cacerts # ls -l
  2. ls -l
  3. -rw-r--r-- root     root         4767 2012-09-28 14:15 00673b5b.0
  4. [...]
  5. -rw-r--r-- root     root         5106 2012-09-28 14:15 ff783690.0



Después tan sólo hacíamos el mencionado hash con openssl x509 -noout hash -in .../mallory/src/ca/cer.key, renombrábamos el certificado a ese hash (más un .0) y lo metíamos mediante un adb push al directorio contenedor de certificados. Pero a mí particularmente no me funcionó. Por lo que puse en marcha la solución sencilla. Montar un apache, meter ahí el certificado de mallory y acceder desde el móvil para descargarlo. Dicho y hecho.


Pinchando en él se descarga a la SD, por lo que el siguiente paso en el móvil es ir a Ajustes -> Seguridad -> Instalar desde almac dispositivo -> seleccionar el certificado que acabamos de descargar. Si ahora vamos a Credenciales de confianza -> pestaña Usuario, debería aparecer el certificado que acbamos de instalar.


Ahora intentamos acceder a una web con https y...


Ya confía en nosotros :) Ahora podremos ver el tráfico en claro desde mallory:


Además de que otras aplicaciones que transmiten sobre SSL también funcionarán :)


Mallory además tiene una interfaz contra la base de datos que podemos utilizar para consultarla sobre los streams almacenados. En la pestaña advanced podemos pulsar sobre create flow query y nos generará una consulta con los campos más importantes para poder ver un flujo de tráfico. 


Además podemos abrirla directamente con sqlite3 y hacer consultas desde la línea de comandos. Para ver el schema de la base de datos:

  1. root@bt:~/Desktop/mallory/mallory/db# sqlite3 trafficdb
  2. SQLite version 3.7.11 2012-03-20 11:35:50
  3. Enter ".help" for instructions
  4. Enter SQL statements terminated with a ";"
  5. sqlite> .schema
  6. CREATE TABLE connections(
  7.                 connCount INTEGER,
  8.                 serverIp TEXT,
  9.                 serverPort INTEGER,
  10.                 clientIp TEXT,
  11.                 clientPort INTEGER
  12.             );
  13. [...]  
  14.          
  15. sqlite>


Y con .help podemos ver todos los comandos disponibles en sqlite3. Por ejemplo, .tables nos mostrará el nombre de todas las tablas de esa base de datos.

Con todo esto en marcha, no sería muy difícil crear un punto de acceso falso, conseguir clientes que se conectarían pensando que es un AP legítimo, colocarles una especie de portal cautivo dónde se les pidiera la instalación del certificado y a continuación dejarles navegar con normalidad.
Para otra entrada queda cómo crear un punto de acceso falso con hostapd.


Artículo por @jorch_garcia

15 comments :

car dijo...

Desde luego que te has currao el articulo Jorch, en serio lo he tenido que leer 2 veces consecutivas para llegar a entenderlo,sin embargo lo que no me ha quedado muy claro es la instalación de certificados en Android y el porque de tanta complejidad para ello. Pues lo dicho Jorch, buen articulo y por supuesto muy buen Blog el cual sigo desde hace tiempo ademas de tenerlo enlazado desde mi el mio propio, saludos.

juju666 dijo...

Lo del Fake-AP lo tienes aquí:

http://exploit.co.il/hacking/set-fake-access-point-backtrack5/


Hace tiempo me ocurrió lo mismo que a ti y quería ver que hacía el movil y "con quien" :)

Antonio González dijo...

Interesante y muy buen articulo, pero realmente creo que el foco y principal problemática que tienen lo usuarios no es capturar trafico SSL a través del proxy del navegador web, sino capturar las peticiones y peticiones cifradas de una APP. Seria interesante que investigar´s un poco mas a fondo y completaras este articulo con esta información, tienes bastante información en inglés sobre este tema.


Un saludo y felicidades por el articulo.

Jorge García dijo...

Gracias! Lo del primer método lo leí de primeras en algún sitio del internés hace algún tiempo. Lo puse en práctica y a mí particularmente no me funcionó, pero bueno, lo dejé ahí porque en principio se supone que funciona. Así que la opción que me quedó fue levantar el apache, además que si te lo envías por correo electrónico no lo reconoce.

Jorge García dijo...

Gracias! Estoy dándole vueltas a una aplicación de mensajería instantánea. Quizá si sale algo pueda dar para una entrada...

Pedro Laguna dijo...

Un detalle: la libreria que pones para 32 o 64 bits no existe. Si vas a la web, no aparece en el listado: http://ubuntu.cs.utah.edu/ubuntu/pool/universe/libn/libnetfilter-conntrack/?C=M;O=A

Yo he usado la version libnetfilter-conntrack1_0.0.81-1_amd64.deb y al menos asi si que parece que funciona.

Ignacio Agulló Sousa dijo...

El artículo es extenso, y está currado, pero tiene un problema gordo.

Se da a entender que se realiza un ataque del tipo Hombre en el medio que permite interceptar cualquier tráfico SSL de los dispositivos conectados al punto de acceso. Sin embargo, para realizar este ataque es preciso que los certificados suministrados a los clientes sean falsos, (indebidamente) acreditados por alguna autoridad de certificación; porque si meramente se reenvían los certificados verdaderos, el tráfico SSL no puede ser descifrado. El artículo no detalle este proceso, no menciona la generación de certificados falsos ni la forma de conseguir acreditarlos (indebidamente) por parte de alguna autoridad de certificación. Parece que simplemente se reeenvíe a los clientes el certicado original, y de esa manera es imposible que el tráfico SSL pueda ser interceptado.

Ignacio Agulló Sousa dijo...

Me respondo a mí mismo. La frase "Si además contamos con un portátil y un par de interfaces wi-fi podemos
crear un AP falso para pasearlo por distintas ubicaciones públicas" me desorientó un poco, pensé que el artículo estaba dedicado a intercepción de SSL en dispositivos ajenos, y no un dispositivo propio donde la instalación de certificados está bajo el control del propietario.

Jorge García dijo...

El proceso de generación de certificados no está detallado porque en ningún momento se genera ninguno, simplemente se instala el ca.cer que viene con mallory. Sí que está detallado el proceso que siguen este tipo de proxys con los certificados y es que, generan uno auto-firmado por cada web https que visitas, que se valida contra el ca que has instalado en el móvil. El certificado original obviamente no se reenvía, sino sería imposible esa captura en la que se ve el número de documento y el pin/password en una web de banca ;) De todas maneras, esto en principio no es un ataque, sino que capturaríamos datos de nuestro propio móvil, que es mi propósito inicial, ver si alguna aplicación no legítima estaba enviando datos hacia fuera :P

Jorge García dijo...

En este caso, habría que forzar a los usuarios de nuestro punto de acceso wifi a instalar el certificado mediante ingeniería social, por ejemplo un portal cautivo :) Lo detallaré si llego a hacer una entrada sobre ello.

dario90 dijo...

Hola, ¿recomendas alguna aplicacion Android para bloquear todas las peticiones salientes por el puerto 80?

Jorge García dijo...

Droidwall, es un firewall para Android. Pero necesitas root ;)

Ed dijo...

¿Y no es más fácil utilizar el Fiddler? Es mucho más simple de instalar. No requiere MITM ni VPN, sólo un conectarte al proxy que crea el programa e instalar un certificado si quieres ver el tráfico SSL.

¿Al final el drenaje de la batería fue por un tráfico extraño?

Jorge García dijo...

Coño, me pasó lo mismo y lo había detectado y se me olvidó incluirlo bien en la entrada. Gracias por el apunte.

Jorge García dijo...

Gracias! Cuando me desperece y decida fixear el portátil (me cargué el mbr y es irrecuperable) quizá haga una entrada complementando esta sobre el uso de un fake ap.