View
214
Download
5
Category
Tags:
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
Recommended