GithubHelp home page GithubHelp logo

android-keystore-audit's People

Contributors

am-withsecure avatar bas-d avatar cduplooy avatar cybermilosz avatar deus-ex-silicium avatar leonjza avatar vvect avatar yogehi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-keystore-audit's Issues

Up-to-date frida

Thank you for providing such great tooling. Extremely helpful.

However, 2 scripts do not work correctly on Android 9 and newer Frida version (>12.6).

https://github.com/FSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass-via-exception-handling.js

after running the bypass() command, Frida >= 12.6 throws the following error message:

exception catched!Error: Wrapper is disposed; perhaps it was borrowed from a hook instead of calling Java.retain() to make a long-lived wrapper?

Unhandled exception in event loop:
  File "c:\python38\lib\asyncio\proactor_events.py", line 768, in _loop_self_reading
    f.result()  # may raise
  File "c:\python38\lib\asyncio\windows_events.py", line 808, in _poll
    value = callback(transferred, key, ov)
  File "c:\python38\lib\asyncio\windows_events.py", line 457, in finish_recv
    raise ConnectionResetError(*exc.args)

Exception [WinError 995] The I/O operation has been aborted because of either a thread exit or an application request
Press ENTER to continue...

Do you know how to modify the execute() function to be compatible with newer Frida version, please?

Similarly, the showKeyguard() function of the script https://github.com/FSecureLABS/android-keystore-audit/blob/master/frida-scripts/keyguard-credential-intent.js crashes when executed on newer Frida versions:

showKeyguard()

Process crashed: Trace/BPT trap

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/sargo/sargo:9/PQ3B.190801.002/5674421:user/release-keys'
Revision: 'MP1.0'
ABI: 'arm64'
pid: 25273, tid: 25292, name: Thread-2  >>> [APPNAME] <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x7ff5eaeae4'
    x0  0000000000000000  x1  00000000000062cc  x2  0000000000000006  x3  0000000000000000
    x4  6461706b616572ff  x5  0000000000000080  x6  0000000000000080  x7  8000000000000000
    x8  0000000000000083  x9  0000000000000001  x10 0000000000000002  x11 00000075951bc140
    x12 0000000018000004  x13 0000000000000058  x14 ffffffffffffffff  x15 0029543fc8f56283
    x16 00000074fca77188  x17 00000075925e2cd0  x18 00000074f78ec01a  x19 0000000000000006
    x20 00000000000062b9  x21 00000074f78ebb80  x22 00000074fcaeae90  x23 00000074fcaec0f0
    x24 000000750f9cc7e0  x25 00000074fcaec000  x26 0000000046508001  x27 ffffffffffffffff
    x28 00000074fcaea000  x29 00000074f78eb8d0
    sp  00000074f78eb850  lr  00000074fa971d84  pc  00000074fa971d9c

backtrace:
    #00 pc 0000000001dc1d9c  /system/app/Chrome/Chrome.apk (offset 0xf2e000)

It would be great, if you could update the scripts.

Thank you again for great research and scripts.

AES-GCM IV reuse

Hello,

Thank you for the clear blog on Android Keystore authentication, very helpful.
However, I think it's not a good idea to store the IV in sharedPreferences and reuse it for subsequent encryption operations with AES-GCM, as this exposes ciphertexts to a known-plaintext attack.

Proof of concept:
The following plaintexts have been encrypted with the demo-app:

P1: With AES-GCM you should not reuse
C1: bCqRKGQjnr07Qnk4WW5jeo9ARrEgdvFuHv0Wjxoz+fv3Q9+wsZaAQLpL8CzqAyhuNQ==

P2: The initialization vector
C2: byuAYC0Mspp/ZFYcA3Z4ZsBdDqgweeEhAsGcqLwfNjq0Mtq

The second plaintext can be derived by doing
P2 = C1 ⊕ C2 ⊕ P1
xor

An alternative approach could be to generate a fresh IV for each encryption operation and prepend it to the ciphertext.

For reference, the following key and IV were used for the example, above:
Application Key: 59F20FB3213DDE76F4D4F6598F70771035AB3F10DBF3D968B474C3A6B6786D08
IV: A4C8A8392FEEBC671D21FA3E71C8E8E7

Cyberchef recipe:

From_Base64('A-Za-z0-9+/=',true)
XOR({'option':'Base64','string':'byuAYC0Mspp/ZFYcA3Z4ZsBdDqgweeEhAsGcqLwfNjq0Mtq'},'Standard',false)
XOR({'option':'Latin1','string':'With AES-GCM you should not reuse'},'Standard',false)

App crashing immediately on start up

Step:

  • edit app/build.gradle adding
    lintOptions {
        abortOnError false
    }
  • build using ./gradlew build

App crashing immediately on start up

Output of adb logcat -b crash:

01-01 19:24:52.070 24273 24273 E AndroidRuntime: FATAL EXCEPTION: main
01-01 19:24:52.070 24273 24273 E AndroidRuntime: Process: com.example.keystorecrypto, PID: 24273
01-01 19:24:52.070 24273 24273 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.keystorecrypto/com.example.keystorecrypto.MainActivity}: java.security.InvalidAlgorithmParameterException: java.lang.IllegalStateException: At least one biometric must be enrolled to create keys requiring user authentication for every use
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:107)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:213)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8178)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: Caused by: java.security.InvalidAlgorithmParameterException: java.lang.IllegalStateException: At least one biometric must be enrolled to create keys requiring user authentication for every use
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi.engineInit(AndroidKeyStoreKeyGeneratorSpi.java:256)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi$AES.engineInit(AndroidKeyStoreKeyGeneratorSpi.java:53)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at javax.crypto.KeyGenerator.init(KeyGenerator.java:519)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at javax.crypto.KeyGenerator.init(KeyGenerator.java:502)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at com.example.keystorecrypto.KeystoreManager.generateSymmetricKey(KeystoreManager.kt:86)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at com.example.keystorecrypto.KeystoreManager.generateMasterKeys(KeystoreManager.kt:33)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at com.example.keystorecrypto.SecureLocalManager.<init>(SecureLocalManager.kt:27)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at com.example.keystorecrypto.MainActivity.onCreate(MainActivity.kt:26)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8086)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8074)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1313)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3755)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	... 11 more
01-01 19:24:52.070 24273 24273 E AndroidRuntime: Caused by: java.lang.IllegalStateException: At least one biometric must be enrolled to create keys requiring user authentication for every use
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.security.keystore.KeymasterUtils.addUserAuthArgs(KeymasterUtils.java:148)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi.engineInit(AndroidKeyStoreKeyGeneratorSpi.java:254)
01-01 19:24:52.070 24273 24273 E AndroidRuntime: 	... 22 more

Problems with Android 13 (API 33)

I was doing tests on android 13 (API 33) and it always fails with the following message:

`javax.crypto.IllegalBlockSizeException
at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:613)
at javax.crypto.Cipher.doFinal(Cipher.java:2056)

Caused by: android.security.KeyStoreException: Key user not authenticated (internal Keystore code: -26 message: In KeystoreOperation::update
Caused by:
0: In update: KeyMint::update failed.
1: Error::Km(ErrorCode(-26))) (public error code: 2 internal Keystore code: -26)
at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:369)
at android.security.KeyStoreOperation.handleExceptions(KeyStoreOperation.java:78)
at android.security.KeyStoreOperation.update(KeyStoreOperation.java:115)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer$MainDataStream.update(KeyStoreCryptoOperationChunkedStreamer.java:222)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:156)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:179)
at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:603)`

App Crash after successful biometric authentication

Android Device Info:

  • Android 10
  • Samsung M31

The app is crashing when biometric authentication is successful after clicking on LOCK button

From the logcat stacktrace :

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.keystorecrypto, PID: 20738
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:506)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100) 
     Caused by: javax.crypto.AEADBadTagException
        at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:517)
        at javax.crypto.Cipher.doFinal(Cipher.java:2055)
        at com.example.keystorecrypto.KeystoreManager.encryptApplicationKey(KeystoreManager.kt:112)
        at com.example.keystorecrypto.SecureLocalManager.loadOrGenerateApplicationKey(SecureLocalManager.kt:55)
        at com.example.keystorecrypto.MainActivity.onAuthenticationSuccessful(MainActivity.kt:118)
        at com.example.keystorecrypto.biometrix.BiometricCallbackV28.onAuthenticationSucceeded(BiometricCallbackV28.java:20)
        at android.hardware.biometrics.BiometricPrompt$1.lambda$onAuthenticationSucceeded$1$BiometricPrompt$1(BiometricPrompt.java:548)
        at android.hardware.biometrics.-$$Lambda$BiometricPrompt$1$ob5suq_ELA05xslg_M8nDaDCttg.run(Unknown Source:2)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8167)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100) 
     Caused by: android.security.KeyStoreException: Signature/MAC verification failed
        at android.security.KeyStore.getKeyStoreException(KeyStore.java:1564)
        at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
        at android.security.keystore.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:373)
        at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
        at javax.crypto.Cipher.doFinal(Cipher.java:2055) 
        at com.example.keystorecrypto.KeystoreManager.encryptApplicationKey(KeystoreManager.kt:112) 
        at com.example.keystorecrypto.SecureLocalManager.loadOrGenerateApplicationKey(SecureLocalManager.kt:55) 
        at com.example.keystorecrypto.MainActivity.onAuthenticationSuccessful(MainActivity.kt:118) 
        at com.example.keystorecrypto.biometrix.BiometricCallbackV28.onAuthenticationSucceeded(BiometricCallbackV28.java:20) 
        at android.hardware.biometrics.BiometricPrompt$1.lambda$onAuthenticationSucceeded$1$BiometricPrompt$1(BiometricPrompt.java:548) 
        at android.hardware.biometrics.-$$Lambda$BiometricPrompt$1$ob5suq_ELA05xslg_M8nDaDCttg.run(Unknown Source:2) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:8167) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100) 
I/Process: Sending signal. PID: 20738 SIG: 9

Missing license.

Hello!

Please could this project get a license? We received a PR (sensepost/objection#452) in another project that uses code from this, and I'd like to make sure that contribution is ok.

Thanks!

Patch for android 11 - fingerprint-bypass-via-exception-handling.js

Hello All,

I noticed that android 11 uses a different constructor for the BiometricPrompt$AuthenticationResult() function as you can find here: https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt.AuthenticationResult

Because of this the script will throw an error as it is expecting 2 arguments but gets 3.

Error: BiometricPrompt$AuthenticationResult(): argument types do not match any of:
	.overload('android.hardware.biometrics.BiometricPrompt$CryptoObject', 'int')
    at X (frida/node_modules/frida-java-bridge/lib/class-factory.js:563)
    at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:966)
    at e (frida/node_modules/frida-java-bridge/lib/class-factory.js:547)
    at <anonymous> (/fingerprint-bypass-via-exception-handling.js:65)
    at apply (native)
    at ne (frida/node_modules/frida-java-bridge/lib/class-factory.js:613)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:592)

Changing authenticationResultObj.$new(cryptoInst,null,0); to authenticationResultObj.$new(cryptoInst,0);
And authenticationResultObj.$new(crypto,null,0); to authenticationResultObj.$new(crypto,0); respectively should fix the issue.

Made a quick fix and posted it on frida codeshare here:

https://codeshare.frida.re/@krapgras/android-biometric-bypass-update-android-11/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.