Post has attachment
In July/August 2017 we discovered two interesting malware apps in GooglePlay. We wrote a short article about it: https://team-sik.org/sideloading-malware-googleplay-2017/

Post has attachment
Good day for us all !

Has anyone read anything somewhere else about this article? How Triada works? How it works on the sandbox Droid.Plugin ?
Please comment below, share a link, and thanks!

Post has attachment
Here is a simple tool for Android app reverse engineering and basic analysis for any vulnerabilities based on owasp. It's still more of a POC. Any feedback is most welcome.

I'm looking for a new job (remote) in android security (internals/reverse/vuln research/...). My resume can be found here: https://sh4ka.fr

P.S: I don't know if it's allowed to post something like that in this group. If not sorry and feel free to remove my post.

Hello everyone.
I wanna start in Android security.
Can any one recommend a beggener material to start with?
Thanks in advance.

We are organizing another Android Hacking Event (Android CTF) this year on 7th June. Feel free to participate either locally in Germany or remotely. Last year, it was a lot of fun and we hope it will be as successful as last year. This year, there will be also Android-based hardware challenges. More information here: www.sit4.me/ahe17

Post has shared content
Reshare here:
Here's a write up about some work that I did while trying to recovery some lost encrypted data on an LG G4:

Note that I am not especially well versed in reverse engineering or working with TZ / QSEE environments. I am definitely not an expert at these things, though I do have some experience working with Android encryption having developed decrypt support within TWRP. Some of the information in this article may be incomplete or completely wrong. I worked on this particular case in blocks of a few hours at a time over the course of several months, so my memory of things may be a little fuzzy.

Some time ago, an Android user asked me for help retrieving some encrypted data from an LG G4. In this case, the user had unlocked the bootloader on his LG G4 H811 T-Mobile USA model phone and had rooted the device. The user was using root to send various commands to the device to manually change the decryption password on the device. Normally the lock screen password and the password to decrypt the device on first boot are one and the same. The user was following an older version of the guide found here:
https://github.com/nelenkov/cryptfs-password-manager
The intent was to set a much stronger password for decrypting data while using a simpler password at the lock screen. At the earlier time, the guide did not contain the clear warnings about using the correct syntax that it does today.

Using root, you can communicate with vold using vdc, which is a binary included on most recent Android devices. Specifically, you can do things like:
vdc cryptfs checkpw 0000
All vold commands related to encryption use the “cryptfs” parameter. The checkpw command in this case would attempt to decrypt the data partition with a password of 0000. Note that the password type (pin/pattern/password) does not matter as all types boil down to a string of characters. The type of password is stored in the crypto footer, in the case of the G4, in the encrypt partition. The type is read by the device during boot and tells the device whether to display the pattern input, a simple numeric pad for pin, or a regular keyboard for passwords.

You can also use vdc to change your password and password type. Normally you would use a command like this:
vdc cryptfs changepw pin 0000 1111
In this case, we tell vold that we want to change the password with changepw and that we want the new password to be a pin. The 0000 is the old password and the 1111 is the new pin.

In this particular case, the user had supplied a different set of parameters. Specifically, the user had supplied something like:
vdc cryptfs changepw pin 1111
This syntax is actually the correct syntax on some devices and firmwares. Unfortunately in the case of the G4, the user ended up in a bad state where decrypt was no longer possible using any password, old or new. Ultimately the user ended up in the situation discussed here:
https://github.com/nelenkov/cryptfs-password-manager/issues/14
We will go into a deeper dive later to discuss exactly what happened and what we were able to do to ultimately decrypt the data on the device and successfully retrieve that data.

I purchased a LG G4 H811 from a local T-Mobile store. I OTA’ed the device up to the (at the time) latest Android 6.0 (marshmallow) 20i which can be found here:
https://forum.xda-developers.com/tmobile-g4/development/stock-h811-20i-images-kdz-flashable-t3308227

One of the first steps that I work towards when dealing with encryption is to obtain a root shell at or before the encryption prompt. On Nexus/Pixel devices, this is relatively easy as I can just download AOSP and make an engineering boot image. This approach isn’t possible on the G4 though. Instead, I modified the init scripts in the stock boot image to make adb start by default and set a slightly different set of USB settings. At this point I was able to obtain a non-root shell at the decrypt prompt. Further, I copied the adb_keys file out of an unencrypted data partition and placed the adb_keys file in the ramdisk so that my attempts to use adb would be authorized.

Next, I reached out to phh who develops his own open source superuser tools and asked if it was possibly to create a version of his su binary that did not require the user to grant root privileges via an app. He graciously supplied me with such a binary that I then included in the /sbin folder in the modified boot image. Now I was able to get a root shell at the decrypt prompt. This root access allows us to push files anywhere we want to the device, grab logcats and dmesgs, and even run vdc commands manually.

Based on past experience and looking at logcats, I was able to determine a few things about the encryption methods used on the LG G4. It appears to be fairly close to CAF using Qualcomm’s “hardware” encryption that I have seen used by Cyanogen Inc on the OnePlus One and by Motorola on various Moto G models. Specifically in the logcat, we see “HW based disk encryption is enabled”.
https://github.com/LineageOS/android_device_qcom_common/blob/cm-12.0/cryptfs_hw/cryptfs_hw.c#L181
The LG firmware includes a libcryptfs_hw.so in the system partition. I used the source code that we have available for this library from:
https://github.com/TeamWin/android_device_qcom_common/blob/android-6.0/cryptfs_hw/cryptfs_hw.c
I compiled my own libcryptfs_hw.so and replaced the one in the stock firmware with my own. It appears that LG made no changes to this library, as my own version of the library worked flawlessly for encrypting, decrypting, and changing passwords.

In addition, it appears that the G4 uses some modifications to CAF. Specifically, LG uses a TZ module named secureks. Perhaps this is short for secure keystore. LG has also replaced the key derivation from PIN/password with their own key manager library (km_, in liblgkm.so).

Before we go any further, I want to briefly highlight some of the relevant partitions on the G4 and try to explain each partition’s role. All of the partitions will be referred to here by name and may be found in /dev/block/platform/f9824900.sdhci/by-name/
userdata – The actual data partition in encrypted form
encrypt – contains encryption information. On the G4 this includes the counter which tells us how many tries we have left before we trigger a wipe. It also tells the device what input method to display (pin/pattern/password). I will also refer to this data as the “crypto footer”. On some devices this data is stored in the last 16KB of the data partition (hence the term footer) instead of in its own separate partition.
drm – appears to contain some password key/hash data used by LG’s secureks module
dm-0 – (full path is /dev/block/dm-0) which is created by the device mapper in the kernel when the encrypted data is successfully unencrypted.

Since I was able to supply my own libcryptfs_hw.so library, I added some additional logging to my library to log what password parameters were being sent and to get a better idea of what functions were being called and what values they were returning.

Nikolay (https://twitter.com/kapitanpetko) helped us out by supplying some information about what goes on in the vold change password function. The order of operations are found below. Note that function calls that begin with km_ are calls into liblgkm.so.
Call km_get_km_meta which we assume retrieves the current password information
Next km_encrypt_key and km_get_key_mac_by_password which appears to prepare the new password and put it in the proper format for saving
Call km_put_km_meta which saves the new password data (later we determine that this data is saved in the drm partition)
Call put_crypt_ftr_and_key which would update the password information in the encrypt partition
Finally call update_hw_device_encryption_key which updates the password that is saved in QSEE for Qualcomm’s hardware encryption

Here is a logcat of vdc cryptfs changepw pin 0000 1111:
01-08 00:25:16.132 368 412 E VoldCryptCmdListener: [LGE][VOLD][CommandListener.cpp][CryptfsCmd::runCommand()] argv[0]:cryptfs, argv[1]:changepw
01-08 00:25:16.132 368 412 D VoldCryptCmdListener: cryptfs changepw pin {}
01-08 00:25:16.132 368 412 I Ext4Crypt: ext4 crypto complete called on /data
01-08 00:25:16.132 368 412 I Ext4Crypt: No master key, so not ext4enc
01-08 00:25:16.134 368 412 I : Keymaster partition does not exists
01-08 00:25:16.134 368 412 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 00:25:16.134 368 412 D QSEECOMAPI: : App is not loaded in QSEE
01-08 00:25:16.180 368 412 D QSEECOMAPI: : Loaded image: APP id = 18
01-08 00:25:16.182 368 412 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 00:25:16.207 368 412 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 00:25:16.207 368 412 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 18
01-08 00:25:16.207 368 412 D QSEECOM_SEUCREKS_CLIENT: : sksc_decryption:: file_read success~!!!
01-08 00:25:16.235 368 412 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 00:25:16.235 368 412 D QSEECOMAPI: : App is not loaded in QSEE
01-08 00:25:16.273 368 412 D QSEECOMAPI: : Loaded image: APP id = 19
01-08 00:25:16.274 368 412 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 00:25:16.288 368 412 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 00:25:16.288 368 412 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 19
01-08 00:25:16.289 368 412 D QSEECOM_SEUCREKS_CLIENT: : sksc_decryption:: file_read success~!!!
01-08 00:25:16.305 368 412 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 00:25:16.305 368 412 D QSEECOMAPI: : App is not loaded in QSEE
01-08 00:25:16.342 368 412 D QSEECOMAPI: : Loaded image: APP id = 20
01-08 00:25:16.343 368 412 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 00:25:16.358 368 412 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 00:25:16.358 368 412 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 20
01-08 00:25:16.358 368 412 D QSEECOM_SEUCREKS_CLIENT: : sksc_decryption:: file_read success~!!!
01-08 00:25:16.358 368 412 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 00:25:16.358 368 412 D QSEECOMAPI: : App is not loaded in QSEE
01-08 00:25:16.395 368 412 D QSEECOMAPI: : Loaded image: APP id = 21
01-08 00:25:16.396 368 412 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 00:25:16.537 368 412 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 00:25:16.537 368 412 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 21
01-08 00:25:16.537 368 412 D QSEECOM_SEUCREKS_CLIENT: : sksc_encryption:: File_write success !!!
01-08 00:25:16.577 368 412 I : Keymaster partition does not exists
01-08 00:25:16.577 368 412 D : HW based disk encryption is enabled
01-08 00:25:16.577 368 412 E : set_key called with operation: 2
01-08 00:25:16.577 368 412 D : HW based disk encryption is enabled
01-08 00:25:16.577 368 412 E : get_tmp_passwd: Passed argument is '1111'
01-08 00:25:16.577 368 412 E : get_tmp_passwd: Passed argument is '0000'
01-08 00:25:16.963 368 412 E QSEECOMAPI: : SUCCESS::ioctl call to update the encryption key for usage 1 success with ret = 0
01-08 00:25:16.963 368 412 I Cryptfs : Encryption hardware key updated

In this case, the password was changed successfully from 0000 to 1111.

Now here is the output of vdc cryptfs changepw pin 0000:
01-08 02:08:31.589 367 402 E VoldCryptCmdListener: [LGE][VOLD][CommandListener.cpp][CryptfsCmd::runCommand()] argv[0]:cryptfs, argv[1]:changepw
01-08 02:08:31.589 367 402 D VoldCryptCmdListener: cryptfs changepw pin {}
01-08 02:08:31.589 367 402 I Ext4Crypt: ext4 crypto complete called on /data
01-08 02:08:31.590 367 402 I Ext4Crypt: No master key, so not ext4enc
01-08 02:08:31.595 367 402 I : Keymaster partition does not exists
01-08 02:08:31.595 367 402 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 02:08:31.595 367 402 D QSEECOMAPI: : App is not loaded in QSEE
01-08 02:08:31.670 367 402 D QSEECOMAPI: : Loaded image: APP id = 16
01-08 02:08:31.681 367 402 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 02:08:31.711 367 402 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 02:08:31.711 367 402 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 16
01-08 02:08:31.711 367 402 D QSEECOM_SEUCREKS_CLIENT: : sksc_decryption:: file_read success~!!!
01-08 02:08:31.748 367 402 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 02:08:31.748 367 402 D QSEECOMAPI: : App is not loaded in QSEE
01-08 02:08:31.828 367 402 D QSEECOMAPI: : Loaded image: APP id = 17
01-08 02:08:31.836 367 402 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 02:08:31.863 367 402 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 02:08:31.863 367 402 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 17
01-08 02:08:31.863 367 402 D QSEECOM_SEUCREKS_CLIENT: : sksc_decryption:: file_read success~!!!
01-08 02:08:31.887 367 402 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 02:08:31.887 367 402 D QSEECOMAPI: : App is not loaded in QSEE
01-08 02:08:31.964 367 402 D QSEECOMAPI: : Loaded image: APP id = 18
01-08 02:08:31.968 367 402 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 02:08:31.992 367 402 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 02:08:31.992 367 402 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 18
01-08 02:08:31.992 367 402 D QSEECOM_SEUCREKS_CLIENT: : sksc_decryption:: file_read success~!!!
01-08 02:08:31.992 367 402 D QSEECOMAPI: : QSEECom_get_handle sb_length = 0x1c00
01-08 02:08:31.992 367 402 D QSEECOMAPI: : App is not loaded in QSEE
01-08 02:08:32.057 367 402 D QSEECOMAPI: : Loaded image: APP id = 19
01-08 02:08:32.064 367 402 D QSEECOM_SECUREKS_TZ_CMD: : Loading app secureks succeded
01-08 02:08:32.216 367 402 D QSEECOMAPI: : QSEECom_dealloc_memory
01-08 02:08:32.216 367 402 D QSEECOMAPI: : QSEECom_shutdown_app, app_id = 19
01-08 02:08:32.216 367 402 D QSEECOM_SEUCREKS_CLIENT: : sksc_encryption:: File_write success !!!
01-08 02:08:32.223 367 402 I : Keymaster partition does not exists
01-08 02:08:32.223 367 402 D : HW based disk encryption is enabled
01-08 02:08:32.223 367 402 E : set_key called with operation: 2
01-08 02:08:32.223 367 402 D : HW based disk encryption is enabled
01-08 02:08:32.223 367 402 E : get_tmp_passwd: Passed argument is ''
01-08 02:08:32.223 367 402 E : get_tmp_passwd: Passed argument is ''
01-08 02:08:32.522 367 402 E QSEECOMAPI: : Error::ioctl call to update the encryption key for usage 1 failed with ret = -1, errno = 22
01-08 02:08:32.522 367 402 E Cryptfs : Error updating device encryption hardware key ret -9

In this case we end up in a bad state where we can no longer decrypt the device. (It may be worth noting that the device will register a change in the password type, e.g. pin to password, and display the new input method at the decrypt screen meaning that the crypto footer has been updated.) The new password that is being supplied to libcryptfs_hw.so is an empty string based on get_tmp_passwd: Passed argument is '' which we obtained by adding more logging to our libcryptfs_hw.so library in the set_key function here:
https://github.com/TeamWin/android_device_qcom_common/blob/android-6.0/cryptfs_hw/cryptfs_hw.c#L165

The set_key function calls a function in libQSEEComAPI.so which just calls an ioctl. I traced the ioctl through the G4 kernel all the way down to where the kernel passes the information to TZ to verify that it really was TZ that was supplying the error when trying to change the password to an empty string and that there was not some function in the kernel that was not handling an empty string.

During another test cycle, I backed up various partitions on the G4, then changed the password. I compared md5 outputs from the backups and the partitions and determined that the drm partition was apparently responsible for storing the password data that was being saved by liblgkm.so. I ran the “bad” vdc cryptfs changepw pin 0000 command again and placed the device in the state where it could no longer be decrypted. I restored the drm partition from the backup, then entered the old pin from before the bad vdc command and the device was able to be decrypted again.

So from the above test case, we learn some very valuable information. First, it is possible to potentially recover the encrypted data. It appears that if we can restore the drm partition to a working state, we will be back in good shape. Secondly, there appears to be a separation between the data that is stored by liblgkm.so and the data that is stored by Qualcomm’s hardware encryption routines. These two sets of data end up out of sync when we try to change the password using the bad vdc command.

At first, I thought long and hard about how I might go about trying to restore the drm partition to a working state. Finally, it dawned on me that a much simpler solution might be available. I compiled another libcryptfs_hw.so and hard coded the password in the set_key function to the old password. I ran vdc cryptfs checkpw ‘’ and device successfully decrypted!

So, let’s step back to our change password function calls from vold:
Call km_get_km_meta which we assume retrieves the current password information
Next km_encrypt_key and km_get_key_mac_by_password which appears to prepare the new password and put it in the proper format for saving
Call km_put_km_meta which saves the new password data (later we determine that this data is saved in the drm partition)
Call put_crypt_ftr_and_key which would update the password information in the encrypt partition
Finally call update_hw_device_encryption_key which updates the password that is saved in QSEE for Qualcomm’s hardware encryption

From the function calls and our logcats, we can now see that vold will save the new password data to the drm partition first, then update the Qualcomm hardware encryption data later. There is no code in vold to roll back the changes made to the drm partition by km_put_km_meta if the call to update_hw_device_encryption_key fails. The km_* functions will allow you to set an empty password and saves the new data as evidenced in the logcats by “QSEECOM_SEUCREKS_CLIENT: : sksc_encryption:: File_write success !!!”. The same empty password will fail to be saved by update_hw_device_encryption_key leaving the 2 sets of data out of sync.

After successfully decrypting the data partition, we were able to retrieve the data by using dd to dump the entire /dev/block/dm-0 partition, which is the device-mapped decrypted data. After dumping the data, we were able to mount the dumped image on a PC to view and retrieve individual files. Further, we were able to boot into TWRP, format the data partition, then use dd again to write the backed up data back to the data partition unecrypted and boot the device up with working, decrypted data, though we did have some troubles with the lock screen.

There are some other takeaways that I’d like to note. Using root to mess around with vdc can be dangerous. Either work with data that you don’t care if you lose, or make a good backup. The vdc commands in this case were only accessible by root. Ideally LG and even Google should improve error handling and roll back changes if some part of the password change process fails. The same type of issue potentially exists in AOSP, though I’m not aware of any Google devices using hardware disk encryption. See https://android.googlesource.com/platform/system/vold/+/android-7.1.1_r28/cryptfs.c#3360 and line 3370.

I believe that LG’s implementation of encryption and password handling to be potentially less secure than it would otherwise could be. Storing the password related data in the drm partition provides a larger attack surface. While I didn’t do an extensive dive into LG’s liblgkm.so, I don’t get the impression that liblgkm.so is using any hardware backing from TZ on the G4. Further, in more recent TZ implementations from Google, there is a rate limit. The rate limit is intended to make brute forcing a strong password impossible by limiting the number of password attempts in a given time frame. Some may say that the device will wipe itself after 10 or 30 failed attempts, but the counter for this forced wipe is stored in plain text in the crypto footer and it is easy to reset the counter. Further, I believe that the wipe is triggered by rebooting the device into recovery mode. An attacker could replace or remove the recovery to thwart attempts to wipe the data or simply reset the counter in the crypto footer. While I’m no expert, it seems likely that an attacker could utilize the weaker attack surface in LG’s liblgkm.so and drm partition to attempt to brute force the user’s password.

Post has attachment
Today, we fully-disclose 26 vulnerabilities in Android Password Manager Apps: https://team-sik.org/trent_portfolio/password-manager-apps/ #TeamSIK

Post has attachment

Post has attachment
"Google launches Project Zero bug hunting competition

Researchers interested in breaking Android security can earn themselves up to $200,000."

http://www.zdnet.com/article/google-launches-project-zero-bug-hunting-competition/
Wait while more posts are being loaded