25 enero 2012

Seguridad en aplicaciones IOS, Parte I

Después de un tiempo perdido en el espacio dedicando todo mi tiempo y esfuerzo a las auditorias en entornos móviles de varios clientes, vuelvo para ver un tema que hemos tratado poco: la seguridad de aplicaciones en iPhone.

En esta primera serie de entradas voy a explicar el caso más sencillo para hacer una auditoria de caja negra sobre la aplicación, ya que con la aparición del iPhone 3GS y la versión 4.3 de  IOS esta tarea se complica un poco más.

Para seguir este mini tutorial básico, se necesita disponer de un iPhone jailbreakeado con los siguientes paquetes de cydia instalados: OpenSSH, adv-cmds, Erica Utils, Darwin CC Tools, ldone, Gawk, developer-cmds, odcctools y com.ericasadun.utilities, opcionalmente: sqlite3, syslogd, class dump y tcpdump.

Si además vuestro terminal tiene IOS 5, deberéis descargar esta versión del debugger GDB y almacenarla en el directorio /usr/bin. Si por el contrario es inferior, se puede instalar el paquete GNU Debbuger de cydia.

En cuanto a la estación de trabajo, es recomendable tener un editor hexadecimal, un cliente de SSH y una aplicación que permita acceder al directorio root del sistema de ficheros del teléfono, como DiskAid o iFunBox. No vamos a entrar en detalles de cómo se instala todo esto, en casi todas es "next, next, finish" y poco más. Es importante que seamos capaces de hacer un SSH al móvil.

Una vez listos, se procede a buscar una aplicación candidata. Como se ha contado anteriormente, de momento será la más sencilla.

Existen dos complicaciones "nativas", es decir, sin contar con que el desarrollador haya incluido ninguna protección adicional.  La primera viene a raíz del nacimiento del iPhone 3GS, donde cambian el procesador de un ARMv6 a ARMv7 y esta modificación requiere que los binarios  Match-O pasen de ser sencillos a binarios fat, lo que significa que  que incluyen juegos de instrucciones para varios procesadores.

La siguiente complicación es la actualización a IOS 4.3, donde se incluye  una característica de seguridad ya común en otros sistemas operativos: ASLR (address space layout randomization). Aunque su implantación es parcial si la aplicación no es compilada con PIE (position-independent executable).

Este primer experimento se hará con un binario que no sea fat y sin soporte completo de ASLR. La experiencia dice que encontrar binarios simples es complicado, pero que no tengan el soporte completo  es bastante sencillo. ¡Vamos a buscar una!

Las aplicaciones se encuentran en unos directorios llamados "bundles" y su ruta es  /var/mobile/Applications/*/*.app/, dentro de cada uno de estos directorios están los recursos necesarios para su funcionamiento.

Cada aplicación almacena información en un archivo del tipo property list, llamado "Info.plist"  que puede ser XML o binario y que se consulta con la herramienta de comandos plutil, incluido en el paquete com.ericasadun.utilities o con un simple editor de textos.

Con plutil -key se consultan los valores que dan información sobre la aplicación, algunas claves útiles son:
  • CFBundleExecutable: nombre del ejecutable.
  • CFBundleDisplayName: nombre que se muestra de la aplicación.
  • CFBundleName: nombre de la aplicación.
  • CFBundleVersion: versión de la aplicación.
  • CFBundleShortVersionString: versión corta de la aplicación.
  • MinimumOSVersion: versión de IOS necesaria.
  • UIRequiredDeviceCapabilities: requerimientos hardware del dispositivo, como armv7, o acelerometro, teléfono, wifi, etcétera.
  • UIDeviceFamily: si devuelve 1 es software para iPad si devuelve un 2, es compatible con iPad e iPhone.
Y también el archivo plist "iTunesMetadata.plist":
  • itemName: nombre de la aplicación en iTunes.
  • artistName: nombre de la compañía que ha creado el software.
Por ejemplo, de Waze se sacan estos datos:

iPhone:~ root# plutil -key CFBundleExecutable /private/var/mobile/Applications/C3178EAC-0E19-43A7-A92C-994438E59835/Waze.app/Info.plist
Waze
iPhone:~ root# plutil -key MinimumOSVersion /private/var/mobile/Applications/C3178EAC-0E19-43A7-A92C-994438E59835/Waze.app/Info.plist
4.0
iPhone:~ root# plutil -key UIDeviceFamily /private/var/mobile/Applications/C3178EAC-0E19-43A7-A92C-994438E59835/Waze.app/Info.plist

(
    1,

    2
)

Ahora se muestra que binarios son fat y cuales no dentro de los que tenemos instalados para hacer la prueba. La forma más rápida es utilizar el comando "file", que comprobará la cabecera del fichero y si comienza con el magic "cafebabe" .

iPhone:~ root# IFS='
'
iPhone:~ root#  for i in `ls -d /var/mobile/Applications/*/*.app 2> /dev/null | sort -f -t \/ -k 6` ; do b=`plutil -key CFBundleExecutable $i/Info.plist`; file $i/$b; done

/var/mobile/Applications/B78EB987-6D05-4B5A-8C15-053565934EBA/Twitter.app//Twitter: Mach-O fat file with 2 architectures
/var/mobile/Applications/9729C704-D0FA-47A0-82D0-D9528688A61D/Viber.app//Viber: Mach-O fat file with 2 architectures
/var/mobile/Applications/C3178EAC-0E19-43A7-A92C-994438E59835/Waze.app//Waze: Mach-O fat file with 2 architectures
/var/mobile/Applications/F6CF4CAE-1B55-4516-9CDF-98BCBFE72E37/Rapid.app//Rapid: Mach-O executable acorn

Aunque también se puede sacar con un simple "dd" que lea los primeros bytes y "od" para convertirlos a hexadecimal, si devuelve el magic "ca fe ba be", tenemos un fat binary:


iPhone:~ root# dd bs=4 count=1 skip=0 if="/var/mobile/Applications/C3178EAC-0E19-43A7-A92C-994438E59835/Waze.app//Waze" 2> /dev/null | od -A n -t x1 -v | grep "ca fe ba be"
 ca fe ba be
iPhone:~ root# dd bs=4 count=1 skip=0 if="/var/mobile/Applications/F6CF4CAE-1B55-4516-9CDF-98BCBFE72E37/Rapid.app//Rapid" 2> /dev/null | od -A n -t x1 -v | grep "ca fe ba be"
iPhone:~ root#

El soporte ASLR completo, es decir, si se ha compilado con PIE, se consulta de forma similar, buscando el hexadecimal 20 en la posición del byte 26 del binario:

iPhone:~ root# dd bs=1 count=1 skip=26 if="/var/mobile/Applications/F6CF4CAE-1B55-4516-9CDF-98BCBFE72E37/Rapid.app//Rapid" 2> /dev/null | od -A n -t u -v
          0
iPhone:~ root# dd bs=1 count=1 skip=26 if=/private/var/stash/Applications/MobileSafari.app/MobileSafari 2>/dev/null | od -A n -t x1 -v
          20

La herramienta "otool" usada para trabajar con binarios Match-O, también puede facilitar esta información, identificando el flag "PIE" al final de la línea.

iPhone:~ root# otool -hv /private/var/stash/Applications/MobileSafari.app/MobileSafari

/private/var/stash/Applications/MobileSafari.app/MobileSafari:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
   MH_MAGIC     ARM          9  0x00     EXECUTE    43       5004   NOUNDEFS DYLDLINK TWOLEVEL PIE

¡¡Y todo esto solo para identificar una aplicación!! Bueno, realmente con este ejercicio se han visto muchas otras cosas.

Continuaremos muy pronto en las siguientes partes.


3 comments :

Alex dijo...

Muy bueno, me pregunto si algún día podrías hacer un tuto parecido para Android

Un saludo

Alejandro Ramos dijo...

Gracias Alex, la idea es ir publicando algunas cosas que hemos ido haciendo últimamente en auditorias de plataformas móviles, así que cuenta con ello.

Rodolfo dijo...

Pues si que cuesta identificar la aplicación! espero las siguientes partes, a ver en que queda esto!