Desarrollo seguro de aplicaciones C/C++ en Android con NDK
IES Gran Capitán - 26 Enero 2016Nacho Álvarez
@neonigmacdb✉ [email protected]
http://www.nacho-alvarez.es
Acerca de mí● Ingeniero en Informática por la UCO● Trayectoria profesional:
○ Soporte Servicio Informática UCO○ Desarrollo Web○ Desarrollo / Integración distribuciones GNU/Linux○ Android mobile + backend developer (WUL4)○ Actualmente: Área de Innovación (Redsys)
2/36
Acerca de mí● Involucrado en la Innovación de soluciones
de medios de pago
3/36
Eventos● GDG Córdoba
https://www.facebook.com/GDGCordobaESP/
● Hack&Beers Córdobahttps://twitter.com/hackandbeers
● BetaBeers Córdobahttps://twitter.com/betabeersODB
● Codemotion Madridhttps://www.facebook.com/Codemotion-Madrid-505998872792272/
● FOSDEM (Free and Open Source Software Developers’ European Meeting)https://fosdem.org 4/36
Índice1) Estructura de una app Android
2) Introducción al NDK
3) Nuestro primer programa con NDK
4) Seguridad en aplicaciones móvilesa) Hacking app Androidb) Hacking app nativa
5/36
Estructura de app Android
6/36
Tutoriales Android● http://www.sgoliver.net/blog/curso-de-programacion-
android/indice-de-contenidos/
● https://github.com/sgolivernet/curso-android-src
● https://github.com/sgolivernet/curso-android-src-as
7/36
Introducción al NDK● Conjunto de herramientas que permiten incorporar
código nativo (C/C++) en aplicaciones Android.
● Con NDK generas librerías binarias para cada arquitectura de procesador (arm, armv7, x86, etc)
● Las librerías binarias se pueden invocar desde Java por medio de JNI (Java Native Interface).
8/36
¿Por qué usar NDK?
9/36
Estructura de app NDK
10/36
Nuestra primera app NDKpublic class AndroidActivity extends Activity { static {
System.loadLibrary("mixed_sample"); }
private Context context;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);context = this;String greeting = SayHello("neonigma");Saludo saludo = new Saludo(greeting);Saludar.enviarSaludo(context, saludo);
}
public native String SayHello(String name);}
src/main/java/blog/neonigma/AndroidActivity.java
11/36
Nuestra primera app NDKpublic class Saludo { private String mensajeSaludo;
public Saludo(String mensajeSaludo) { this.mensajeSaludo = mensajeSaludo; }
public String getMensajeSaludo() { return mensajeSaludo; }}
src/main/java/blog/neonigma/Saludo.java
12/36
Nuestra primera app NDKpublic class Saludar {
public static void enviarSaludo(Context context, Saludo saludo) { Toast.makeText(context, saludo.getMensajeSaludo(), Toast.LENGTH_LONG).show(); }}
src/main/java/blog/neonigma/Saludar.java
13/36
Nuestra primera app NDK#include <jni.h>
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
extern "C"
{
JNIEXPORT jstring JNICALL Java_blog_neonigma_AndroidActivity_SayHello(JNIEnv *env, jobject thiz, jstring name)
{
src/main/jni/code.cpp
14/36
Nuestra primera app NDK std::string variableImportante = "3.14";
try
{
const char *myName = env->GetStringUTFChars(name, 0);
std::string nameCPP(myName);
nameCPP = "Hello: " + nameCPP;
return env->NewStringUTF(nameCPP.c_str());
}
catch (exception &ex)
{
const char *error = "Failed";
return env->NewStringUTF(error);
}
}
}
src/main/jni/code.cpp
15/36
Nuestra primera app NDKapply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 19
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "src.blog.neonigma"
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 19
versionCode = 1
versionName = "1.0"
}
}
build.gradle
16/36
Nuestra primera app NDK android.ndk {
moduleName = "mixed_sample"
stl = "stlport_static"
CFlags.addAll("-fexceptions")
cppFlags.addAll("-fexceptions")
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.pro"))
}
}
}
build.gradle
17/36
Demo time!
18/36
Hacking app Android● Una app Android se empaqueta dentro de un fichero APK
● Estos ficheros son solamente ficheros ZIP conteniendo recursos y un archivo Dalvik Executable (.dex)
● Con las herramientas adecuadas, podemos extraer el código Java incluido dentro del fichero .dex
● Elementos como los recursos gráficos y el fichero AndroidManifest.xml no van ofuscados 19/36
Hacking app AndroidPara extraer el código de la parte Java (no nativa)
● Paso 1: extraer .dex del APK$ unzip program.apk classes.dexArchive: program.apk inflating: classes.dex
● Paso 2: utilizar dex2jar para convertir classes.dex a ficheros .class de Java$ d2j-dex2jar.sh./classes.dexdex2jar classes.dex -> ./classes-dex2jar.jar
● Paso 3: utilizamos el decompiler JD-GUI para extraer el código fuente$ ./jd-gui classes.dex.dex2jar.jar
20/36
Hacking app Android
21/36
Hacking app Android● Necesitamos ofuscación defensiva: Proguard /
Dexguard
● ProGuard optimiza, reduce y ofusca el código de aplicaciones Android
● Solo funcionará cuando hagamos la exportación a APK
● Las reglas se escriben en fichero proguard-rules.pro 22/36
Hacking app Android● Ejemplo proguard (identificar lo que se excluye):
-optimizations !code/simplification/arithmetic
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
} 23/36
Hacking app Android
No obstante, hay que ir probando reglas de ofuscación....
24/36
Desarrollo apps NDK
25/36
Hacking app nativa● El código nativo se incluye dentro del apk como ficheros .so
● Este código está compilado y ensamblado contra una arquitectura específica (ARM, x86, …)
● En teoría es difícil leer un fichero ensamblado, pero… hay herramientas que ayudan: IDA como disassembler, apktool para desempaquetado y reempaquetado, etc.
26/36
Hacking app nativa
27/36
Hacking app nativa● Cosas que podemos hacer:
○ Ocultar nuestras funciones y variables de la tabla de símbolos
○ Ofuscar el código, por ej. con O-LLVM
LOCAL_CFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden
Instructions Substitution: -mllvm -subBogus Control Flow: -mllvm -bcfControl Flow Flattening: -mllvm -flaFunctions annotations
28/36
Hacking app nativa
Sin ofuscación Con ofuscación 29/36
Caso prácticoCharlemos sobre un caso real...
30/36
Ejemplo
31/36
32/36
33/36
Ejemplo práctico
34/36
Ejemplo práctico
¡Nada de ser malvadou!35/36
Referencias● Curso de programación Android sgoliver
● Introduccion al Desarrollo de NDK appshttp://es.slideshare.net/RevistaSG/introduccion-al-desarrollo-de-ndk-apps-dev-day-4-woman-condesasama● Conectar programas C/C++ con apps Androidhttp://www.nacho-alvarez.es/index.php/blog/2012/05/02/conectar-programas-cc-con-aplicaciones-android/ 36/36