Pruebas de seguridad en aplicaciones de banca móvil

Basado en un post de José María Luque (JML) en elhacker.net en el que se analizan algunas aplicaciones de bancos españoles para móvil, me di a la tarea de hacer lo siguiente.
Dado que la escala de calificación no está indicada en el post, es conveniente establecer criterios para determinar la calificación y establecer elementos para que las pruebas puedan ser replicadas en otras aplicaciones, ya sea de otros bancos o de otros países.
De esta manera establecí los siguientes criterios adivinando un poco lo que JML intentó decir con cada nivel de calificación:
  • Seguridad buena: la aplicación evita el tipo de ataque.
  • Seguridad media: la aplicación bloquea parcialmente el ataque o de forma inconsistente.
  • Seguridad mala: la aplicación no bloquea el ataque.
También traté de aumentar las pruebas realizadas, aunque solamente logré realizar con éxito una más, de forma que el set de pruebas quedó de la siguiente forma:
  • Modificación de la aplicación y comprobar su posible instalación y funcionamiento: Esta prueba consistió en extraer el APK (Apk Extractor: meher Tools) y posteriormente realizar cambios sencillos en la app; básicamente sustituir algunos iconos que son visibles en las primeras pantallas (APK editor: Steel Works) y volver a generar el APK. Esto significa que la aplicación ha sido modificada y que la firma del desarrollador es distinta a la original. Posteriormente, con el APK descargado hice algunas otras modificaciones utilizando APKStudio, compilando y firmando la aplicación con una llave creada en Android Studio. El objetivo es identificar si existe una validación de la firma o autenticidad de la aplicación bancaria.
  • Comportamiento anti malware, captura pantalla durante su funcionamiento: Utilizando dos apps para capturar pantalla y grabar video de los movimientos en el dispositivo, una que no requiere del dispositivo rooteado (RecMe Screen Recorder: MOBZAPP) y otra que sí lo requiere (Screen Recorder: Hiandroidstudio). El objetivo es identificar si la aplicación bancaria evita de algún modo la captura de pantalla.
  • Comportamiento anti malware, captura teclado y claves: Utilizando un teclado que permite capturar lo que se escribe “Keylogging” (Custom Keyboard: Mehdi Mirzaei). El objetivo es identificar si la aplicación bancaria realiza alguna validación del uso de teclados “no estándares”.
  • APP testean si el dispositivo tiene root: Se rooteo el dispositivo (Superuser: ChainsDD). El objetivo es identificar si la aplicación verifica que el dispositivo está rooteado.
  • Intercepción de mensajes sobre la red: Utilizando Wireshark se capturaron los paquetes salientes del dispositivo. El objetivo es identificar si existe transmisión de información de inicio de sesión o algunos otros datos.
Por último en esta etapa de diseño, comparto con ustedes que hice pruebas en un dispositivo físico (Samsung Galaxy S4, OS 5.0.1) y un dispositivo emulado con virtual box. La imagen viene previamente rooteada y la pueden encontrar en http://mirror1.jarfil.net/androvm.org/Download/ bajo el nombre “androVM_vbox86p_4.1.1_r6.1-20130222-gapps-houdini-flash.ova”

Probé 5 aplicaciones con base en la lista de los bancos más grandes de México publicada por Forbes http://www.forbes.com.mx/los-20-bancos-mas-grandes-en-mexico/. Las aplicaciones probadas fueron:
Después de los resultados de cada una de las pruebas incluí algunas referencias a modo de ayuda, tanto para desarrolladores como para usuarios, a fin de evitar la vulnerabilidad.


En segundo lugar se ejecutaron las pruebas a las aplicaciones mencionadas y los resultados son los siguientes:

Alteración de la APP
BBVA Bancomer: Tanto en la versión creada por el APK editor con su firma, como en la creada con APK Studio con una firma hecha por mí, la aplicación se pudo ejecutar sin alguna restricción o notificación.
RESULTADO: Seguridad mala

Banamex: Tanto en la versión creada por el APK editor con su firma, como en la creada con APK Studio con una firma hecha por mí, la aplicación se pudo ejecutar sin alguna restricción o notificación.
RESULTADO: Seguridad mala

Banorte: Tanto en la versión creada por el APK editor con su firma, como en la creada con APK Studio con una firma hecha por mí, la aplicación se pudo ejecutar sin alguna restricción o notificación.
RESULTADO: Seguridad mala

HSBC: Tanto en la versión creada por el APK editor con su firma, como en la creada con APK Studio con una firma hecha por mí, la aplicación se pudo ejecutar sin alguna restricción o notificación.
RESULTADO: Seguridad mala

Santander: Tanto en la versión creada por el APK editor con su firma, como en la creada con APK Studio con una firma hecha por mí, la aplicación se pudo ejecutar sin alguna restricción o notificación. Al iniciar dice “comprobando versión” pero abrió de cualquier forma.
RESULTADO: Seguridad mala

Recomendaciones para desarrolladores: Utilizar una firma para publicar la app que sea almacenada de forma segura y de ser posible no solamente autocertificada. Posteriormente, al momento de la instalación y en cada ejecución, validar que la firma de la aplicación coincida con la original. Se puede encontrar más información acerca de este proceso en https://www.airpair.com/android/posts/adding-tampering-detection-to-your-android-app

Recomendaciones para usuarios: no permitir la instalación de fuentes desconocidas. El sistema operativo tiene desactivada esta opción por default y no es recomendable habilitarla en equipos que se usan para trabajo en el día a día; está diseñada para desarrolladores y gente que prueba aplicaciones. Solo instalen aplicaciones de las tiendas oficiales.

Capturar pantalla durante el logueo de claves bancarias
Las 5 aplicaciones probadas permitieron la captura de video de la pantalla, tanto con la aplicación que requiere rooteo como con la que no.
BBVA Bancomer
RESULTADO: Seguridad mala

Banamex
RESULTADO: Seguridad mala

Banorte
RESULTADO: Seguridad mala

HSBC
RESULTADO: Seguridad mala

Santander
RESULTADO: Seguridad mala



Recomendaciones para desarrolladores: utilizar el valor “ Window FLAG_SECURE” (http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SECURE), (https://commonsware.com/blog/2012/01/16/secure-against-screenshots.html), en caso de que toda la pantalla quede ilegible puede usarse un validador como este:
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
   getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}


Recomendaciones para usuarios: No hacer root al dispositivo ni habilitar la depuración vía USB; por lo menos las dos opciones que probé requieren una de las dos opciones. Solo instalen aplicaciones de las tiendas oficiales.

Capturar toda actividad del teclado durante el logueo de claves bancarias y actividad
Las 5 aplicaciones probadas permiten la captura del texto y números tecleados durante el inicio de sesión:
Captura de pantalla del archivo generado por el key logger

BBVA Bancomer
RESULTADO: Seguridad mala

Banamex
RESULTADO: Seguridad mala

Banorte
RESULTADO: Seguridad mala

HSBC
RESULTADO: Seguridad mala

Santander
RESULTADO: Seguridad mala

Recomendaciones para desarrolladores:
Opción 1
public boolean isUsingCustomInputMethod() {
   InputMethodManager imm = (InputMethodManager) mCtx.getSystemService(
       Context.INPUT_METHOD_SERVICE);
   List<InputMethodInfo> mInputMethodProperties = imm.getEnabledInputMethodList();
   final int N = mInputMethodProperties.size();
   for (int i = 0; i < N; i++) {
       InputMethodInfo imi = mInputMethodProperties.get(i);
       if (imi.getId().equals(
           Settings.Secure.getString(mCtx.getContentResolver(),
                   Settings.Secure.DEFAULT_INPUT_METHOD))) {
           if ((imi.getServiceInfo().applicationInfo.flags &
               ApplicationInfo.FLAG_SYSTEM) == 0) {
               return true;
           }
       }
   }
   return false;
}

Opción 2
InputMethodManager m = (InputMethodManager) ctx.getSystemService("input_method");
List<InputMethodInfo> a = m.getInputMethodList();
for (InputMethodInfo inputMethodInfo : a) {
       if (inputMethodInfo.getIsDefaultResourceId() == 0) {
           //it is not default
           return false;
       }
}
//it is default
return true;
También puede implementarse una advertencia sobre el uso de otros teclados al iniciar la aplicación en caso de que no se desee bloquear por completo la ejecución al usar otros teclados.

Recomendaciones para usuarios: No instalar teclados de editores no reconocidos, aun de las tiendas oficiales.

Comprobar si la APP testea si el dispositivo está rooteado
BBVA Bancomer:
RESULTADO: Seguridad mala

Banamex
RESULTADO: Seguridad mala

Banorte
RESULTADO: Seguridad mala

HSBC
RESULTADO: Seguridad mala

Santander
RESULTADO: Seguridad mala
Se utiliza la aplicación Root Checker: Joeikrym para identificar si el dispositivo está rooteado.

Recomendaciones para desarrolladores:
Validar al momento de la instalación y en cada ejecución que el dispositivo no ha sido rooteado.
De manera muy sencilla, si el comando Runtime.getRuntime().exec("su"); devuelve root, bloquear la aplicación.
De forma más detallada:
@Override
protected void onResume() {
   // TODO Auto-generated method stub
   super.onResume();
   if(new DeviceUtils().isDeviceRooted(getApplicationContext())){
       showAlertDialogAndExitApp("This device is rooted. You can't use this app.");
   }
}

public void showAlertDialogAndExitApp(String message) {

   AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
   alertDialog.setTitle("Alert");
   alertDialog.setMessage(message);
   alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
           new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int which) {
                   dialog.dismiss();
                   Intent intent = new Intent(Intent.ACTION_MAIN);
                   intent.addCategory(Intent.CATEGORY_HOME);
                   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                   startActivity(intent);
                   finish();
               }
           });

   alertDialog.show();
}
DeviceUtis.java was a Utility class which returned if a device is rooted or not.
public class DeviceUtils {

   public Boolean isDeviceRooted(Context context){
       boolean isRooted = isrooted1() || isrooted2();
       return isRooted;
   }

   private boolean isrooted1() {

       File file = new File("/system/app/Superuser.apk");
       if (file.exists()) {
           return true;
       }
       return false;
   }

   // try executing commands
   private boolean isrooted2() {
       return canExecuteCommand("/system/xbin/which su")
               || canExecuteCommand("/system/bin/which su")
               || canExecuteCommand("which su");
   }
}
Alternativamente puede implementarse una notificación con una advertencia de que ejecutar la aplicación en un dispositivo rooteado puede ser vulnerable, si no se quiere bloquear por completo la ejecución.

Recomendaciones para usuarios: No hacer root a los dispositivos que se utilicen para este tipo de transacciones; en general no hacerlo para dispositivos de uso normal.

Intercepción de mensajes sobre la red
Utilizando Wireshark se capturaron los mensajes salientes del dispositivo; utilizando un firewall se bloquearon todas las aplicaciones, menos la de la prueba para facilitar el filtrado de mensajes.
BBVA Bancomer: Manda el número de sesión en texto plano, pero no me fue posible replicar la sesión con el número. El resto de la información, tanto el inicio de sesión como las transacciones parecen viajar cifradas.
RESULTADO: Seguridad media

Banamex: Manda el número de cliente en texto plano. El resto de la información, tanto el inicio de sesión como las transacciones parecen viajar cifradas.
RESULTADO: Seguridad media


Banorte: No fue posible detectar algún dato en los paquetes capturados.
RESULTADO: Seguridad buena

HSBC: manda el nombre del cliente en texto plano. El resto de la información, tanto el inicio de sesión como las transacciones parecen viajar cifradas.
RESULTADO: Seguridad media

Santander: Manda el número de cliente en texto plano. El resto de la información, tanto el inicio de sesión como las transacciones parecen viajar cifradas.
RESULTADO: Seguridad media

Recomendaciones para desarrolladores: Enviar todo el tráfico en una sesión sobre SSL, TLS o algún mecanismo de cifrado asíncrono.
Recomendaciones para usuarios: No usar aplicaciones de banca en redes públicas, monitorear que no existan dispositivos desconocidos en las redes propias. Si es necesario usar redes públicas utilizar una VPN.

Resumen
Se calificó con:
  • -1 a las aplicaciones con seguridad baja
  • 0 a las aplicaciones con seguridad media
  • +1 a las aplicaciones con seguridad alta

Modificación de la aplicación
Captura pantalla
Captura teclado
Dispositivo con root
Intercepción de mensajes

Total
BBVA Bancomer
-1
-1
-1
-1
0
-4
Banamex
-1
-1
-1
-1
0
-4
Banorte
-1
-1
-1
-1
1
-3
HSBC
-1
-1
-1
-1
0
-4
Santander
-1
-1
-1
-1
0
-4

Si bien la conclusión es que la aplicación de Banorte es la menos insegura, no lo es por mucho y todas las que se probaron reprueban. Aquí un mensaje a los desarrolladores para que enfoquen sus esfuerzos en desarrollo seguro.

Actualización 13:14 2016/04/12: Todo lo anterioir no significa que las aplicaciones no deban ser utilizadas, de hecho en lo personal utilizo varias de ellas, simplemente hayq ue tener cuidado y seguir las recomendaciones para usuarios, de forma que mantengamos nuestros datos y sobre todo nuestro patrimonio seguros.

Comentarios

Entradas populares de este blog

Investigación Forense con Autopsy

Preocupaciones y propuestas sobre los cambios en la ley Telecom y la CURP biométrica

¿Cómo saber si mi certificación ISO 27001 es legítima?