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

I just hacked your app - TakeOff 2016

I just hacked your app - TakeOff 2016

Android security is nowhere near where it should be. I have been able to hack and get sensitive information from a few different apps and I’m just an amateur hacker at best.

In this session we will explore a number of ways an Android app can be exploited and most importantly methods that we can use to avoid these attacks.

Marcos Placona

October 20, 2016
Tweet

More Decks by Marcos Placona

Other Decks in Programming

Transcript

  1. NOT

  2. POST /users/461845f5d03e6c052a43afbc/points Accept: application/json Accept-Language: en-gb X-App-Version: 1.28.0 User-Agent: Dalvik/2.1.0

    (Linux; U; Android 6.0.1;) ... Content-Type: application/json; charset=UTF-8 Content-Length: 375 Host: api.eatapp.com Connection: Keep-Alive Accept-Encoding: gzip { "authentication_token":"boKUp9vBHNAJp7XbWZCK", "latitude":..., "longitude":..., "point":{ "isDoneByGesture":false, "main_beacon":{ "major":38995, "minor":12702, "uuid":"2C75E74B-41B7-49E3-BD26-CE86B2F569F8" }, "place_id":"450", "promoted_products_ids":[ {"id":"647035946536601578040000"}, {"id":"647035946536601578040000"}, {"id":"647035946536601578050000"} ] } }
  3. POST /users/461845f5d03e6c052a43afbc/points Accept: application/json Accept-Language: en-gb X-App-Version: 1.28.0 User-Agent: Dalvik/2.1.0

    (Linux; U; Android 6.0.1;) ... Content-Type: application/json; charset=UTF-8 Content-Length: 375 Host: api.eatapp.com Connection: Keep-Alive Accept-Encoding: gzip { "authentication_token":"boKUp9vBHNAJp7XbWZCK", "latitude":..., "longitude":..., "point":{ "isDoneByGesture":false, "main_beacon":{ "major":38995, "minor":12702, "uuid":"2C75E74B-41B7-49E3-BD26-CE86B2F569F8" }, "place_id":"450", "promoted_products_ids":[ {"id":"647035946536601578040000"}, {"id":"647035946536601578040000"}, {"id":"647035946536601578050000"} ] } }
  4. POST /users/461845f5d03e6c052a43afbc/points Accept: application/json Accept-Language: en-gb X-App-Version: 1.28.0 User-Agent: Dalvik/2.1.0

    (Linux; U; Android 6.0.1;) ... Content-Type: application/json; charset=UTF-8 Content-Length: 375 Host: api.eatapp.com Connection: Keep-Alive Accept-Encoding: gzip { "authentication_token":"boKUp9vBHNAJp7XbWZCK", "latitude":..., "longitude":..., "point":{ "isDoneByGesture":false, "main_beacon":{ "major":38995, "minor":12702, "uuid":"2C75E74B-41B7-49E3-BD26-CE86B2F569F8" }, "place_id":"450", "promoted_products_ids":[ {"id":"647035946536601578040000"}, {"id":"647035946536601578040000"}, {"id":"647035946536601578050000"} ] } }
  5. • Encrypt all the values • Utilise security features when

    they exist • Certificate pinning • DO NOT TRUST THE DEVICE
  6. // Sending side byte[] data = text.getBytes("UTF-8"); String base64 =

    Base64.encodeToString(data, Base64.DEFAULT); // Receiving side byte[] data = Base64.decode(base64, Base64.DEFAULT); String text = new String(data, "UTF-8"); Encrypt all the values
  7. • Encrypt all the values • Utilise security features when

    they exist • Certificate pinning • DO NOT TRUST THE DEVICE
  8. • Encrypt all the values • Utilise security features when

    they exist • Certificate pinning • DO NOT TRUST THE DEVICE
  9. public class KeyPinStore { private static KeyPinStore instance = null;

    private SSLContext sslContext = SSLContext.getInstance("TLS"); public static synchronized KeyPinStore getInstance() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException{ if (instance == null){ instance = new KeyPinStore(); } return instance; } private KeyPinStore() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException{ // Load CAs from an InputStream // (could be from a resource or ByteArrayInputStream or ...) CertificateFactory cf = CertificateFactory.getInstance("X.509"); // randomCA.crt should be in the Assets directory InputStream caInput = new BufferedInputStream(MainActivity.context.getAssets().open("randomCA.crt")); Certificate ca; try { ca = cf.generateCertificate(caInput); System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); } finally { caInput.close(); } // Create a KeyStore containing our trusted CAs String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); // 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 context = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); } public SSLContext getContext(){ return sslContext; } } Certificate pinning https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#Android
  10. • Encrypt all the values • Utilise security features when

    they exist • Certificate pinning • DO NOT TRUST THE DEVICE
  11. Options • Make sure you encrypt them • Protect them

    with tools like DexGuard and ProGuard • Get them off a server http://bit.ly/SafeKey
  12. Tampering detection // myPackageName should decode at runtime to "com.yourpackagename"

    // google should decode at runtime to "com.android.vending"; // amazon should decode at runtime to "com.amazon.venezia"; public boolean isHacked(Context context, String myPackageName, String google, String amazon) { //Crooks renamed your app? if (context.getPackageName().compareTo(myPackageName != 0) return true; // BOOM! //Rogues relocated your app? String installer = context.getPackageManager().getInstallerPackageName(myPackageName); if (installer == null) return true; // BOOM! if (installer.compareTo(google) != 0 && installer.compareTo(amazon) != 0) return true; // BOOM! return false; } http://bit.ly/isHacked
  13. Tampering detection // myPackageName should decode at runtime to "com.yourpackagename"

    // google should decode at runtime to "com.android.vending"; // amazon should decode at runtime to "com.amazon.venezia"; public boolean isHacked(Context context, String myPackageName, String google, String amazon) { //Crooks renamed your app? if (context.getPackageName().compareTo(myPackageName != 0) return true; // BOOM! //Rogues relocated your app? String installer = context.getPackageManager().getInstallerPackageName(myPackageName); if (installer == null) return true; // BOOM! if (installer.compareTo(google) != 0 && installer.compareTo(amazon) != 0) return true; // BOOM! return false; } http://bit.ly/isHacked
  14. • Check your app’s signature • Check for rooted device

    • Check for emulator • Check if the app is debuggable
  15. private static final int VALID = 0; private static final

    int INVALID = 1; private static final String APP_SIGNATURE = "1038C0E34658923C4192E61B16846"; public static int checkAppSignature(Context context) { try { PackageInfo packageInfo = context.getPackageManager() .getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); for (Signature signature : packageInfo.signatures) { byte[] signatureBytes = signature.toByteArray(); MessageDigest md = MessageDigest.getInstance("SHA"); md.update(signature.toByteArray()); //compare signatures if (SIGNATURE.equals(APP_SIGNATURE)){ return VALID; }; } } catch (Exception e) { //assumes an issue in checking signature., but we let the caller decide on what to do. } return INVALID; } Check your app’s signature http://bit.ly/AndroidTampering
  16. • Check your app’s signature • Check for rooted device

    • Check for emulator • Check if the app is debuggable
  17. private static boolean canExecuteCommand(String command) { try { int exitValue

    = Runtime.getRuntime().exec(command).waitFor(); if (exitValue != 0) return false; else return true; } catch (Exception e) { return false; } } Check for rooted device
  18. • Check your app’s signature • Check for rooted device

    • Check for emulator • Check if the app is debuggable
  19. • Check your app’s signature • Check for rooted device

    • Check for emulator • Check if the app is debuggable