Bits on Android security Miroslav Svítok About me ● I work as a penetration tester in Citadelo. ● I work (together with Dušan) at PhoneX - a mobile application for end to end encryption of calls, messages and files. ● Android security model ● Credentials storage ● Web view ● SSL/TLS and pinning Android security model Android security model ● Android = Linux-like OS ● Uses UID and GID in a different way than traditional Linux desktop or server ● Single physical user ● Sandboxing - unique UID* to each app, runs in a separate process ● App is given directory only it has permission to read/write * exception - android:sharedUserId Android security model - UIDs ● No /etc/passwd, system UIDs are statically defined. ● System daemons/apps UID 1000+ (e.g. SYSTEM user UID 1000, ROOT 0) ● Applications UID 10000+, automatically assigned $ ps 5786 u0_a71 289m S {amsungapps.una2} com.sec.android.app.samsungapps.un 5799 u0_a76 290m S {.osp.app.signin} com.osp.app.signin 5813 u0_a101 294m S {nce.swype.input} com.nuance.swype.input 5828 u0_a69 292m S {moteNotiProcess} com.sec.spp.push:RemoteNotiProcess 5869 u0_a105 366m S {le.android.talk} com.google.android.talk 5906 u0_a42 290m S {id.partnersetup} com.google.android.partnersetup u0_a101 = UID 10101 Android security model - application directory ● Directory is assigned by package name in /data/data ● E.g. /data/data/com.google.android.youtube $ ls -la drwxrwx--x 3 u0_a128 u0_a128 4096 Feb 9 16:05 cache drwxrwx--x 2 u0_a128 u0_a128 4096 Mar 9 23:55 databases drwxrwx--x 4 u0_a128 u0_a128 4096 Mar 9 23:56 files drwxr-xr-x 2 system system 4096 Feb 18 10:24 lib drwx------ 2 u0_a128 u0_a128 4096 Feb 9 16:05 no_backup drwxrwx--x 2 u0_a128 u0_a128 4096 Mar 20 17:57 shared_prefs Android security model ● Files in internal storage can be made readable/writeable for others ● MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE ● @Deprecated (4.2+) and dangerous. Context.getSharedPreferences(String name, int mode); Context.openOrCreateDatabase(String name, int mode); Context.openFileOutput (String name, int mode) ● Files in external storage are globally readable and writable! ● android:installLocation: preferExternal - apps on external storage Communication with other applications?? ● Interprocess communication! (IPC) ● Bypass processes isolation ● Implemented via Binder driver ● High-level abstraction: ○ Intents ○ Messengers ○ ContentProviders Security of IPC - Permissions ● To control access, Android uses custom Permissions system. ● Requested in AndroidManifest.xml ● Assigned to app during installation (as supplementary GIDs). ● Permission protection levels: ○ Normal ○ Dangerous (=give access to user data or some form of control over the device, e.g. SMSs) ○ Signature ○ SignatureOrSystem Security of IPC - Permissions ● Permissions handled by the PackageManager service ● Central database of installed packages ○ /data/system/packages.xml ● Cannot be changed or revoked by users without uninstalling app (<= Android 5.1) ● Android 6.0 + targetSdkVersion >= 23 ○ Apps request permissions at runtime ○ Permission can be revoked Security of IPC - Permissions ● Permissions can be enforced in a number of places ○ Start activity ○ Starting and binding a service ○ Sending and receiving broadcasts ○ Accessing a content provider ○ Making a system call ● High-level permission enforcement by android:permission attribute in AndroidManifest ● Context.checkPermission (String permission, int pid, int uid) Security of IPC ● Minimize exposure of your ContentProviders, Services and Broadcast receivers. ● android:exported="false" ● Added IntentFilter often causes unintended exporting of features. ● You can require signature level permission - e.g custom one android:permission="android.permission.ABC" Broadcast permissions ● Can be requested when sending (only app with perms) ● Context.sendBroadcast(Intent intent, String receiverPermission) ● LocalBroadcastManager - broadcast locally Attacks ● Broadcast theft - data eavesdropped without knowing ● Ordered broadcasts (Context.sendOrderedBroadcast) can be stopped from propagating (depends on IntentFilter priority) ● Activity hijacking - malicious activity launched instead of intended (phishing) ● Service hijacking - app establishes connection with malicious service ● Stealing Special intents - granting permission ○ FLAG_GRANT_READ_URI_PERMISSION ○ FLAG_GRANT_WRITE_URI_PERMISSION ● Intent spoofing Pending Intents ● Specifies an action that needs to be performed on behalf of your app by the other app in the future (NotificationManager, AlarmManager ...) ● Foreign app will execute Intent using your app’s permission ● Can be stolen, be explicit: //explicit (to MyService) Intent intent = new Intent(context, MyService.class); PendingIntent pi = PendingIntent.getService(getApplicationContext(), 0, intent, 0); //implicit Intent intent = new Intent("com.my.app.action") PendingIntent pi = PendingIntent.getService(getApplicationContext(), 0, intent, 0); ● CVE-2014-8609 Android Settings application privilege leakage vulnerability Credential storage Credential storage options ● KeyChain API (Android 4.0+) ○ Import keys into system-wide credential storage ○ Can be used by different apps ● KeyStore API (Android 4.3+) ○ Support for app-private keys ○ Extraction prevention ■ Key material never enters application process ■ Key material may be bound to the secure hardware ● Backed by new Android JCA provider = AndroidKeyStore ● Entry types = CA certificate, user certificate, private key Keystore implementation ● keystore service, runs as dedicated keystore user # ls -la /data/misc/keystore/user_0 -rw------- keystore keystore 84 .masterkey -rw------- keystore keystore 980 1000_CACERT_cacert -rw------- keystore keystore 756 1000_USRCERT_test -rw------- keystore keystore 884 1000_USRPKEY_test -rw------- keystore keystore 724 10019_USRCERT_myKey -rw------- keystore keystore 724 10019_USRCERT_myKey1 ● .masterkey encrypted with AES-128, pass derived from screen unlock pass + random salt (PBKDF2, 8192 iterations) ● Other files - BLOB: metadata || enc(MD5(data) || data) WebView What is WebView? WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com"); WebView security ● Consumes web content. ● Limit its capability to minimum. ● Do not call setJavaScriptEnabled() if necessary. ● Security patches for WebView’s webkit not available on Android < 4.4 “Devices running platforms older than Android 4.4 (API level 19) use a version of webkit that has a number of security issues. As a workaround, if your app is running on these devices, it should confirm that WebView objects display only trusted content.” - Android Developer Portal, Google WebView - addJavascriptInterface() ● Enables to call Java functions via JS ● CVE-2012-6636 - execute attacker Java code via malicious JS ● Vulnerable code for Android < 4.2: webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JavaScriptInterface(), "jsinterface"); final class JavaScriptInterface { JavaScriptInterface () { } public void showToast() { // @JavascriptInterface Toast.makeText(mContext, “some toast”, Toast.LENGTH_SHORT).show(); } Bad Good SSL/TLS and Certificate pinning Certificate pinning - Motivation ● Scenario: server side REST interface over SSL/TLS ● https://verysecure.com:4001 ● Android by default trusts wide range of certificates for SSL/TLS ● Settings -> Security -> Trusted credentials ● HttpsURLConnection or HttpClient automatically validate against system’s trusted certs. Certificate pinning - Motivation 2 ● Do we want to trust everybody? ● Sometimes CAs can be tricked or even hacked (Comodo - 03/2011, DigiNotar - 09/2011), or deliberately issue fraudulent cert to spy (French ANNSI - 12/2013). ● Single compromised CA can issue certificates for arbitrary domain (*.google. com?) ● Solution: blacklist or whitelist ● “Pinning is the process of associating a host with their expected X509 certificate or public key.“ - whitelisting approach Certificate pinning - HowTo on Android ● Generate KeyStore (.bks) with your signing certificate ● KeyStore - load your custom keystore from the file system, initiate TrustManager with the KeyStore ● Create SSLContext ● or ● Pin against hash (SHA-256/512) of SubjectPublicKeyInfo (=public key + algorithm) ● Keep it simple = https://github.com/moxie0/AndroidPinning Pinning Example // Define an array of pins. One of these must be present // in the certificate chain you receive. A pin is a hex-encoded // hash of a X.509 certificate's SubjectPublicKeyInfo. A pin can // be generated using the provided pin.py script: // python ./tools/pin.py certificate_file.pem String[] pins = new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}; URL url = new URL("https://www.google.com"); HttpsURLConnection connection = PinningHelper.getPinnedHttpsURLConnection(context, pins, url); return connection.getInputStream(); The end Thank you