lunes, 21 de noviembre de 2011

Patch Bindiffing (II)

La semana pasada nos quedamos en un anterior post con que habíamos analizado un parche y habíamos descubierto que ficheros del sistema habían sido añadidos o actualizados.

Ahora nos quedaba la segunda parte, que es... ¿qué modificaciones se han hecho sobre estos binarios?
Para hacer esto tendremos que coger las dos versiones del binario, librería, o en este caso driver, y emplear alguna de las herramientas que existen para hacer este análisis diferencial.

Para este caso concreto he usado una extensión de IDA, desarrollada por Tenable, llamada patchdiff2, y que os podeis descargar de forma completamente gratuita aquí.

Hay otras extensiones para IDA que realizan estas mismas acciones. Vierito5 publicó hace tiempo en su blog una lista de extensiones recomendadas para IDA en las que, además de otras muchas extensiones de todo tipo, podemos encontrar varias opciones para realizar bindiffing.

Para añadir uno de estas extensiones únicamente hay que buscar el directorio "plugins" dentro del directorio de IDA. Lo reconoceremos porque veremos que tiene dentro ficheros con extensión "*.pmc", que son exactamente como los que nos vendrán en el zip del patchdiff2. Dejamos los "pmc" del patchdiff2 en este directorio y ya tendremos completamente disponible la extensión la próxima vez que arranquemos IDA.

Para poder utilizar el bindiffing es necesario que este se haga a partir de los ficheros "*.idb" de IDA, que es un formato propio de esta herramienta en el que podemos guardar el análisis que realiza la herramienta sobre un binario concreto. Para ello, abrimos el primero de los binarios (tcpip-old.sys) y dejamos que IDA lo pre-procese, y cuando acabe de hacerlo cerramos y elegimos guardar la base de datos, con lo que se nos generará un fichero tcpip-old.idb, que usaremos a continuación.

Ahora abrimos de nuevo IDA pero esta vez elegimos analizar tcpip-new.sys, y dejamos de nuevo que IDA lo pre-procese. Una vez que acabe nos vamos al menú "Edit" y a "Plugins", y elegimos el plugin "PatchDiff2", con lo que se nos abrirá una ventana para elegir con que otro fichero "*.idb" lo queremos comparar. Elegimos tcpip-old.idb y lo dejamos que realice el bindiffing.

Al hacer esto, veremos que nos salen tres pestañas nuevas:

  • Identical Functions: Son aquellas que han sido detectadas como idénticas en ambos binarios, es decir, no han cambiado al hacer el bindiffing.
  • Unmatched Functions: Son aquellas de las que, teóricamente, no se ha podido encontrar una función equivalente en el otro binario. Generalmente suele tratarse de funciones nuevas, aunque es muy común que nos encontremos muchas funciones idénticas pero que por algún motivo no se han hecho match. La columna CRC nos puede dar una pista sobre esto.
  • Matched Functions: Son aquellas que han sido detectadas como que son las mismas, pero que han sufrido alguna modificación

Sabiendo esto, y dado que nos estamos centrando en un bindiffing, podemos asumir que las funciones que han hecho match completo no nos interesan, y que las unmatched que tengan un CRC idéntico o que sean completamente nuevas, tampoco nos interesan (a priori, si notamos que nos falta información volveremos atrás), ya que las funciones nuevas tienen que ser llamadas desde ningún sitio, así que su "origen" lo vamos a tener pillado a través de las funciones "matched".


En este caso, tenemos cinco funciones que parecen haber sido modificadas por el parche, así que alguna de ellas tiene que haber sido la que corrige la vulnerabilidad, o quizá una combinación de varias de ellas.

Para poder ver los cambios exactos introducidos en cada una de ellas, deberemos seleccionar la función y pulsar con el botón secundario del ratón para que nos salga el menú, y elegiremos la opción "Display Graphs".


Una vez que vemos gráficamente la función, vemos de una forma muy clara las modificaciones realizada, ya que el código se encuentra separado en bloques con un código de colores que nos proporciona información sobre estos cambios:

  • Blanco: Bloques idénticos, es decir, no se ha producido ningún cambio en ellos.
  • Gris: Bloques "unmatched", generalmente trozos nuevos de código que serán llamados desde algún otro bloque modificado.
  • Rojo: Bloques "matched", es decir, que han sufrido algún tipo de modificación.

No os puedo remitir a la documentación de PatchDiff2 para más información, ya que al menos yo no he encontrado ninguna fuente oficial, pero podeis encontrar información buscando en Google, o sencillamente jugando un poco con ella, ya que permite hacer correcciones sobre el análisis automático que hace, es decir, podeis pasar de "unmatched" a "matched" una función, y cosas así.

En el próximo post, veremos cada una de estas funciones, a ver que cambios concretos ha realizado el parche, a ver si conseguimos averiguar en que consiste la vulnerabilidad que parchea.

miércoles, 16 de noviembre de 2011

Encuesta: Cursos del SANS Institute en España

Como ya se comentó en el anterior post, publicamos una encuesta sobre los cursos y modalidades del SANS Institute más demandadas, con el fin de plantear los cursos de 2012 en adelante.

Os pido que, al completar el formulario, seais sinceros con respecto a los cursos y modalidades a los que OS APUNTARIAIS, no solo los que os interesan, sino en los que realmente existen altas probabilidades de que pudiéramos contar con vosotros como alumnos. Toda la información sobre cursos, modalidades, precios, etc, se puede encontrar aquí. La descripción de muchos cursos aún no está, pero podéis mirarlo directamente en la web del SANS, o simplemente completar el formulario más adelante.

lunes, 14 de noviembre de 2011

Patch Bindiffing (I)

Todos sabemos, más que nada por lo mediáticos que son, lo que son las vulnerabilidades/exploits 0-day, que son vulnerabilidades descubiertas por alguien que no notifica al creador del producto, sino que utiliza el exploit para su propio provecho, o simplemente lo publica en full-disclosure, antes de que pueda prepararse un parche.

Otro tipo de exploits que podamos encontrar son los 1-day. La explotabilidad de los 1-day está muy estrechamente relacionada con la lentitud de algunas personas o entidades en aplicar los parches de seguridad. Una vez que el fabricante del producto saca un parche, aunque no proporcione mucha información acerca de la vulnerabilidad, dicho parche es analizado para obtener toda esa información, y de este modo poder tener un exploit funcional para dicha vulnerabilidad. Si esto se consigue en un día o en unos pocos días (de ahí su nombre), podemos decir casi con seguridad que habrá muchas potenciales víctimas que no tendrán parcheados sus sistemas.

Para ejemplificar esto, vamos a utilizar la vulnerabilidad MS-11-083, publicada por Microsoft la semana pasada y que, según parece, podría provocar ejecución remota de código mediante el envio de paquetes UDP en sistemas Windows 7 y Windows 2008.

Para poder hacer un Bindiffing, lo primero que tenemos que hacer es obtener dos binarios sobre los que hacer el diffing, ¿verdad? ¿cómo conseguimos esto? Siguiendo estos pasos:
  1. Instalamos un Windows 7 (en este caso) en una máquina virtual y lo actualizamos hasta que nos aparezca para actualizar el parche en cuestión que queremos analizar. Éste no lo instalamos.
  2. Nos descargamos e instalamos en la máquina el RegShot o alguna herramienta similar, que nos sirva para tomar snapshot fichero a fichero de todo el sistema.
  3. Hacemos un Snapshot completo de la máquina virtual.
  4. Lanzamos RegShot para hacer un Snapshot de todos los ficheros. Por comodidad, ya que sabemos que es un parche de sistema, le podemos decir que busque solo en C:\Windows, que siempre irá más rápido que hacer Snapshot de todo el disco. Elegimos la opción "shot and save" para que nos guarde el snapshot en un fichero, ya que este parche necesita reiniciar y sino perderemos el estado.


  5. Instalamos el parche. Nos pedirá que reiniciemos.
  6. Volvemos a lanzar RegShot, pero esta vez en la opción "1st shot" elegimos "load" y cargamos el snapshot que hicimos antes de reiniciar. Hacemos el segundo shot (2nd shot, shot) y cuando acabe pulsamos sobre "Compare" para que nos saque las diferencias.
En otro tipo de parches puede resultar mucho más inmediato ver los ficheros modificados, pero en este caso, con un reinicio de por medio, va a haber muchísimos registros y ficheros modificados. Veremos un montón de temporales del parche que acabamos de instalar, prefetchs, ficheros de logs, y un montón de registros, pero debemos pasar de toda esa "paja" e intentar ir a la sección de ficheros modificados y buscar aquellos que estén en un path que nos hagan ver que se trata de un fichero del sistema:

[...]
----------------------------------
Files [attributes?] modified:133
----------------------------------
[...]
C:\Windows\System32\drivers\tcpip.sys
C:\Windows\System32\LogFiles\Scm\729f4f57-2181-4edb-bb11-79c7914d10dc
C:\Windows\System32\LogFiles\Scm\9b75c702-ea13-406a-badb-6c588ee4375b
C:\Windows\System32\LogFiles\Scm\a1cfa52f-06f2-418d-addb-cd6456d66f43
C:\Windows\System32\LogFiles\Scm\a316e645-1c56-45a6-bd6a-7dca79778090
[...]


El resultado tiene sentido, vemos que ha modificado el driver tcpip.sys, que presumiblemente es el que contiene la vulnerabilidad. En este caso solo he podido apreciar un fichero (aunque hay gente por ahí que habla de dos, pero yo en Windows 7 solo he visto uno), así que lo que nos queda ahora por hacer es copiarlo fuera de la máquina virtual, y llamarlo tcpip-new.sys para diferenciarlo del original.


Para finalizar, restauramos el Snapshot de la máquina virtual al estado previo a la aplicación del parche que queremos analizar y buscamos estos mismos ficheros que hemos encontrado que han sido modificados, en este caso tcpip.sys, y lo copiamos de nuevo fuera de la máquina virtual, esta vez con el nombre tcpip-old.sys, para no confundirlo con el anterior.

Una vez hecho esto, ya tenemos la version anterior y posterior al parche de los ficheros modificados pero... ¿cómo sabemos ahora que cambios concretos se han hecho a cada fichero?

Lo veremos en el próximo post.

lunes, 7 de noviembre de 2011

SANS Institute: Explicaciones

En mi experiencia como Mentor y también alumno del SANS Institute, diría que todos pasamos por una primera etapa en la que nos perdemos un poco cuando buscamos información sobre cursos y modalidades de esta entidad. Perdí ya la cuenta hace mucho tiempo de la cantidad de correos que me llegan de gente que ha estado buceando por la web del SANS, y no se sabe muy bien si por su organización, por el idioma, o por una combinación de ambas, no consiguen comprender como tienen que proceder para hacer alguno de sus cursos.

Pensando en esto, y en la cantidad de veces que he copiado y pegado mis propios correos, he decidido publicar una pequeña "guía SANS" en Español que podéis encontrar AQUÍ, en donde se explican las diferentes modalidades de los cursos, y las que suelen ser mis recomendaciones habituales según el caso, con lo que espero que pueda ayudar a toda la gente que se encuentra perdida saltando entre las webs de SANS y GIAC, o por lo menos ahorrarme escribir en los correos siempre la misma explicación xD

También he añadido una descripción de cada curso de los que conozco, así como los cursos que en la actualidad tengo conocimiento de que estén teniendo lugar en España, pero si eres un Mentor, Community Instructor o Instructor del SANS y quieres aportar una descripción para tu curso, o corregir alguna de la información que he dado sobre los cursos disponibles, por favor ponte en contacto conmigo.

En unos pocos días sacaré también una encuesta de interés por los cursos de SANS, en los que podréis todos marcar, ahora que conoceréis bien las diferentes opciones, que cursos serían de vuestro interés, en que modalidades y en que ciudades, para que de este modo podamos plantear mejor con SANS que cursos montar de cara al 2012 que ya nos acecha.

Cualquier comentario sobre lo escrito, algo que no se entienda, o necesidad de ampliación de alguna parte, estoy completamente abierto a sugerencias.

miércoles, 2 de noviembre de 2011

#5EBloggers en León (INTECO-CERT)

El pasado miércoles tuve la oportunidad de estar en León participando en la mesa redonda de Bloggers de Seguridad organizada por el INTECO-CERT, que tenía idéntico tema al del ENISE: "Hacia una sociedad conectada más confiable".

Siempre he sido de la opinión de que existe un exceso de confiabilidad en el mundo de la tecnología, y que ciertamente no ocurren más incidentes porque, aunque parezca mentira, los atacantes aún tienen "buena Fé", o al menos no tanta mala leche como podrían tener, y no pensaba que ninguno de los otros invitados tuviera opiniones muy diferentes al respecto.

De izquierda a derecha:
Javier Berciano (@jberciano)
Manolo Benet (@mbenet)
Sergio de los Santos (@ssantosv)
David Hernández (@daboblog)
Jose Selvi (yo) (@JoseSelvi)
Yago Jesús (@YJesus)
Francisco Losada (@flosadam)
Gracias a Dabo por hacer con su móvil y pasarnos la foto :)

No tiene mucho sentido que haga una crónica extensa de lo que comentó cada uno de nosotros en la mesa redonda porque el resto de asistentes han publicado ya sus propias crónicas, así que en ese sentido no tengo mucho más que aportar al respecto.

A modo de resumen, todos estuvimos de acuerdo en que, en este momento, existen muchas deficiencias en la tecnología que usamos que nos hacen perder esa "confiabilidad" que se busca en el título de la mesa redonda. Culpables... un montón, nuestra propia visión de la tecnología, la publicidad engañosa por parte de empresas, etc. Sin embargo, alcanzar la deseada confiabilidad es posible, con mucho trabajo, y con una actitud responsable por parte de las empresas y de las personas.

Por citar una frase que dije durante mi intervención, y que al parecer gustó bastante a Yago (no sé como resumirla para que quepa en un Tweet xD):

Seguro que la primera persona que consiguió volar, una vez lo hizo, primero se pasó un buen rato felicitándose a si mismo por el logro conseguido, y cuando acabó de hacerlo y de decirse lo bueno que era, se dio cuenta que no había pensado como aterrizar. Lo mismo ocurre con la tecnología hoy en día, nos estamos preocupando tanto de poder llevar la conectividad a un extremo, de conseguir nuevos avances, y de lo buenos que somos por haberlos conseguido, que luego nos damos cuenta de que no tenemos ni idea de como "vamos a terrizar".

Para acabar, simplemente agradecer a Javier Berciano, a Francisco Losada, y en general al INTECO-CERT, por una impecable organización y por un trato personal excepcional. Sin duda uno de los eventos mejor organizados y en los que mejor me han tratado de los que he asistido.

Espero poder tener la oportunidad de asistir en futuras ediciones.
¡Muchas gracias!

lunes, 24 de octubre de 2011

Jugando con VirtualHosts (III): Necromant

Como ya sabéis, los servicios webs tienen la opción de configurar varios hosts virtuales, que contienen diferentes sitios webs en base al nombre de hosts que se utilizó en la URL.

Para que el servicio web sepa que nombre de hosts usamos en la URL, nuestro navegador inserta una cabecera HTTP llamada "Host". Esta cabecera no aparecerá si accedemos directamente a una URL por su IP, pero sí aparecerá si accedemos por ejemplo a http:/www.alcampo.es:

Host: www.alcampo.es

Si un servicio web no tiene configurado ningún host virtual, en ese caso cualquier cabecera host o la ausencia de ella hará que nos devuelva el host por defecto, con lo que en todos los casos devolverá el mismo contenido.

Necromant es una nueva herramienta desarrollada en Pentester.Es para el descubrimiento de hosts virtuales "muertos", de ahí su nombre [Wikipedia], es decir, aquellos hosts virtuales que responden a un nombre de host concreto, pero cuyo nombre DNS no existe o no apunta a su dirección IP, con lo que resultan a priori inaccesibles.

Hay varias situaciones en las que podemos encontrarnos estos hosts virtuales "muertos", como por ejemplo:
  • Servicios web de desarrollo, donde los desarrolladores resuelven manualmente en su ficheros "hosts" local.
  • Servicios web que se encuentran balanceados por algún tipo de dispositivos.
  • Servicios web donde antes se alojaba una web y que se trasladó a otro host, cambiando la resolución DNS, pero sin eliminar el host virtual antiguo.
Encontrar este tipo de hosts virtuales "difuntos" puede ser de mucha utilidad, ya que muchas veces vamos a poder encontrar aplicaciones web antiguas o en desarrollo, saltarnos filtrados por IP utilizando los balanceadores, y mucho más.

Veamos que opciones tiene Necromant:

$ ./Necromant.py 
# Necromant v0.1 - 04/May/2011
# Dead Virtual Host Searcher
# Jose Selvi - jselvi (4.t) pentester (d0.t) es
# http://www.pentester.es
# http://tools.pentester.es/necromant


Usage: ./Necromant.py hostname.list url.list

Como podemos ver, Necromant acepta dos parámetros, una lista de hostnames y otra lista de urls. La información necesaria para completar estos ficheros podemos obtenerla mediante otros métodos, como vimos en anteriores posts [1][2]. La mejor manera de aprender el formato de ambos ficheros es ver un sencillo ejemplo, para ello vamos a elegir un objetivo, por ejemplo la red de hipermercados Alcampo, y vamos a buscar servicios web en sus IPs. La búsqueda real sería mucho más extensa que esta, pero para el ejemplo buscaríamos solo ofrecidos en puertos 80.

# nmap -PN -T4 -open -sS -p 80 -oG alcampo_nmap80.grep 217.140.24.0/24

Tras este escaneo ya podemos crear el fichero alcampo_urls.txt, que tendrá el siguiente contenido:

http://217.140.24.10
http://217.140.24.19
http://217.140.24.23

La herramienta acepta http y https, y acepta también la definición de puertos no estándar, para que podamos incluir los servicios webs en otro tipo de puertos. Ahora solo nos queda crear el fichero alcampo_hosts.txt con los nombres de host que queremos comprobar contra las URLs anteriores:

www.alcampo.com
www.alcampo.es

Ahora que ya tenemos los dos ficheros, solo tenemos que lanzar Necromant y dejarle actuar:

$ ./Necromant.py alcampo_hosts.txt alcampo_urls.txt 
Looking for this HostNames:
- www.alcampo.es
- www.alcampo.com


Looking at this Servers:
- http://217.140.24.10
- http://217.140.24.19
- http://217.140.24.23


Searching hostnames for: http://217.140.24.10
Searching hostnames for: http://217.140.24.19
- www.alcampo.es
- www.alcampo.com
Searching hostnames for: http://217.140.24.23
- www.alcampo.es
- www.alcampo.com


Virtual Hosts Found:
www.alcampo.es:http://217.140.24.19
www.alcampo.com:http://217.140.24.19
www.alcampo.es:http://217.140.24.23
www.alcampo.com:http://217.140.24.23

Como podemos ver, hay dos IPs que responden a los mismos nombres de hosts, a pesar de que el registro DNS solo nos resuelve a uno de ellos:

$ host www.alcampo.es
www.alcampo.es has address 217.140.24.23
$ host www.alcampo.com
www.alcampo.com has address 217.140.24.23

Si configuramos en nuestro fichero de hosts local la resolución de nombres estática apropiada, vamos a poder acceder a estos hosts virtuales en esta IP diferente a la que accederíamos de la forma habitual. A veces puede no aportar ningún tipo de relevancia, y otras veces puede resultarnos MUY útil.

Antes de terminar, me gustaría destacar que la herramienta lo que realiza es un fingerprint del sitio web accedido en base a algunos parámetros, entre ellos el contenido, comparando el resultado del fingerprint entre los nombres de host que buscamos y un hombre de host ficticio. Esto quiere decir que si el único sitio web está configurado como host por defecto, no nos va a detectar ningún nombre de hosts, aunque uno de los que hayamos probado esté ahí, ya que no está "oculto". Quizá en una siguiente versión le añada la posibilidad de que realice un fingerprint accediendo por nombre de host y luego compare, para detectar también donde está cada nombre de host por IP.

Por último, deciros que la herramienta está en estado beta, es decir, puede que os encontréis con algún tipo de falsos positivos. Si os encontráis alguno escribidme un correo, pero antes comprobad verdaderamente que se trata de un falso positivo, porque yo me he encontrado con algunos sitios web que los han configurado por separado y han copiado el contenido del html, pero que han añadido alguna tontería y la web, parece idéntica, pero no lo es.

Como os comentaba, podeis descargar la herramienta de AQUÍ.
Sed buenos.

miércoles, 19 de octubre de 2011

Jugando con VirtualHosts (II): WebSearch

En el post anterior nos quedábamos con una serie rangos de IPs que habíamos sacado de la herramienta theHarvester, pero nos quedábamos con las ganas de sacar todos y cada unos de los hosts virtuales de todo el rango.

Hay muchas herramientas en el mercado que sacan los hosts virtuales a partir de una IP empleando la cache de Bing y su fantástica opción "ip:", pero al menos cuando desarrollé la herramienta WebSearch (que ya presenté hace tiempo) no encontré ninguna a la que le pudiera pasar de forma cómoda un rango completo de IPs y que esta me buscara absolutamente todos los hosts virtuales, así que por ese motivo la desarrolle, y puedo decir que hasta el momento no he encontrado otra herramienta que me guste más para hacer este tipo de descubrimiento.

No entraré en detalles sobre la instalación y manejo porque eso ya lo hice en el anterior post en el que se presentó la herramienta, pero vamos a aplicarlo directamente a los rangos de renfe.es obtenidos de nuestro anterior post:

$ ./WebSearch.py 213.144.32.0-213.144.63.255
Searching hostnames for: 213.144.32.0 (0)
Searching hostnames for: 213.144.32.1 (0)
Searching hostnames for: 213.144.32.2 (0)
Searching hostnames for: 213.144.32.3 (0)
[...]
Searching hostnames for: 213.144.32.153 (0)
Searching hostnames for: 213.144.32.154 (1)
mail.adif.es
Searching hostnames for: 213.144.32.155 (0)
Searching hostnames for: 213.144.32.156 (0)
[...]
Searching hostnames for: 213.144.33.126 (0)
Searching hostnames for: 213.144.33.127 (10100)
www.adif.es
www.estacionesverdes.com
www.videoadif.org
www.videosferrocarril.net
www.abrimoscaminos.org
www.adifvideos.net
www.videosferrocarril.com
www.videosferroviarios.com
www.adif.org.es
www.videosferroviarios.net
[...]

Como podemos ver, después de unos cuantos minutos buscando por todo el rango, encontramos bastantes hosts que no habíamos encontrado en los pasos anteriores (enseño solo unos pocos de ellos), y algunos de ellos de dominios que desconocíamos hasta ahora, pero que evidentemente pertenecen a la misma empresa. Podemos usar estos dominios para volver a usar theHarvester con ellos y volver a empezar el proceso, y así ir enriqueciendo nuestra lista de dominios y nombres de host.

Ahora ya tenemos un montón de nombres de hosts y unos cuantos rangos de IPs donde hay bastantes servicios webs a la escucha y... queda un post más para acabar la serie.

En el próximo post presentamos Necromant.

lunes, 17 de octubre de 2011

Jugando con VirtualHosts (I): theHarvester

Este es el primero de una serie de posts sobre como manejarse con los virtual hosts de un servicio webs, que acabará con la presentación de un pequeño script de cosecha propia, pero que me ha parecido que merecía la pena tomar este tema desde el principio.

Hace algo más de dos años publiqué una herramienta (o pequeño script) en Perl llamado TargetSearch, al que se le pasaba como entrada un dominio y éste buscaba en Google nombres de host cacheados que acabaran en este dominio, con lo que éramos capaces de descubrir nuevos nombres de hosts y rangos de IPs en los que la empresa auditada tiene recursos, aunque las IPs no sean realmente de su propiedad, sino del ISP, o similar.

Hace ya bastante tiempo tuve el impulso de reescribirlo entero en python y cambiar algunas cosas para mejorarlo, ya que con su uso diario me había dado cuenta de bastantes limitaciones, pero tras valorarlo decidí no continuar el desarrollo del script, ya que hay otros desarrollador por otras personas que ofrecen una funcionalidad mayor que este y... ¿para que reinventar la rueda?

De entre las opciones que hay por ahí, a mi la que más me gusta es theHarvester, desarrollada por mi amigo Christian Martorella, y que podéis encontrar tanto en su blog como en distribuciones de seguridad bien conocidas como pueda ser BackTrack.

theHarvester ofrece la posibilidad de buscar subdominios dentro de un dominio a través de Google, al igual que hacía TargetSearch, pero también encuentra otro tipo de información como correos electrónicos, y utiliza más fuentes de datos, como Bing, LinkedIn, y algunos otros. Veamos la ayuda de la herramienta (le quito la cabecera donde pone autor y esas cosas, por claridad):


$ ./theHarvester.py -h
Usage: theharvester options 


       -d: Domain to search or company name
       -b: Data source (google,bing,bingapi,pgp,linkedin,google-profiles,exalead,all)
       -s: Start in result number X (default 0)
       -v: Verify host name via dns resolution and search for vhosts(basic)
       -l: Limit the number of results to work with(bing goes from 50 to 50 results,
            google 100 to 100, and pgp does'nt use this option)
       -f: Save the results into an XML file


Podemos elegir alguna de las fuentes o simplemente elegir "all" para que nos busque en todas las fuentes disponibles. La opción -l nos deja ajustar cuantos resultados va a leer la herramienta antes de parsear los resultados, así que cuanto más alto sea este número más fácil será encontrar la información que buscamos, pero eso se traducirá también en un mayor número de conexiones contra los buscadores, y por lo tanto una mayor lentitud y una mayor probabilidad de ser detectado y/o bloqueado por ellos.

Veamos un ejemplo sencillo de como intentaríamos sacar toda la información posible de, por ejemplo, renfe.es:


$ ./theHarvester.py -d renfe.es -l 200 -b all
Full harvest..
[-] Searching in Google..
Searching 100 results...
Searching 200 results...
Searching 300 results...
[-] Searching in PGP Key server..
[-] Searching in Bing..
Searching 100 results...
Searching 200 results...
[-] Searching in Exalead..
Searching 100 results...
Searching 200 results...
Searching 300 results...


[+] Emails found:
 -------------
SIR@renfe.es
ozramos@renfe.es
antonio.sierra@renfe.es
slozano@renfe.es
Jsagues@renfe.es
internet@renfe.es
grupos@renfe.es
comercial.ext.sir@renfe.es
mdelgadoa@renfe.es
comprasave@renfe.es
jacorral@renfe.es
crodriguez@renfe.es
rgcamus@renfe.es
ciapu17@cosme.renfe.es
cijoua7@cosme.renfe.es
ismiguel@renfe.es
ciapu66@cosme.renfe.es
fgarcia@renfe.es
cigou24@renfe.es
fdelmoral@renfe.es
alorenzo@renfe.es
jvillen@renfe.es
ihorcajo@renfe.es
arocha@renfe.es
didgu01@cosme.renfe.es
vrdid08@renfe.es
@renfe.es


[+] Hosts found
 -----------
80.239.224.25:www.renfe.es
213.144.33.20:w1.renfe.es
213.144.33.35:clubave.renfe.es
213.144.49.9:mail.renfe.es
80.239.224.25:horarios.renfe.es
213.144.49.136:infocer.renfe.es
213.144.33.206:web02.renfe.es
213.144.49.43:dns2.renfe.es
213.144.33.254:ns1.renfe.es
213.144.32.153:ns2.renfe.es
213.144.33.39:w4.renfe.es
213.144.33.20:W1.renfe.es
213.144.34.30:rnessl.renfe.es
213.41.75.72:boletines.renfe.es
213.144.49.35:dns1.renfe.es
213.144.49.59:interesaportal.renfe.es
213.144.33.35:w5.renfe.es
213.144.49.59:tuclubave.renfe.es
213.144.49.59:Tuclubave.renfe.es
80.239.224.25:Www.renfe.es
213.144.50.64:mercancias.renfe.es
213.144.49.9:mail.renfe.es
80.239.224.25:Www.renfe.es
213.144.33.206:web02.renfe.es
213.144.33.35:clubave.renfe.es
80.239.224.25:www.renfe.es
213.144.33.35:w5.renfe.es
213.144.33.206:asista.renfe.es
213.41.75.72:boletines.renfe.es
213.144.33.20:w1.renfe.es
80.239.224.25:Horarios.renfe.es
80.239.224.25:horarios.renfe.es
213.144.49.59:interesaportal.renfe.es


[+] Virtual hosts:
----------------
213.144.33.20:w1.renfe.es
213.144.33.35:clubave.renfe.es
213.144.33.35:w5.renfe.es
213.144.49.9:mail.renfe.es
213.144.49.136:infocer.renfe.es
213.144.33.206:asista.renfe.es
213.144.33.206:web02.renfe.es
213.41.75.72:boletines.renfe.es
213.41.75.72:t.cab09.net
213.41.75.72:grupoplaneta.cab09.net
213.41.75.72:www.help.icrc.org
213.41.75.72:www.tracabilite.org
213.41.75.72:www.initialservices.fr
213.41.75.72:lalettre.promotelec.com
213.41.75.72:dons.lesvillagesdenfants.com
213.41.75.72:info.geoportail.fr
213.41.75.72:gazdefrancedolcevita3.gdfsuez.com
213.41.75.72:don.lesvillagesdenfants.com
213.41.75.72:news.cegid.fr
213.41.75.72:soutenons.fondation-autisme.org
213.41.75.72:info.ign.fr
213.144.49.59:www.enpuntorenfe.es
213.144.49.59:www.enpuntorenfe.com
213.144.49.59:revistaenpunto.com
213.144.49.59:revistaenpunto.es
213.144.50.64:mercancias.renfe.es


De esta salida sacamos diferentes tipos de información:

  1. Listado de cuentas de correo, que nos puede servir tanto para obtener un listado de usuarios válido para posteriormente hacer ataques de diccionario a contraseñas, como para descubrir nuevos dominios desconocidos (un @cosme.renfe.es nos muestra la existencia de este dominio).
  2. Subdominios del dominio que hemos buscado, y algunos otros que estén alojados en los mismos servidores donde se han encontrado. Puede que sean nuevos dominios pertenecientes a la empresa que estamos auditando, o puede que se trate de un hosting compartido y no tengan nada que ver.
  3. Listado de IPs que alojan los nombres de hosts encontrados. A partir de ellos vamos a poder sacar, mediante whois, los rangos completos.

Yo os recomiendo un poco de grepping y awk para separar la información y hacerla más sencilla de manejar:

$ ./theHarvester.py -d renfe.es -l 200 -b all > renfe_theharvester.txt
$ cat renfe_theharvester.txt | grep "@" | grep -v edge-security | awk -F"@" '{print $1}' | sort | uniq > renfe_theharvester_users.txt
$ cat renfe_theharvester.txt | grep "@" | grep -v edge-security | awk -F"@" '{print $2}' | sort | uniq > renfe_theharvester_maildomains.txt
$ cat renfe_theharvester.txt | grep "renfe.es" | grep ":" | awk -F":" '{print $1}' | sort -n | uniq > renfe_theharvester_ips.txt
$ cat renfe_theharvester.txt | grep "renfe.es" | grep ":" | awk -F":" '{print $2}' | sort | uniq > renfe_theharvester_hosts.txt
$ cat renfe_theharvester.txt | grep -v "renfe.es" | grep ":" | grep -v "+" > renfe_theharvester_alternatehosts.txt

Si nos centramos en los rangos de IPs y hacemos whois a alguna de ellas, vemos que podemos reducir la información obtenida a la siguiente:

  • 80.239.224.25 -> 80.239.224.0 - 127 (Akamai)
  • 213.144.32.0 - 213.144.63.255 (Renfe)
  • 213.41.75.72 -> 213.41.75.0 - 255 (Colt)

A pesar de que theHarvester ya nos ha hecho una obtención de hosts virtuales de las IPs encontradas... ¿qué pasa con las IPs de las que no ha encontrado nada pero que están en el mismo rango? Si por ejemplo tuvieramos el dominio renfe.es en una serie de IPs y el dominio renfo.com (inventándomelo) en otra serie de IPs, no encontraríamos nada sobre este dominio.

En el siguiente post veremos como lo haremos.

jueves, 6 de octubre de 2011

Ponente en SOURCE Conferences Barcelona 2011

Los próximos 16 y 17 de Noviembre estaré en las SOURCE Conferences Barcelona 2011, participando como ponente en el track en español.


La charla se titula "Canales Cubiertos en Redes Sociales", y básicamente tratará el tema de los canales cubiertos que se han empleado toda la vida a través de las cabeceras IP, TCP o en determinados campos de otros protocolos, pero dándole una vuelta más, y yéndonos a la capa de aplicación y más allá, hasta las aplicaciones web como son las redes sociales.

Como prueba de concepto, se ha desarrollado una herramienta llamada FaceCat (FaceBook NetCat), que realiza más o menos la misma funcionalidad que NetCat en cuanto a relay de puertos, pero empleando la red social FaceBook como pasarela por la cual la información será transmitida.

Este tipo de canales cubiertos van a poner cada vez más difícil a los administradores de red la protección perimetral de una compañía, ya que a nivel de red pueden llegar a resultar indistinguibles de tráfico normal de la aplicación, y dado que opera por encima de la capa de aplicación, va a atravesar sin problemas todo tipo de filtrado de puertos o proxies.

Podeis ver el resto de las charlas AQUÍ.
Me hubiera gustado romper el hielo de las charlas en inglés en estas conferencias, pero al final estoy en el track en español, a no ser que alguien se ponga enfermo, en cuyo caso me presentaré voluntario para cubrirle, por supuesto xD

Espero veros por Barcelona, el 16 de Noviembre, a eso de las 12:00.
FaceBook, no me leais, que no quiero que me fastidiéis la demo ;P

martes, 4 de octubre de 2011

Securizando Android para un uso corporativo (parte 3)

Contribución de Angel Alonso-Párrizas que continúa el post anterior.

Continuando con el post anterior en el que explicamos como deshabilitar la instalación de software, es necesario deshabilitar el software preinstalado para Android así como los ejecutables del sistema operativo que son innecesarios. 

Para deshabilitar los binarios es tan sencillo como borrarlos o bien revocar los permisos.  Esto ser hará con un script de manera automática que pondremos mas abajo.
Este mismo proceso se seguirá de manera análoga para deshabilitar el software preinstalado que no necesitamos.

Controles adiciones de seguridad

Para implementar una política de contraseñas seguras de manera centralizada, Google ha desarrollado una herramienta disponibles para empresas accesible desde el Google Apps. La herramienta va vinculada a una cuenta de Google Business que cuestan 40$ anuales.
Con esta herramienta se puede definir:
  • Forzar a usar contraseñas para acceder al dispositivo
  • Forzar a crear una contraseña segura
  • Forzar a cambiar la contraseña
  • Forzar a no rehusar las N contraseñas últimas
  • Bloquear el dispositivo después de N minutos
  • Umbral en el número de contraseñas erróneas hasta que el dispositivo se borra
  • Permitir el uso de cámara o no

Además de la política de contraseñas es posible también:
  • Localizar el dispositivo por GPS con Google Maps
  • Borrar el dispositivo remotamente
  • Bloquear el dispositivo remotamente

Otra herramienta útil para añadir seguridad al dispositivo es Autowipe. Las funcionalidades que usamos en este proyecto, que no son las únicas de ésta aplicación,  son:
  • Borrado del dispositivo mediante SMS con una contraseña
  • Borrado del dispositivo si la SIM es cambiada


La última herramienta que usamos es el conocido antivirus de AVG. Este antivirus tiene varias funcionalidades, pero las que no son de utilidad son:
  • Escaneo de aplicaciones en busca de malware
  • Navegación segura



Securizando el dispositivo 

El proceso de boot de Android es similar al de linux. Existen una serie de scripts de inicio que se ejecutan cuando el sistema se inicia. Sin embargo, el principal script de arranque init.rc  se encuentra en la ramdisk por lo que para modificarlo habría que modificar la imagen de arranque. Para evitar esto, la versión de la ROM, hace una llamada a un script llamado userinit.sh almacenado en /data/local. Así, tan solo necesitamos crear nuestro propio script, subirlo a ese directorio del Android y darle permisos de ejecución.

#!/system/bin/sh
# Customize some parameters and lockout the SO

mount -o rw,remount /system
# run dropbear / SSH
/system/xbin/dropbear -g -s
# Disable Bluetooth
chmod 000 /dev/ttyMSM0
chmod 000 /dev/ttyHS0
# stop market if running
killall com.android.vending
# hardening TCP/IP stack for IPV4
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 #ICMP broadcast
sysctl -w net.ipv4.conf.all.accept_redirects=0 # ICMP redirects ipv4
sysctl -w net.ipv6.conf.all.accept_redirects=0 #ICMP redirects ipv6
sysctl -w net.ipv4.conf.all.send_redirects=0 # ICMP redirects
sysctl -w net.ipv4.conf.all.accept_source_route=0 #source routing disable
sysctl -w net.ipv4.conf.all.forwarding=0 #Forwarding traffic
sysctl -w net.ipv4.conf.all.rp_filter=1
sysctl -w net.ipv4.conf.all.log_martians=1 #filter martians
sysctl -w net.ipv4.tcp_max_syn_backlog=1280 # TCP syn half-opened
sysctl -w net.ipv4.ip_forward=0
# Removing/ disabling unnecessary binaries. Some of them have access to Internet
rm -f /system/xbin/irsii
rm -f /system/xbin/nano
rm -f /system/xbin/nc
rm -f /system/xbin/netserver
rm -f /system/xbin/netperf
rm -f /system/xbin/opcontrol
chmod 740 /system/xbin/scp
chmod 740 /system/xbin/rsync
chmod 740 /system/xbin/sdptest
chmod 740 /system/xbin/ssh
chmod 740 /system/xbin/strace
chmod 000 /system/xbin/tcpdump
chmod 740 /system/xbin/vim
chmod 000 /system/bin/bluetoothd
chmod 750 /system/bin/iptables
chmod 750 /system/bin/ping
chmod -s /system/bin/ping
# Run Iptables
/data/local/iptables.sh
## This is the last step of the hardening
## This will be uncommented only when the system is configured
## This will lockout the system and will only give access through SSH
# Removing unnecessary software
# This must be uncomment at last step
# do a backup before
/data/local/removesoftware.sh
# disable the Packet Management binary
chmod -x /system/bin/pm
# Disable the adbd daemon
mount -o rw,remount -t rootfs rootfs /
chmod -x /sbin/adbd
mount -o ro,remount -t rootfs rootfs /
# disable the SD card
umount /mnt/sdcard/.android_secure
umount -l /mnt/sdcard
mount -o ro,remount /system

Este script llama a dos scritpts: iptables.sh y removesoftware.sh. (iptables.sh ya se comentó en el primer post)

#!/system/bin/sh
# Remove and disable unnecessary software
cd /system/app/
rm /system/app/AndroidTerm.apk
rm /system/app/Bluetooth.apk
rm /system/app/Development.apk
rm /system/app/FM.apk
rm /system/app/CarHomeGoogle.apk
rm /system/app/GoogleFeedback.apk
rm /system/app/GoogleQuickSearchBox.apk
rm /system/app/FileManager.apk
rm /system/app/HTMLViewer.apk
rm /system/app/MarketUpdater.apk
rm /system/app/Music.apk
rm /system/app/RomManager.apk
rm /system/app/SoundRecorder.apk
rm /system/app/Talk.apk
rm /system/app/Torch.apk
rm /system/app/Vending.apk
chmod 000 /data/data/com.android.bluetooth
chmod 000 /data/data/jackpal.androidterm2
chmod 000  /data/data/com.android.development
chmod 000 /data/data/com.android.fm
chmod 000 /data/data/com.android.htmlviewer
chmod 000  /data/data/com.android.music
chmod 000 /data/data/com.android.musicvis
chmod 000  /data/data/org.openintents.cmfilemanager
chmod 000 /data/data/com.android.soundrecorder
chmod 000 /data/data/com.google.android.carhome
chmod 000  /data/data/com.google.android.apps.books
chmod 000 /data/data/com.google.android.googlequicksearchbox
chmod 000 /data/data/com.android.vending
chmod 000 /data/data/com.android.vending.updater
chmod 000  /data/data/com.koushikdutta.rommanager

Una vez se ejecuten estos scripts el sistema esta securizado y solo sera accesible por SSH a través del túnel.
Lo que hay que hacer para configurar el dispositivo desde el principio es lo siguiente:

1.     Instalar Cyanogenmod
2.     Instalar Google Apps
3.     Instalar la aplicación Google App Device Policy
4.     Instalar el Antivirus
5.     Instalar Autowipe
6.      Configurar la cuenta de Google enterprise. Se introduce una contraseña segura en el dispositivo.
7.      Configurar el antivirus: frecuencia de autoscan, de actualización y  la navegación segura. 
9.     Configurar el  VPN: importar el certificado y configurar los parámetros del VPN
10.  Configurar SSH
11.  Copiar iptables.sh, removesoftware.sh y userinit.sh script a /data/local. Cambiar los permisos de estos ficheros a 700.
12.  Reiniciar el sistema.

Con esto finalizamos esta serie de artículos sobre la securización de android para entornos corporativos. No dudéis en dejar comentarios sobre cualquier duda que pueda haberos surgido.

jueves, 29 de septiembre de 2011

Securizando Android para un uso corporativo (parte 2)

Contribución de Ángel Alonso-Párrizas que continua el post anterior:

En el primer post explicamos como configurar el túnel VPN. Ahora vamos a utilizar ese túnel para gestionar de manera remota el dispositivo mediante SSH. Esto nos permitie deshabilitar el acceso al smartphone por USB y así garantizar que sólo las persona autorizadas dentro de la compañía acceden al mismo. Además, el túnel es de gran utilidad para instalar software de manera remota y controlada, ya que unos de los objectivos del proyecto, como se mencionó en el post anterior, es evitar que se instale software no autorizado.

Configuración de SSH 

En primer lugar, generamos las claves RSA para el servidor VPS mediante el siguiente comando:

test -d $HOME/sshids || mkdir $HOME/sshids && ssh-keygen -t rsa -f $HOME/sshids/idrsa-1

Esto genera un par de ficheros, la clave privada (idrsa-1) y la clave pública (idrsa-1.pub). La clave pública hay que importarla a la tarjeta SD, para a su vez poder incluirlo en el fichero authorized_keys en Android.

En segundo lugar, hay que configurar el servidor SSH en el smarphone, y para ello es necesario ejecutar los siguientes comandos:

adb shell # abrimos una shell
mkdir /data/dropbear # creamos el directorio dropbear
chmod 755 /data/dropbear # cambiamos los permisos
mkdir /data/dropbear/.ssh # creamos el directorio .ssh
chmod 700 /data/dropbear/.ssh # cambiamos los permisos
mv /sdcard/authorized_keys /data/dropbear/.ssh/ # copiamos la clave publica del cliente 
chown root: /data/dropbear/.ssh/authorized_keys # cambiamos el propietario 
chmod 600 /data/dropbear/.ssh/authorized_keys # cambiamos los permisos
dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_host_key # generamos la clave RSA
dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key # generamos la clave dss 

Con esto ya se tiene configurado el servidor. Ahora, solo hay que lanzarlo para que la autenticación funcione únicamente con claves, en lugar de usuario y password. En el siguiente post veremos como se se ejecuta el servidor ssh de manera automatica al iniciar el dispositivo. 
En una shell en Android ejecutamos el comando dropbear -s -g y a continuación en el VPS usaremos el cliente SSH con el parámetro ¨-i¨ y el fichero con la clave privada, algo del estilo: ssh -p 22 root@172.16.1.99 -i idrsa-1
Un ejemplo del la negociación SSH y del acceso al sistema se puede ver en la captura:


Al estar el SSH corriendo es posible subir cualquier fichero mediante SCP, así pues tenemos total control mediante shell y SCP sobre el sistema.



Deshabilitar la instalación de software y el acceso por USB

Una vez ya tenemos garantizado el acceso al dispositivo hay que restringir el acceso mediante USB. 
Existen varias maneras de instalar software en Android y una de ellas es mediante el acceso por USB. 
Hay dos binarios fundamentales en Android que son los que dan soporte a estas funcionalidades:
  • /sbin/adbd es el daemon que gestiona el acceso mediante shell 
  • /system/bin/pm es el binario que gestiona la instalación de paquetes
Si quitamos los permisos a estos binario, el acceso por USB/shell no funcionara y además no sera posible instalar software mediante la shell. Más adelante explicaremos como deshabilitar las aplicaciones como el Market, que sirven para instalar aplicaciones por red.  
Este proceso se hace de manera automatica mediante un script que publicaremos en el próximo post.

Un punto importante a destacar es que si queremos instalar algo de manera controlada el administrador de seguridad puede restablecer los permisos del binario /system/bin/pm  (por SSH) e instalar cualquier fichero 'apk' subido por SCP. De esta manera tenemos la posibilidad de instalar nuevas versiones del software o nuevo software.


Deshabilitar bluetooth 

En este proyecto consideré que el bluetooth no era necesario en un entorno corporativo. Puede estar justificado su funcionamiento en algunos casos (por ejemplo algún responsable que necesite hablar por bluetooth mientras conduce) pero a priori el bluetooth no debe poder usarse.
Análogamente a como se deshabilitó la instalación del software, haremos lo mismo con los dispositivos de blueetooth: 

/dev # ls -l /dev/* | grep blue
crw-rw---- 1 bluetoot bluetoot 249, 0 Jun 29 19:48 /dev/ttyHS0
crw-rw---- 1 bluetoot bluetoot 250, 0 Jun 29 19:48 /dev/ttyMSM0
crw-rw---- 1 system bluetoot 10, 223 Jun 29 19:48 /dev/uinput
srw-rw---- 1 bluetoot bluetoot 0 Jun 29 19:49 dbus

Así, si revocamos los permisos a /dev/ttyHS0 y /dev/ttyMSM0 bluetooth no funcionara como podemos ver en los logs:

V/NotificationService( 164): Active profile: Default
I/PROFILE ( 164): Group: Gmail containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: Phone containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: Calendar containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: Email containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: SMS containing : com.android.server.vpn : false
V/ProfileManager( 164): No active group, returning default: Other
V/NotificationService( 164): Pkg: com.android.server.vpn group: Other
E/bluedroid( 164): bt_enable: Timeout waiting for HCI device to come up
D/BluetoothService( 164): Bluetooth state 11 -> 10
V/BluetoothEventRedirector( 791): Received android.bluetooth.adapter.action.STATE_CHANGED
D/SettingsAppWidgetProvider( 791): Widget is from a previous version... Let's update
D/SettingsAppWidgetProvider( 791): No instances yet... Wait for at least one instance to exist before adding global set
tings

Deshabilitar la tarjeta SD

Conectar un dispositivo externo, como un pendrive, a un sistema seguro puede ser peligroso y las políticas corporativas deben de limitar estas situaciones. En el caso de Android, tenemos varios problemas con la tarjeta SD:
  •  La ausencia de cifrado de datos
  •  El modelo de permisos. Al ser FAT, una aplicación con permisos de lectura/escritura tiene acceso a toda la tarjeta independientemente de los permisos de las aplicaciones dueñas de los datos.
  • Algunas vulnerabilidades que aprovechan la SD com la descubierta por el colega Mario Ballano.
Por estas razones la tarjeta hay que deshabilitarla desmontándola con 'umount' en tiempo de booting.


lunes, 26 de septiembre de 2011

Securizando Android para un uso corporativo (parte 1)

Contribución de Ángel Alonso-Párrizas:

Esta serie de posts sobre Android son el resultado de un trabajo hecho como parte del proyecto final del Máster en seguridad y análisis forense en la Universidad de Dublin City University. El trabajo original con título "Securely deploying Android devices¨ se puede encontrar en inglés aquí, así como la publicación del paper en la web del SANS Institute. Como nada del proyecto ha sido publicado en castellano aprovecho el blog del colega José Selvi, al cual tengo el placer de conocer desde nuestros años mozos en la Universidad, para exponer el trabajo en la lengua de Cervantes :)

Antes que nada comentar que la idea de este proyecto surgió cuando trabaja en una compañía en la que necesitábamos dar cobertura al uso de Android de manera segura en entornos corporativos. Así que algunas de las funcionalidades que son limitadas en este proyecto pueden no tener tanto sentido si se trata de un usuario final (como por ejemplo la posibilidad de instalar software). Teniendo esto en cuenta, vamos al lío.

Android está sujeto a los mismos problemas de seguridad que cualquier sistema operativo moderno con la particularidad de que el acceso a Internet es itinerante, es decir, puede usarse cualquier conexión WiFi o 3G de manera dinámica. Esto implica ciertos riesgos, como por ejemplo ataques de tipo sniffing. Además, el modelo de distribución de software vía los distintos repositorios (como Market) lo hacen muy vulnerable al malware. Estos son los puntos más débiles de Android pero no los únicos.

Si entrar mucho al detalle, el modelo de seguridad de Android a nivel de Sistema Operativo es robusto ya que las aplicaciones se ejecutan en la máquina virtual (Dalvik) de manera aislada (como en un sistema operativo tradicional donde cada proceso tiene su espacio de memoria). Además, el sistema de ficheros sigue el modelo de permisos de Linux. La diferencia fundamental radica en que en lugar de múltiples usuarios tenemos múltiples aplicaciones (cada aplicación tiene asignado un UID).
Con este modelo es posible definir con cierta granularidad, cuando se desarrolla la aplicación, que permisos necesita ésta para ejecutarse (esto se hace en un fichero llamado AndroidManifest.xml), pero es el usuario final quién tiene la última palabra al aceptar (o no) los permisos. Los problemas que subyacen de este modelo son dos: que un desarrollador con malas intenciones cree un fichero AndroidManifest.xml con más permisos de los necesarios y que un usuario acepte los permisos de una aplicación con más permisos de los requeridos. Si hablamos de un entorno corporativo, donde las políticas de seguridad deben restringir la instalación de cualquier software, aún hay más motivo para mitigar estos riesgos.

Teniendo en cuenta los problemas expuestos de manera resumida arriba, los objetivos principales de este trabajo se pueden resumir en lo siguientes puntos:

  1. Implementar un canal de comunicación seguro a través de VPN (OpenVPN) y enrutar todo el tráfico a través del túnel. Implementar políticas de filtrado de tráfico entrante y saliente.
  2. Limitar el acceso a la administración del dispositivo y centralizar su acceso. El acceso al dispositivo sólo debe ser permitido a los administradores de seguridad a través de SSH con claves.
  3. Deshabilitar la instalación del software. Solo debe instalarse software autorizado por las políticas de seguridad corporativas y el usuario no debe poder instalar nada.
  4. Implementar una política de contraseñas alineados con los estándares de la compañía. El dispositivo debe de borrarse después de un número determinado de fallos en la contraseña.
  5. Habilitar funcionalidades remotas de seguridad, como por ejemplo el borrado remoto, la localización a través de GPS (Google Maps) o el borrado mediante mensaje de texto.
  6. Incluir capas adicionales de seguridad como el antivirus.
  7. Deshabilitar servicios y dispositivos inseguros o innecesarios, como por ejemplo el bluetooth o la tarjeta SD.

Las herramientas que son necesarias para este proyecto son:
  • Un smartphone al que se le pueda instalar la versión de ROM Cyaongenmod (en el caso de este proyecto fue un HTC Desire).
  • Un servidor con Linux (para este proyecto use un VPS ubicado en Holanda).
  • El kit de desarrollo SDK para Android (indistintamente en Linux, Mac o Windows).
  • Tarjeta 3G y un punto de acceso WiFi.
  • Algunas herramientas como OpenVPN, Iptables y SSH.




Cifrar el canal de comunicación e implementar políticas de filtrado

La idea fundamental de este punto consiste en enviar todo el tráfico a través de un túnel VPN-SSL independientemente de que nos conectemos por 3G o WiFi. Para ello, lógicamente, lo primero es establecer el túnel entre el dispositivo y el VPN endpoint (que es el VPS bajo nuestro control o un sistema Linux).
Además, implementaremos políticas de firewall en Android mediante iptables, de tal manera que el único tráfico permitido es el necesario para establecer el túnel y para enrutar todo el tráfico hacia el VPS. Se puede ver un diagrama con la arquitectura en la siguiente figura:


Como muestra la figura, todo el tráfico pasa por el VPN endpoint, por lo que es también posible crear reglas de filtrado con iptables. Así pues es posible aceptar solo el tráfico que las políticas de seguridad de la empresa dictaminen, por ejemplo HTTP/s. Adicionalmente sería posible añadir filtrado de contenido en el trafico web, un antivirus perimetral o lo que se quisiera.
También, es posible crear reglas de filtrado por usuario o rol, es decir, podemos asignar IP estáticas a los clientes del VPN y aplicar reglas en función de la dirección origen.
Con este modelo se consigue 4 cosas: 

  1. Que todo el tráfico vaya cifrado
  2. Que se pueda controlar de manera centralizada qué tráfico es aceptado y cuál debe ser filtrado
  3. Crear reglas en función de un perfil o usuario determinado
  4. Tener visibilidad y poder analizar todo el tráfico en caso de que el smartphone sea comprometido (o porque las políticas de seguridad así lo requieran)

Para establecer el túnel con OpenVPN es necesario únicamente instalar el binario (o compilar) en la máquina linux ya que la ROM de Android antes mencionada ya incluye OpenVPN. A la hora de establecer el túnel es posible hacer uso de certificados o usar una clave privada compartida. Evidentemente, para un entorno corporativo lo aceptable es el uso de clave pública.
El manual de como configurar la CA (autoridad de certificación) para generar certificados y usarlos con OpenVPN lo podéis encontrar en este link. Sin entrar mucho al detalle los pasos importantes para crear la CA y los certificados son:
  • Editar el fichero 'vars' para configurar los datos de los certificados (país, ciudad, correo, etc)
  • Inicializar la PKI y crear la CA con los comandos ./vars; ./clean-all; ./build-ca
  • Generar el certificados del servidor OpenVPN con el comando ./build-key-server server
  • Para cada cliente que queramos que se conecte, hay que generar un certificado con el comando ./build-key client1
  • Generar el fichero que se usara para el intercambio de claves con Diffile Helman mediante el comando ./build-dh

Con esto ya tendremos los ficheros necesarios.



El único paso restante es mover el certificado del cliente, la clave privada y el certificado de la CA a un único fichero con formato 'p12' para poder integrarlo de manera sencilla con Android. Este fichero debe estar protegido con contraseña.
El comando para crear el fichero es:

openssl pkcs12 -export -in client1.crt -inkey client1.key -certfile ca.crt -name cert-master -out client1-all.p12

Una vez tenemos solucionado la parte de los certificados hay que configurar el servidor OpenVPN mediante el fichero server.conf. Básicamente, lo que hay que configurar son los siguientes parámetros:
  • local X.X.X.X # dirección IP del servidor
  • port 80 # puerto donde escucha el servidor VPN
  • proto tcp # protocolo
  • dev tun # interfaz del tunel (no está en modo bridge) 
  • ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt # ubicacion del fichero de la CA
  • cert /etc/openvpn/easy-rsa/2.0/keys/server.crt # ubicacion del fichero del servidor 
  • key /etc/openvpn/easy-rsa/2.0/keys/server.key # ubicación de la clave del servidor 
  • dh /etc/openvpn/easy-rsa/2.0/keys/dh1024.pem # ubicacion del fichero del Diffie Hellman 
  • server 172.16.1.0 255.255.255.0 # red asignada al VPN 
  • push "route 0.0.0.0 0.0.0.0" # rutas que irán através del VPN 
  • client-config-dir ccd # directorio con los ficheros que mapean las IPs por usuario/certificado 
  • cipher AES-256-CBC # algoritmos de cifrado simétrico, clave privada, etc
  • comp-lzo # habilitación de la comprension

Aquí hay que destacar que se eligió el puerto 80/TCP en lugar del estándar de OpenVPN 1194/UDP para saltarse los firewalls en los puntos WiFi que estén filtrados. Es cierto que puede existir sitios donde haya filtrado de contenidos en el tráfico web mediante proxys con lo que podría fallar, pero siempre se pueden usar otros puertos.
La ruta 0.0.0.0/0.0.0.0 es necesaria para enrutar todo el tráfico por el VPN y así conseguir nuestro objectivo.

Para configurar el cliente OpenVPN en Android es tan sencillo como importar el fichero p12 a la tarjeta SD y desde la aplicación OpenVPN de Android abrirlo (hay que introducir  la password configurada anteriormente). Luego, a través de las opciones de configuración es necesario seleccionar la IP del servidor VPN, puerto/protocolo y los valores para la clave simétrica: AES con 256 bit en modo CBC.



Con esto ya se tiene configurado el túnel VPN y lo único que falta es implementar las políticas de firewall en ambos endpoints.

En Android es sencillo usar iptables si se tiene acceso a la shell, así pues podemos crear un script con las políticas de firewall con el siguiente contenido:


#!/system/bin/sh
/system/bin/iptables -F
# Aceptamos el tráfico a lo
/system/bin/iptables -A INPUT -i lo -j ACCEPT
/system/bin/iptables -A OUTPUT -o lo -j ACCEPT
# Política por defecto
/system/bin/iptables --policy INPUT DROP
/system/bin/iptables --policy OUTPUT DROP
/system/bin/iptables --policy FORWARD DROP
# Reglas para el tráfico aceptado
/system/bin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/system/bin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED  -p 6 --sport 22 -j ACCEPT
# Tráfico del tunel VPN 
/system/bin/iptables -A INPUT -i tun0 -p 6 --dport 22 -j ACCEPT
/system/bin/iptables -A INPUT -i tun0 -p 1 -j ACCEPT
# Tráfico hacia el endpoint para establecer el túnel
/system/bin/iptables -A OUTPUT -d x.x.x.x/32 -j ACCEPT
# Trafico que va por el túnel
/system/bin/iptables -A OUTPUT -o tun0 -j ACCEPT

Ahora es necesario crear las reglas en el VPS. Estas incluyen reglas para hacer en forwarding del VPN hacia el interfaz público, reglas de NAT para salir a Internet y las políticas de filtrado que en este caso no he aplicado y las dejo a gusto del consumidor:


#!/bin/sh
/sbin/iptables -F
# Tráfico de/hacia localhost y el VPN aceptado
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT
/sbin/iptables -A INPUT -i tun0 -j ACCEPT
/sbin/iptables -A OUTPUT -o tun0 -j ACCEPT
# Política por defecto. 
/sbin/iptables --policy INPUT DROP
/sbin/iptables --policy OUTPUT ACCEPT
/sbin/iptables --policy FORWARD ACCEPT
# Tráfico aceptado hacia los puertos 80 y 443
/sbin/iptables -A INPUT  -i eth0 -p 6 --dport 80 -j ACCEPT
/sbin/iptables -A INPUT  -i eth0 -p 6 --dport 443 -j ACCEPT
/sbin/iptables -A INPUT -p ALL -i eth0 -m state --state  ESTABLISHED,RELATED -j ACCEPT
# NAT / Forwarding para el tráfico del VPN a Internet
/sbin/iptables -A FORWARD -i tun0 -j ACCEPT
/sbin/iptables -A FORWARD -i tun0 -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -j ACCEPT
/sbin/iptables -A FORWARD -i eth0 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


Con esto ya se tiene configurado el túnel, las políticas de firewall en el smartphone para forzar el tráfico a través del túnel y la política en el endpoint para enrutar el tráfico hacia Internet.