Desarrollo seguro de aplicaciones C/C++ en Android con NDK

Anuncio
Desarrollo seguro de aplicaciones
C/C++ en Android con NDK
IES Gran Capitán - 26 Enero 2016
Nacho Álvarez
@neonigmacdb
✉ neonigma@gmail.com
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ó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
Í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
Estructura de app Android
6/36
Tutoriales Android
● http://www.sgoliver.net/blog/curso-de-programacionandroid/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 NDK
public class AndroidActivity extends Activity {
static {
System.loadLibrary("mixed_sample");
}
src/main/java/blog/neonigma/AndroidActivity.java
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);
}
11/36
Nuestra primera app NDK
public class Saludo {
private String mensajeSaludo;
src/main/java/blog/neonigma/Saludo.java
public Saludo(String mensajeSaludo) {
this.mensajeSaludo = mensajeSaludo;
}
public String getMensajeSaludo() {
return mensajeSaludo;
}
}
12/36
Nuestra primera app NDK
public class Saludar {
src/main/java/blog/neonigma/Saludar.java
public static void enviarSaludo(Context context, Saludo saludo) {
Toast.makeText(context, saludo.getMensajeSaludo(), Toast.LENGTH_LONG).show();
}
}
13/36
Nuestra primera app NDK
#include <jni.h>
#include <iostream>
src/main/jni/code.cpp
#include <string>
#include <stdexcept>
using namespace std;
extern "C"
{
JNIEXPORT jstring JNICALL Java_blog_neonigma_AndroidActivity_SayHello(JNIEnv *env, jobject thiz, jstring name)
{
14/36
Nuestra primera app NDK
std::string variableImportante = "3.14";
try
src/main/jni/code.cpp
{
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);
}
}
}
15/36
Nuestra primera app NDK
apply plugin: 'com.android.model.application'
build.gradle
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"
}
}
16/36
Nuestra primera app NDK
android.ndk {
build.gradle
moduleName = "mixed_sample"
stl = "stlport_static"
CFlags.addAll("-fexceptions")
cppFlags.addAll("-fexceptions")
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.pro"))
}
}
}
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 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
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
LOCAL_CFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden
○ Instructions
Ofuscar
el código, por ej. con O-LLVM
Substitution: -mllvm -sub
Bogus Control Flow: -mllvm -bcf
Control Flow Flattening: -mllvm -fla
Functions annotations
28/36
Hacking app nativa
Sin ofuscación
Con ofuscación
29/36
Caso práctico
Charlemos 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
● Introducció n al Desarrollo de NDK apps
http://es.slideshare.net/RevistaSG/introduccion-aldesarrollo-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/conectar-programas-cc-conaplicaciones-android/
36/36
Descargar