Skip to main content

Monitor Cryptographic Functions

Cryptography is crucial to mobile application security since a lot of attacks are based on a threat actor having physical access to the device. Cryptography includes Encryption/Decryption, Hashing, Message Authentication Codes (MAC), Signatures, and Key Derivation Functions (KDF’s).

When testing a mobile app, you need to evaluate the cryptographic algorithms and protocol’s that are in use and evaluate them for weak or insecure configurations. This can be accomplished through source code review, and dynamic analysis.

Weak Algorithms

The following algorithms are known to be weak or insecure: • DES / 3DES • RC2 • RC4 • Blowfish • MD4 • MD5

Static Analysis

Extract the APK file using the jadx tool:

jadx -d App filename.apk 

Identify the algorithms, key generators, and classes used for cryptography functions.

  • Algorithms: AES, DES, etc.
  • Key Generator: KeyGenParameterSpec, KeyPairGeneratorSpec, KeyPairGenerator, KeyGenerator, KeyProperties
  • Classes: java.security.*, javax.crypto.*, android.security.*, android.security.keystore.*

Search the source code output from jadx for cryptographic functions:

grep -riI “SecretKeySpec” sources

Dynamic Analysis

For dynamic analysis, use Frida to trace the cryptographic functions while the app is in use. There are a few Frida scripts on GitHub to perform this action.

Frida

Using the preferred script, run it so that Frida will spawn the app from a non-running state. If you are currently logged into the app, logout first so that you can capture the whole process.

The example below uses the android-crypto-intercept.js script to trace the cryptographic functions:

frida -U -l android-crypto-intercept.js -f com.appname.app –no-pause

Substitute com.appname.app for your test application.

The flags used in this command:

  • -U Use the USB cable to connect to the device
  • -l Load the script
  • -f Spawn the app
  • --no-pause Immediately start the process once the app is hooked

android-crypto-intercept:

frida -U -l android-crypto-intercept.js -f com.godaddy.gx.go --no-pause

Spawned `com.godaddy.gx.go`. Resuming main thread!
[Pixel 6::com.godaddy.gx.go ]-> message: {'type': 'send', 'payload': 'KEY: xxxxxxx4a7b4f1ff54fxxx5af0c2933a8a0129221f3f7314e09cb5b623fed5b7'} data: None
message: {'type': 'send', 'payload': 'CIPHER: AES/ECB/PKCS5Padding'} data: None
message: {'type': 'send', 'payload': 'doFinal!'} data: None
message: {'type': 'send', 'payload': 'D_i¨`ô\x18ڡʦXeÑf\x16\x9f-\x1c\x8d\x88|éÁu~t\x8d\x1d¡è^'} data: None
message: {'type': 'send', 'payload': 'KEY: befeb914a7b4f1ff54f77f5af0c2933a9a0129221f3f7314e09cb5b623fed5b7'} data: None
message: {'type': 'send', 'payload': 'CIPHER: AES/ECB/PKCS5Padding'} data: None
message: {'type': 'send', 'payload': 'doFinal!'} data: None
message: {'type': 'send', 'payload': '\x0e\x1d©©ç\x17ÔZ\x03\x1c×Ïâ<\x84\x02Î\x06\x8d,áÀ\x1dãE¤\x8báºTp}bë\x11ÆKÅ»ÎL\x8ath0\n·\x8c'} data: None
message: {'type': 'send', 'payload': 'KEY: xxxxxxx4a7b4f1ff54fxxx5af0c2933a8a0129221f3f7314e09cb5b623fed5b7'} data: None
message: {'type': 'send', 'payload': 'CIPHER: AES/ECB/PKCS5Padding'} data: None
message: {'type': 'send', 'payload': 'doFinal!'} data: None
message: {'type': 'send', 'payload': 'KEY: xxxxxxx4a7b4f1ff54fxxx5af0c2933a8a0129221f3f7314e09cb5b623fed5b7’} data: None
message: {'type': 'send', 'payload': 'CIPHER: AES/ECB/PKCS5Padding'} data: None
message: {'type': 'send', 'payload': 'doFinal!'} data: None
message: {'type': 'send', 'payload': 'CIPHER: AES/CBC/PKCS5Padding'} data: None
message: {'type': 'send', 'payload': 'KEY: 7daxxxxxd5803a75006313a497e26877'} data: None
message: {'type': 'send', 'payload': 'doFinal!'} data: None

Another script can show where the cryptographic function is being called from the code:

android-crypto.js:

frida -U -l android-crypto.js -f com.godaddy.gx.go --no-pause 

[Pixel 6::com.godaddy.gx.go ]-> [Crypto Monitor]
{
"category": "Crypto",
"class": "javax.crypto.spec.SecretKeySpec",
"method": "$init",
"args": "[[-66,-2,-71,20,-89,-76,-15,-1,84,-9,127,90,-16,-62,-109,58,-102,1,41,34,31,63,115,20,-32,-100,-75,-74,35,-2,-43,-73],\"AES\"]",
"returnValue": "N/A",
"calledFrom": "com.godaddy.polaris.helpers.StringHelper.decryptBuildConfig(StringHelper.kt:45)"
}

[Crypto Monitor]
{
"category": "Crypto",
"class": "javax.crypto.Cipher",
"method": "doFinal",
"args": "[[68,95,105,-88,96,-12,24,-38,-95,-54,-90,88,101,-47,102,22,-97,45,28,-115,-120,124,-23,-63,117,126,116,-115,29,-95,-24,94]]",
"returnValue": "101,55,112,97,114,76,69,72,86,52,104,104,117,116,121,121,69,70,100,87,113,71",
"calledFrom": "com.godaddy.polaris.helpers.StringHelper.decryptBuildConfig(StringHelper.kt:48)"
}

[Crypto Monitor]
{
"category": "Crypto",
"class": "javax.crypto.spec.SecretKeySpec",
"method": "$init",
"args": "[[-66,-2,-71,20,-89,-76,-15,-1,84,-9,127,90,-16,-62,-109,58,-102,1,41,34,31,63,115,20,-32,-100,-75,-74,35,-2,-43,-73],\"AES\"]",
"returnValue": "N/A",
"calledFrom": "com.godaddy.polaris.helpers.StringHelper.decryptBuildConfig(StringHelper.kt:45)"
}
android-crypto-monitoring.js:
% frida -U -l android-crypto.js -f com.godaddy.gx.go --no-pause

Spawned `com.godaddy.gx.go`. Resuming main thread!
[Pixel 6::com.godaddy.gx.go ]-> [Crypto Monitor]
{
"category": "Crypto",
"class": "javax.crypto.spec.SecretKeySpec",
"method": "$init",
"args": "[[-66,-2,-71,20,-89,-76,-15,-1,84,-9,127,90,-16,-62,-109,58,-102,1,41,34,31,63,115,20,-32,-100,-75,-74,35,-2,-43,-73],\"AES\"]",
"returnValue": "N/A",
"calledFrom": "com.godaddy.polaris.helpers.StringHelper.decryptBuildConfig(StringHelper.kt:45)"
}

[Crypto Monitor]
{
"category": "Crypto",
"class": "javax.crypto.Cipher",
"method": "doFinal",
"args": "[[68,95,105,-88,96,-12,24,-38,-95,-54,-90,88,101,-47,102,22,-97,45,28,-115,-120,124,-23,-63,117,126,116,-115,29,-95,-24,94]]",
"returnValue": "101,55,112,97,114,76,69,72,86,52,104,104,117,116,121,121,69,70,100,87,113,71",
"calledFrom": "com.godaddy.polaris.helpers.StringHelper.decryptBuildConfig(StringHelper.kt:48)"
}

[Crypto Monitor]
{
"category": "Crypto",
"class": "javax.crypto.spec.SecretKeySpec",
"method": "$init",
"args": "[[-66,-2,-71,20,-89,-76,-15,-1,84,-9,127,90,-16,-62,-109,58,-102,1,41,34,31,63,115,20,-32,-100,-75,-74,35,-2,-43,-73],\"AES\"]",
"returnValue": "N/A",
"calledFrom": "com.godaddy.polaris.helpers.StringHelper.decryptBuildConfig(StringHelper.kt:45)"
}

References