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

Meta-Programming in Kotlin for Enhanced Android...

Adit Lal
November 29, 2023

Meta-Programming in Kotlin for Enhanced Android Security

In this talk, we dive into applying Kotlin meta-programming techniques to bolster the security of Android applications. Kotlin, with its concise syntax and robust features, offers unique opportunities for meta-programming that can significantly enhance app security.

* Kotlin Compiler Plugins for Security Checks: Explore how Kotlin's compiler plugins can be used to create custom lint checks, ensuring secure coding practices and identifying potential security flaws during compile time.

* Code Generation for Security Features: Learn how to use Kotlin's meta-programming capabilities to generate boilerplate code for security features such as data encryption, secure API communication, and user authentication.

* DSLs for Secure Data Handling: Delve into creating Domain-Specific Languages (DSLs) in Kotlin for secure data handling, which can simplify the implementation of complex security protocols and reduce the risk of developer errors.

*Reflection and Annotations for Security Audits: Understand Kotlin's reflection and annotation processing to automate security audits within the app, helping in the early detection of vulnerabilities.

* Secure Multiplatform Development: Examine how Kotlin's multiplatform projects can benefit from shared meta-programming techniques to maintain consistent security practices across different platforms.

This session will give attendees a deeper understanding of Kotlin's meta-programming tools and how they can be creatively applied to develop more secure Android applications.

Adit Lal

November 29, 2023
Tweet

More Decks by Adit Lal

Other Decks in Technology

Transcript

  1. Adit Lal GDE Android Meta-Programming in Kotlin for Enhanced Android

    Security Secure Code, Simplified Travv World
  2. ⾠ MANDATORY LEGAL WARNING ⾠ Information acquired here is solely

    for educational purposes: - Refrain from testing on unauthorized apps. - Seek security advice from knowledgeable sources within your company. - This presentation is not af fi liated with or endorsed by the OWASP Foundation or my employer.
  3. "Crafting a reputation is a time-intensive process, yet a mere

    moment in a cyber incident has the potential to shatter it." Why is the security of apps so important?
  4. MSTG The Mobile Security Testing Guide is a comprehensive manual

    that describes technical processes for verifying the controls listed in the MASVS OWASP The Open Web Application Security Project® (OWASP) is a nonprofit foundation that works to improve the security of software MASVS Mobile App Security Requirements and Verification is a standard that establishes security requirements for testing mobile app security SOP
  5. Mobile App Security Requirements and Verification MASVS Architecture, Design and

    Threat Modeling Cryptography Requirements Data storage and privacy Authentication and session management Network communication requirements Platform interaction Code quality and build settings
  6. Testing Guide Static Analysis • Understand working of a binary

    without running it • Assets analysis ◦ Application entry points ◦ Hard coded secrets ◦ External libraries • Code analysis (reverse engineering) ◦ Retrieve the logic of the application ◦ Identify weakness (cryptographic protocols, …) • Tools : Jadx, IDA pro, Gridra Dynamic Analysis
  7. Dynamic Analysis Testing Guide • Understand the working of a

    binary by executing it. • On a (rooted) phone, verify app by checking exploits using ◦ Data storage ◦ Storage ◦ Logcat • Traffic analysis ◦ Man In The Middle attack • Code instrumentation ◦ Methods hooking • Tools: Debuggers, FRIDA, EdXposed
  8. DEX compiler source code .java Kotlin compiler source code .kt

    .kts Java bytecode .class .jar Java compiler source code .c .cpp Dalvik bytecode .dex Machine code .so application.apk Anatomy of Android apps
  9. $ unzip -d application application.apk
 $ ls application/
 AndroidManifest.xml
 META-INF/


    classes.dex, classes2.dex, ...
 lib/
 assets/
 ... My input! Dalvik bytecode Entry point [Read it first] Native libraries Read-only data application.apk Anatomy of Android apps
  10. $ unzip -d application application.apk
 $ ls application/
 AndroidManifest.xml
 META-INF/


    classes.dex, classes2.dex, ...
 lib/
 assets/
 ... My input! Dalvik bytecode Entry point [Read it first] Native libraries Read-only data application.apk Anatomy of Android apps
  11. Static Analysis - Manifest Usually, the first thing that a

    penetration tester will check on an engagement. We will get additional information on - Permissions - android:protectionLevel attribute - Manifest attributes - Debuggable - CleartextTraffic - Network security configuration - Backup and restore - Exported android components - Intent filters Tools: Jadx Jeb APKTool Static Analysis
  12. Static Analysis - Reverse Engineering Design Code Compilation Output Software

    engineering “square an integer” int square(int num) { return num * num;} mov DWORD PTR [rbp-4], edi mov eax, DWORD PTR [rbp-4] imul eax, eax 89 7d fc 8b 45 fc 0f af c0 Static Analysis
  13. Static Analysis - Reverse Engineering Design Code Compilation Output Software

    engineering Reverse engineering “square an integer” int square(int num) { return num * num;} mov DWORD PTR [rbp-4], edi mov eax, DWORD PTR [rbp-4] imul eax, eax 89 7d fc 8b 45 fc 0f af c0 Static Analysis
  14. - Storage monitoring - Observing changes on the file system

    while using the application. - Files created post log-in - Storing of passwords/tokens in Shared Pref file. - Files created/changed on internal storage - /data/data/<package name>/…. - Files created/changed on external storage - /sdcard/… - Keys created in Keystore Dynamic Analysis
  15. - Behaviour analysis - Observing behavioural changes for various interaction

    with the app Application running on a rooted device may behave differently than on a non-rooted device - Observing error information Gives out small pieces of information (eg) login messages Dynamic Analysis
  16. - Code Instrumentation Java.perform(function() { / / - - -

    - - Location - - - - - / / https: / / developer.android.com/reference/android/location/Location var location = Java.use('android.location.Location'); / / public double getLatitude () var location_getLatitude = location.getLatitude.overload(); location_getLatitude.implementation = function() { var latitude = location_getLatitude.call(this); console.log("[+] Location.getLatitude() : " + latitude); return latitude; / / var modif i ed_latitude = -75.09978; / / return modif i ed_latitude; } / / public double getLongitude () var location_getLongitude = location.getLongitude.overload(); location_getLongitude.implementation = function() { var longitude = location_getLongitude.call(this); console.log("[+] Location.getLongitude() : " + longitude); return longitude; / / var modif i ed_longitude = -123.332196; / / return modif i ed_longitude; } }); Dynamic Analysis
  17. Action - Reaction - Prevention Improper Can you spot the

    mistake? How to secure your android application
  18. Improper Can you spot the mistake? Hardcoded API Key Detection

    package tech.savvy.kdroid.secure /** * Annotation to fl ag hardcoded secrets or sensitive information in code. * @property message A custom message explaining why the element is fl agged. */ @Target(AnnotationTarget.FIELD, AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.SOURCE) annotation class HardcodedSecret( val message: String = "Potential hardcoded secret detected" )
  19. Improper Can you spot the mistake? Hardcoded API Key Detection

    class SecurityProcessor( private val codeGenerator: CodeGenerator, private val logger: KSPLogger ) : SymbolProcessor { override fun process(resolver: Resolver) : List<KSAnnotated> { val symbols = resolver.getSymbolsWithAnnotation("tech.savvy.kdroid.secure.HardcodedSecret") symbols.forEach { symbol - > if (symbol is KSPropertyDeclaration) { logger.warn("Potential security issue detected: $ {symbol.simpleName.asString()}") } } return emptyList() } }
  20. Improper Can you spot the mistake? Hardcoded API Key Detection

    class SecurityProcessorProvider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment) : SymbolProcessor { return SecurityProcessor(environment.codeGenerator, environment.logger) } } plugins { kotlin("jvm") id("com.google.devtools.ksp") } dependencies { implementation("com.google.devtools.ksp:symbol - processing - api : < latest - version>") }
  21. Improper Can you spot the mistake? Hardcoded API Key Detection

    package com.example.app import tech.savvy.kdroid.secure.HardcodedSecret class Example { @HardcodedSecret("This API key should not be hardcoded") val apiKey = "AIza1234567890abcdef" / / Hardcoded API key for demo }
  22. Improper Can you spot the mistake? Hardcoded API Key Detection

    @HardcodedKey(type = "Encryption", description = "Migrate to SecureStorage") val aesKey = "this - is - a - hardcoded - aes - key" / / Processor generates: object SecureConf i g { fun getAesKey() : String { return SecureStorage.get("AES_KEY") } }
  23. Improper Can you spot the mistake? Hardcoded API Key Detection

    SecureStorage.putString("TOKEN", encrypt("my - token")) val token = decrypt(SecureStorage.getString("TOKEN"))
  24. Enforce secure communication - Show an app chooser. If an

    implicit intent can launch at least two possible apps on a user's device, explicitly show an app chooser. This interaction strategy allows users to transfer sensitive information to an app that they trust. Intent intent = new Intent(Intent.ACTION_SEND); String title = getResources().getString(R.string.chooser_title); Intent chooser = Intent.createChooser(intent, title); try { startActivity(chooser); } catch (ActivityNotFoundException e) { / / Def i ne what your app should do if no activity can handle the intent. } Secure Communication Enforce
  25. Enforce secure communication - Use Intents for IPC To send

    data to a specific component of an app, you must create a new instance of the Intent class and use its setComponent() method to specify both the package name of the app and the name of the component. You can then add data to it using the putExtra() method. Intent intent = new Intent(); / / Specify the component name intent.setComponent(new ComponentName("my.other.app","my.other.app.MyActivity")); / / Add data intent.putExtra("DATA", "Hello World!"); / / Send the intent to the activity startActivity(intent); Secure Communication Enforce
  26. Enforce secure communication - Use Intents for IPC To send

    data to multiple apps at once, you can send the intent as a broadcast using the sendBroadcast() method → can be intercepted. • Use a custom permission whose protectionLevel is set to signature • https://developer.android.com/guide/topics/manifest/permission- element#plevel <permission android:name="my.custom.permission" android:protectionLevel="signature" / > <uses - permission android:name="my.custom.permission" / > / / Create an intent Intent intent = new Intent(); / / Add data intent.putExtra("DATA", "Hello World"); / / Specify an action name for / / the receiver's intent - f i lter intent.setAction("my.app.receive"); / / Send as a broadcast using a custom permission sendBroadcast(intent, "my.custom.permission"); Secure Communication Enforce
  27. Enforce secure communication - Lint class IntentUsageProcessor( private val logger:

    KSPLogger ) : SymbolProcessor { override fun process(resolver: Resolver) : List<KSAnnotated> { val symbols = resolver.getAllFiles() / / Analyze all f i les symbols.forEach { f i le - > f i le.declarations.forEach { declaration - > if (declaration is KSFunctionDeclaration) { analyzeFunction(declaration) } } } return emptyList() } … } Secure Communication Enforce
  28. Enforce secure communication - Lint private fun analyzeFunction(function: KSFunctionDeclaration) {

    function.body ? . statements ? . forEach { statement - > if (statement.toString().contains("Intent(")) { / / Detect Intent usage val isImplicit = statement.toString().contains("Intent.ACTION_") & & !statement.toString().contains("component") if (isImplicit) { logger.warn( "Implicit Intent detected in function $ {function.simpleName.asString()} " + "at line ${function.location}", function ) } } } } Secure Communication Enforce
  29. Enforce secure communication - Lint class CustomIntentDetector : Detector(), SourceCodeScanner

    { / / Specify which methods to analyze override fun getApplicableMethodNames() = listOf("Intent") / / Analyze the method calls override fun visitMethodCall(context, node, method) { if (method.name = = "Intent" & & !node.arguments.contains("component")) { / / Report issue for implicit intents context.report( ISSUE, node, "Implicit Intent detected: Specify a target component." ) } } companion object { / / Def i ne the lint issue val ISSUE = Issue.create( Secure Communication Enforce
  30. if (method.name = = "Intent" & & !node.arguments.contains("component")) { /

    / Report issue for implicit intents context.report( ISSUE, node, "Implicit Intent detected: Specify a target component." ) } } companion object { / / Def i ne the lint issue val ISSUE = Issue.create( id = "ImplicitIntent", description = "Implicit Intent Detected", explanation = "Implicit intents can cause security risks. " + "Always use explicit intents.", category = SECURITY, priority = 6, severity = WARNING ) } } Enforce secure communication - Lint Secure Communication Enforce
  31. Enforce secure communication - Network Security • No cleartext communication

    by default starting Android 7.1 android:usesCleartextTraff i c=false / / by default! • Pin certificates (res/xml/network_security_config.xml) <network - security - conf i g> <domain - conf i g> <domain includeSubdomains="true">example.com < / domain> <pin - set expiration="2018-01-01"> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y= < / pin> < / pin - set> < / domain - conf i g> < / network - security - conf i g> Secure Communication Enforce
  32. Improper Platform Usage Can you spot the mistake? How to

    secure your android application https://github.com/ajinabraham/Mobile-Security-Framework-MobSF
  33. <application> <activity android:name=".login.LoginActivity" android:exported="true" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@style/ThemeA"> <intent - f

    i lter> <action android:name="android.intent.action.MAIN" / > <category android:name="android.intent.category.LAUNCHER" / > < / intent - f i lter> < / activity> <activity android:name=".home.MainActivity" android:screenOrientation="portrait" android:exported="true" android:theme=“@style/ThemeA" / > < / application> Can you spot the mistake?
  34. <application> <activity android:name=".login.LoginActivity" android:exported="true" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@style/ThemeA"> <intent - f

    i lter> <action android:name="android.intent.action.MAIN" / > <category android:name="android.intent.category.LAUNCHER" / > < / intent - f i lter> < / activity> <activity android:name=".home.MainActivity" android:screenOrientation="portrait" android:exported="true" android:theme=“@style/ThemeA" / > < / application> How is this exploited?
  35. Use a tool like ‘drozer’ to scan app for vulnerable

    activities, broadcast receivers and content providers How is this exploited? github.com/FSecureLABS/drozer •Run ADB to exploit
  36. <application> <activity android:name=".login.LoginActivity" android:exported="true" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@style/ThemeA"> <intent - f

    i lter> <action android:name="android.intent.action.MAIN" / > <category android:name="android.intent.category.LAUNCHER" / > < / intent - f i lter> < / activity> <activity android:name=".home.MainActivity" android:screenOrientation="portrait" android:exported="false" android:theme=“@style/ThemeA" / > < / application> Fixing the exploit
  37. •‘Tap-jacking’ vulnerability •Apps can draw over other apps and monitor

    their contents •They can also pass spoofed touch events android:f i lterTouchesWhenObscured=“true" •Combined, this can be used maliciously to trick users into entering passwords, accepting permissions, etc •Permission required for these apps, but only recently Other exploits?
  38. Permissions Best practices: Control | Transparency | Data minimization •

    Request a minimal number of permissions • Associate runtime permissions with specific actions • Consider your app's dependencies • Be transparent • Make system accesses explicit Android Permissions Samples Repository • https://github.com/android/permissions-samples
  39. Storing User Data - Android application sandbox • Applications are

    isolated into their own space (user-based protection) ◦ Prefer using internal storage, it prevents other apps from accessing it. • Backup (true by default) ◦ https://developer.android.com/guide/topics/data/autobackup <application android:allowBackup="true" . . . > ◦ Cloud backups / Device-to-device (D2D) transfers <application . . . android:fullBackupContent="@xml/backup_rules" …> backup_rules.xml 👉 <full - backup - content> <include domain="sharedpref" path="." / > <exclude domain="sharedpref" path="device.xml" / > < / full - backup - content> Storing User Data
  40. Storing User Data - File Encryption • Storing data on

    the external storage should be encrypted https://developer.android.com/guide/topics/security/ cryptography • Recommended algorithms ‣Cipher - AES in either CBC or GCM mode with 256-bit keys ‣MessageDigest - SHA-2 family ‣Mac - SHA-2 family HMAC ‣Signature - SHA-2 family with ECDSA
  41. Storing User Data - Encrypted Key Value Storage SharedPreferences is

    a simple key-value storage • In the application private directory • Not encrypted EncryptedSharedPreferences • Store data encrypted in your SharedPreference • Key Store handled everything in the background val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) val encryptedSharedPreferences = EncryptedSharedPreferences.create( "secret_shared_prefs", masterKeyAlias, context, PrefKeyEncryptionScheme.AES256_SIV, PrefValueEncryptionScheme.AES256_GCM) / / use the shared preferences and editor as you normally would SharedPreferences.Editor editor = sharedPreferences.edit();
  42. Common App security risks - Third party frameworks 3rd party

    SDKs or frameworks can be a huge security risk for your applications. Since they get compiled with your app and run in the same sandbox they have the same rights as your app. Be aware that your application is not secure if any of external libraries is not secure. Common App security risks
  43. Common App security risks - Analytics Less is more: especially

    in combination with third party analytics SDKs You should be careful which information you want to collect. Analytics data can often already be enough to identify users or to be able to access their data. Common App security risks
  44. Common App security risks - Loggings The problem arises if

    the logged stuff contains username, password or other sensitive information. Remove log statements in release builds! proguard - rules.pro - assumenosideeffects class android.util.Log { public static boolean isLoggable(java.lang.String, int); public static int v( . . . ); public static int d( . . . ); public static int i( . . . ); } Common App security risks
  45. Android Security Security by Design on Play Academy • Learn

    about best practices for encryption, integrity, and the overall app security lifecycle. Shortlink → goo.gle/androidsecuritycourse Scan Me!