Securing android applications

  • View
    214

  • Download
    5

  • Category

    Mobile

Preview:

DESCRIPTION

Securing android applications

Citation preview

SECURING

ANDROID

APPLICATIONS

October 2014

http://www.linkedin.com/jmortega1

https://speakerdeck.com/jmortega/

@jmortegac

ARCHITECTURE / DALVIK VM / SANDBOX

ANDROID APPLICATIONS / PERMISSIONS

UTILS EXECUTION ENVIRONMENT

TOOLS ECLIPSE / ANDROID STUDIO

COMPONENTS SECURITY / STATIC ANALYSIS

ENCRYPTION / OBSFUSCATION

REVERSING APK TOOLS

APK ANALYZERS / PENTESTING / FORENSICS

Android Architecture

Dalvik VM

REGISTER-BASED VIRTUAL MACHINE

RUN ON A SLOW CPU WITH LITTLE RAM

OPTIMIZED FOR MOBILE DEVICES

DEX(Dalvik executable)

Dalvik vs ART(4.4)

DALVIK ART

Just-In-Time (JIT)

Compilation

Ahead-Of-Time (AOT)

Compilation

Cache builds up over time

Boot times are faster

Cache is built at first boot

Rebooting device takes

significantly longer

Apps compiled when

executed

Stores Compiled Apps

Consumes much more

internal storage space

Settings>Developer options>Select runtime

Sandbox

Each app gets a unique linux ID(uid) and Groud ID(gid)

Gets own dedicated process and dedicated dalvik VM

Applications are "self-signed" with certificate signed by Developer

Apps can share the data with other apps using content providers

Permissions determine the capacity for communication components

The App Data gets stored in /data/data/<app process> accessible only by UID and GID

(root exceptional)

/data/data

Apps installed by user

Apps installed by google default : play store, play

music , maps

Apps that are manufacturer specific : HTC

sense, touchwiz

Apps that are shipped with stock

rom : browsers

ROOT

Android Applications

APK Generating

ZIP + jarsigner+ zipalign for optimizing apk

Obtain APK

Google Play

Alternative markets (BlackMart, Fdroid, Aptoide)

Apk extractor

http://apps.evozi.com/apk-downloader

Permissions model Android permissions protect

Access to sensitive APIs

Access to content providers

Inter- and intra-application communication

Protection mechanism to interact with other applications

Location (GPS), Camera, Bluetooth, Telephony, SMS/MMS,

Network/data

AndroidManifest.xml

Permissions

Permissions

Be carefull with install

applications

Recommend install some

application to check permissions

Disable automatic updates and

check application permissions

manually each time an application

wants to be installed or updated

Permissions in apps

Check permissions in runtime

PackageManager pm = context.getPackageManager();

int hasPerm = pm.checkPermission(

android.Manifest.permission.WRITE_EXTERNAL_STORAGE,

context.getPackageName());

if (hasPerm != PackageManager.PERMISSION_GRANTED) { // do stuff}

private boolean checkWriteExternalPermission(){

String permission =

"android.permission.WRITE_EXTERNAL_STORAGE";

int res = getContext().checkCallingOrSelfPermission(permission);

return (res == PackageManager.PERMISSION_GRANTED);

}

Protection levels

normal: Default level for not application system, always

granted

dangerous: Higher-Risk permission for access to private data. Requires user approval.

SEND_SMS,ACCESS_FINE_LOCATION

signature Matching signature key. Two apps signed with the

same certificate

system, signatureOrSystem:Same as signature, but also system apps pre-installed like Google Play Services

Permissions in apps

Minimize requested permissions

Users like apps that request few permissions

33% apps request more permissions that they need

Get Camera Pic need android.permission.CAMERA? ContentValues contentValues = new ContentValues();

contentValues.put(MediaStore.Images.Media.DESCRIPTION, "Image capture");

contentValues.put(MediaStore.Images.Media.TITLE, "new image");

Uri uri =

getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,

contentValues);

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

startActivityForResult(intent, 1);

Permissions in apps

Application don`t need permission to get a camera pic

<uses-permission android:name="android.permission.CAMERA" />

Where is the permission?

In the Google Camera Application

GoogleCamera.apk

Permissions in apps

Create custom permissions

<permission android:name="android.permission.CUSTOM_PERMISSION" android:protectionLevel="normal" android:label="@string/custom_permission_label">

<permission android:name="android.permission.SEND_SMS" android:permissionGroup=“android.permission-group.COST_MONEY" android:protectionLevel="dangerous" android:label="@string/permlab_sendSms" android:description="@string/permdesc_sendSms" />

Permissions in apps

Group permissions

<permission-group android:name="android.permission-group.LOCATION"

android:description="@string/permgroupdesc_location" />

<!-- Allows an application to access fine (e.g., GPS) location -->

<permission android:name="android.permission.ACCESS_FINE_LOCATION"

android:permissionGroup="android.permission-group.LOCATION"

android:protectionLevel="dangerous"

android:description="@string/permdesc_accessFineLocation" />

<!-- Allows an application to access coarse (e.g., Cell-ID, WiFi) location -->

<permission android:name="android.permission.ACCESS_COARSE_LOCATION"

android:permissionGroup="android.permission-group.LOCATION"

android:protectionLevel="dangerous"

android:description="@string/permdesc_accessCoarseLocation" />

Install in SD CARD

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example1" android:versionCode=“1"

android:versionName="1.0"

android:installLocation="auto|preferExternal"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />

</manifest>

$ adb shell

$ pm set-install-location 2

0 [auto]: Let system decide the best location1

[internal]: Install on internal device storage2

[external]: Install on external media

Check if Play Store is the installer

Check if Debuggable

Check Running emulator

Check Debugger certificate

Check signing key

Root detection

private boolean isDeviceRooted(){

try{

Runtime.getRuntime().exec("su");

return true;

}catch(IOExeception ex){

return false;

}

}

public static boolean() isDeviceRooted(){

File f= new File("/system/sbin/su");

return f.exits();

}

Malware

• Installing applications from known sites

• Check permissions during installation / upgrade

• Review comments from users

• Update the operating system and applications.

• Disable automatic connection to WiFi networks and avoid connecting to free WiFi

• Disable BlueTooth when not in use

Recommendations to avoid malware

Malware detection in Google play

Bluebox Security Scanner

SRT AppScanner

Lookout Mobile Security

Advanced Mobile Care

Malwarebytes Anti-Malware

CM Security

foresafe.com/scan

mobilesandbox.org

andrototal.org

copperdroid

Signing applications Purpose of certificates in Android is to distinguish

application authors

Android won't allow application to be upgraded unless signed with same certificate the applications are signed with the same key.

Android allows applications that are signed with the same certificate to run in the same processes

All applications must be signed with a digital certificate

Signing applications

Java keytool

$ keytool -genkey -v -keystore <keystore filename>

-alias <alias for key> -keyalg RSA -keysize 2048

-validity 10000

Sign apk with private key

Check the apk signature

sm 236 Sun Feb 02 15:08:10 CET 2014 javamail.pop3.provider

X.509, CN=Android Debug, O=Android, C=US [certificate is valid from 3/04/13 18:13 to 27/03/43 17:13]

54226 Sun Feb 02 15:08:10 CET 2014 META-INF/MANIFEST.MF

54279 Sun Feb 02 15:08:10 CET 2014 META-INF/CERT.SF

1203 Sun Feb 02 15:08:10 CET 2014 META-INF/CERT.RSA

s = signature was verified

m = entry is listed in manifest

k = at least one certificate was found in keystore

i = at least one certificate was found in identity scope

jar verified.

Signing applications

$ jarsigner -verify -certs -verbose testing.apk

$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1

-keystore mykeystore testing.apk <alias_name>

Android Studio

Tool included in Android SDK for apk compress and optimizing

$ zipalign -f 4 app-signed.apk final-app.apk

Build > Generate Signed APK

Eclipse/Android Studio

Content Providers

A specialized type of complex data store in Android to

standardize access and manipulation of stored data

Browser: bookmarks, browse history

CallLog: missed calls, call details

Contacts: Contact details

MediaStore: Media files

Content Providers

Offers a structured storage mechanism that can be limited to

your own application or exported to allow access by other

applications.

android:exported =“false"

android:exported ="true"

Versions >= 4.2 exported=“false” by default

<provider android:name=".data.DataProvider"

android:multiprocess="true"

android:authorities="myapp.data.DataProvider"

android:readPermission="myapp.permission.READ"

android:writePermission="myapp.permission.WRITE" />

Data Storage Shared preferences

External storage

Requires permission

android.permission.WRITE_EXTERNAL_STORAGE

Internal storage

Better than external since permissions not required

Sqlite3

File DataBase with extension *.db stored in

/data/data/[package_name]/databases

Cloud Google Cloud Messaging(GCM)

ROOT

Shared preferences

An xml key-value pairs file stored in

/data/data/com.your.package/shared_prefs/preferences.xml

Used by an application in order to save small sets of data for

the application

Storing sensitive information in shared preferences is not

recommended

Library for securing shared preferences

Encrypt the key-value pairs

AES symmetric key

https://github.com/scottyab/secure-preferences

ROOT

Secure Shared preferences ROOT

Networking

Use HttpsURLConnection for secure web traffic

HTTPS + CA Certificate

import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory;

// build key store with ca certificate KeyStore keyStore = buildKeyStore(context, certRawResId); // Create a TrustManager that trusts the CAs in our KeyStore String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); // Create an SSLContext that uses our TrustManager SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); // Create a connection from url RL url = new URL(urlString); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

Webview

class WebAppInterface {

private String sensitiveInformation;

public String toString() { return sensitiveInformation; }

}

WebView webview = new WebView(this);

setContentView(webview);

webView.loadUrl("http://website.com");

webView.addJavascriptInterface(new WebAppInterface(this), "injectedObject");

Vulnerability in version 4.1.2(API 16) Jelly Bean in Cross-site

scripting (XSS), Cross-site Request Forgery (CSRF) attacks

With JavaScript and Java Reflection can access any of the public

methods of the WebAppInterface

setJavascriptEnabled(true);

Webview

<script>

function execute(){

var

sendSMS=Android.getClass.forName("android.telephony.

SmsManager").

getMethod("getDefault",null).invoke(null,null);

sendSMS.sendTextMessage("+323232323",null,"message",

null,null);

}

</script>

Webview best practices

Disable JavaScript and Plugin support if they are not

needed.

Disable local file access. Restricts access to the app’s

resource and asset directory.

Prevent loading content from 3rd party hosts.

Activate SSL in activity using HTTPS

In 4.2 @JavascriptInterface method annotation for limit

access methods from javascript.

Avoid exposing protected data in javascript interface

@JavascriptInterface

public void method() { dostuff(); }

Webview best practices

Not save passwords

Not saving form data

Clear Cache

webSettings.setSavePassword(false);

webSettings.setSaveFormData(false);

@Override public void onPageFinished(WebView view, String url) {

super.onPageFinished(view, url);

view.clearCache(true); //delete local files in the browser

}

SQLite

SQLiteDatabase db = dbHelper.getWriteableDatabase();

String userQuery = "SELECT lastName FROM useraccounts WHERE

userID = ?";

SQLiteStatement prepStatement =db.compileStatement(userQuery);

prepStatement.bindString(1, "userID");

prepStatement.simpleQueryForString();

Prepared statements to avoid sql injection

rawQuery

compileStatement

SQLite Cipher

https://github.com/sqlcipher/android-database-sqlcipher

public void initDB(Context context, String password) { SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(DB_NAME,password, null); database.execSQL("create table MyTable(a, b)"); }

import net.sqlcipher.database.*;

import android.database.sqlite.*;

Static analysis

Static analysis

LINT ECLIPSE /ANDROID STUDIO Scans Android project sources for potential bugs

Comes with the SDK and detects common programming errors

Lint

$ lint --check Security --html security_report.html <project_home>

http://developer.android.com/tools/help/lint.html

ANDROID STUDIO

SONARQuBE http://www.sonarqube.org/

Encryption in phone

Supported since Android 3.0

Encrypts the entire device with AES 128.

Based on dm-crypt implementation

PBKDF2 algorithm for password

Takes at Least 1 h for Encryption of Data.

Denoted to reduce in performance.

Encryption in applications

Android Crypto API

Based in javax.crypto from javaSE

Obtain secretKey

public static SecretKey generateKey(char[] password, byte[] salt)

throws Exception {

int iterations = 1000;

int outputKeyLength = 256;

SecretKeyFactory secretKeyFactory

= SecretKeyFactory.getInstance(“PBKDF2WithHmacSHA1”);

KeySpec keySpec = new PBEKeySpec(password, salt,iterations,

outputKeyLength);

byte[] keyBytes = secretKeyFactory.generateSecret(keySpec).getEncoded();

return new SecretKeySpec(keyBytes, “AES”);

}

import java.security.*;

import javax.crypto.*;

Encryption in applications public static String encryptText(char[] password, String plainText)

throws Exception {

//Obtain secretkey

SecureRandom secureRandom = new SecureRandom();

int saltLength = 8;

byte[] salt = new byte[saltLength];

secureRandom.nextBytes(salt);

SecretKey secretKey = generateKey(password, salt);

Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”);

byte[] initVector = new byte[cipher.getBlockSize()];

secureRandom.nextBytes(initVector);

IvParameterSpec ivParameterSpec = new IvParameterSpec(initVector);

cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

byte[] cipherData = cipher.doFinal(plainText.getBytes(“UTF-8”));

return Base64.encodeToString(cipherData,Base64.NO_WRAP | Base64.NO_PADDING)

+ “]” + Base64.encodeToString(initVector,Base64.NO_WRAP | Base64.NO_PADDING)

+ “]” + Base64.encodeToString(salt,Base64.NO_WRAP | Base64.NO_PADDING);

}

Obsfuscation

Renames classes, fields and methods using short

names (a,b,c,..)

Obsfuscation in android projects Proguard

Integrated in SDK

http://developer.android.com/tools/help/proguard.html

Enable Proguard in eclipse

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-

project.txt

Obsfuscation in android projects Enable Proguard in android STUDIO

In build.gradle

android {

buildTypes {

release {

runProguard true

proguardFile getDefaultProguardFile('proguard-android.txt') ,

'proguard-rules.pro'

}

}

Proguard.config -optimizationpasses 5

-dontusemixedcaseclassnames

-dontskipnonpubliclibraryclasses

-dontpreverify

-verbose

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Application

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep public class * extends android.content.ContentProvider

-keep public class * extends android.app.backup.BackupAgentHelper

-keep public class * extends android.preference.Preference

-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {

native <methods>;

}

-keepclasseswithmembernames class * {

public <init>(android.content.Context, android.util.AttributeSet);

}

-keepclasseswithmembernames class * {

public <init>(android.content.Context, android.util.AttributeSet, int);

}

-keepclassmembers enum * {

public static **[] values();

public static ** valueOf(java.lang.String);

}

-keep class * implements android.os.Parcelable {

public static final android.os.Parcelable$Creator *;

}

Proguard tool http://proguard.sourceforge.net

Reverse Engineering Android Application

Rename Android app (.apk) to .zip

Extract zip

Run dex2jar on the extracted file

Open the .jar in a java decompiler

Reverse Engineering Android Application

Apk Tool

Reverses .apk file to an android project

$ apktool d target.apk output_directory

Apk Tool

Java vs Smali

Reverses .apk file to an android project

Learning smali through dalvik codes

http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Dex2jar http://code.google.com/p/dex2jar

Converts Android’s Dalvik executables into Java jar files.

$ unzip target.apk

$ d2jdex2jar.sh classes.dex -o target.jar

Dex2jar

activity_main.xml

Java Decompiler

http://java.decompiler.free.fr

Dex to Java Decompiler https://github.com/skylot/jadx

Decompile directly form apk or dex

Android Application Vulnerability Scanner

java –jar ScanAndroidApps.jar

Virtuous Ten Studio

http://virtuous-ten-studio.com/

Only for windows

Virtuous Ten Studio

Virtuous Ten Studio

Apk Analyser

https://github.com/maaaaz/androwarn

https://github.com/sonyxperiadev/ApkAnalyser

https://github.com/honeynet/apkinspector

https://code.google.com/p/droidbox

Apk Analyser http://developer.sonymobile.com/knowledge-base/tools/analyse-your-apks-with-apkanalyser/

java -jar ApkAnalyser.jar

Androwarn

python androwarn.py -i my_apk.apk -r html -v 3

DroidBox python apimonitor.py my_apk.apk

Dexter online

https://dexter.bluebox.com

Dexter online

TraceDroid

http://tracedroid.few.vu.nl

Records the behavior of the executed app, such as its network communication, the

UI, but also its internal function calls and Java code that is executed.

Emulates a few actions, such as user interaction, incoming calls and SMS

messages, etc. - this will reveal most malicious intents of an app.

Pentesting

Virtual Machine with tools for Reverse Engineering

https://redmine.honeynet.org/projects/are/wiki

https://appsec-labs.com/AppUse

Hacking distro dedicated to Mobile forensics and Security

https://github.com/viaforensics/android-forensics

http://andriller.com/

Forensics analisys

Intent Snifer —Sees Activity’s startup Intents

—android.permission.GET_TASKS: Recent tasks Intents

ActivityManager am = (ActivityManager)

getSystemService(ACTIVITY_SERVICE);

List<RecentTaskInfo> rti =

am.getRecentTasks(1000,ActivityManager.RECENT_WITH_EXCLUDED);

for (RecentTaskInfo c : rti) {

log.append("received: " + rti.toString() + "\n");

}

Books

References http://code.google.com/p/dex2jar/

https://code.google.com/p/android-apktool

https://code.google.com/p/androguard/wiki/Installation

http://ashishb.net/security/android-security-related-tools

http://androidcracking.blogspot.com.es

http://developer.android.com/guide/topics/security/permissions.html

http://source.android.com/devices/tech/security/#android-

application-security

http://siis.cse.psu.edu/android_sec_tutorial.html