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)"
}