Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sysmana 2016 - Desarrollo seguro de aplicaciones C/C++ en Android con NDK

Sysmana 2016 - Desarrollo seguro de aplicaciones C/C++ en Android con NDK

Charla sobre Desarrollo seguro de aplicaciones C/C++ en Android con NDK, vemos ejemplos de JNI y de posibles vectores de ataque

Nacho Álvarez

January 26, 2016
Tweet

More Decks by Nacho Álvarez

Other Decks in Technology

Transcript

  1. Desarrollo seguro de aplicaciones C/C++ en Android con NDK IES

    Gran Capitán - 26 Enero 2016 Nacho Álvarez @neonigmacdb ✉ [email protected] http://www.nacho-alvarez.es
  2. 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
  3. Eventos • GDG Córdoba https://www.facebook.com/GDGCordobaESP/ • Hack&Beers Córdoba https://twitter.com/hackandbeers •

    BetaBeers Córdoba https://twitter.com/betabeersODB • Codemotion Madrid https://www.facebook.com/Codemotion-Madrid-505998872792272/ • FOSDEM (Free and Open Source Software Developers’ European Meeting) https://fosdem.org 4/36
  4. Índice 1) Estructura de una app Android 2) Introducción al

    NDK 3) Nuestro primer programa con NDK 4) Seguridad en aplicaciones móviles a) Hacking app Android b) Hacking app nativa 5/36
  5. 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
  6. Nuestra primera app NDK public 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
  7. Nuestra primera app NDK public 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
  8. Nuestra primera app NDK public 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
  9. 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
  10. 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
  11. Nuestra primera app NDK apply 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
  12. 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
  13. 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
  14. Hacking app Android Para extraer el código de la parte

    Java (no nativa) • Paso 1: extraer .dex del APK $ unzip program.apk classes.dex Archive: program.apk inflating: classes.dex • Paso 2: utilizar dex2jar para convertir classes.dex a ficheros .class de Java $ d2j-dex2jar.sh./classes.dex dex2jar 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
  15. 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
  16. 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
  17. 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
  18. 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 -sub Bogus Control Flow: -mllvm -bcf Control Flow Flattening: -mllvm -fla Functions annotations 28/36
  19. Referencias • Curso de programación Android sgoliver • Introducción al

    Desarrollo de NDK apps http://es.slideshare.net/RevistaSG/introduccion-al-desarroll o-de-ndk-apps-dev-day-4-woman-condesasama • Conectar programas C/C++ con apps Android http://www.nacho-alvarez.es/index.php/blog/2012/05/02/co nectar-programas-cc-con-aplicaciones-android/ 36/36