You are on page 1of 27
ariigate Hacking Android phona, How deep the rabbit hole goes. kayrus Hacking Android phone. How deep the rabbit hole goes. My first Android phone, a Galaxy Note N7ooo, was bought just after the announcement in October 2011. Thanks to one German guy called bauner, [had an opportunity to use the latest version of CyanogenMod (now LineageOS). Unfortunately, my phone died after using a cheap Chinese car charger about one and a half years ago. 1 spent a lot of time looking for a replacement and stopped at the Kyocera (yes, they produce phones) KC-S7o1. It looks quite brutal and doesn’t have touch buttons. I did not even think about having root access to the phone. I was sure that nowadays every phone had a possibility to obtain root. And there will always be some guy who can port CyanogenMod to it. I was mistaken, Within one and a half years, only one kernel update was released—fix resolved kernel failure on a specially crafted ping packet. Besides, one year ago Android KitKat was already considered to be pretty old. Unfortunately, there was neither info, nor possibility to get root access. The same hardware is used in the American version of the phone called Kyocera Brigadier E6782. It has fastboot mode by default and there is no way to boot unsigned kernels (boot only, not flash, and only using an old vulnerable bootloader, CVE-2014~4325) and besides it provides an opportunity to boot into fastboot and recovery modes by pressing the phone's buttons. Through the efforts of Verizon MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20te%.20-abbIM%420N0Ie%20g008. him 1/27 ariigate Hacking Android phona, How deep the rabbit hole goes. (or maybe Kyocera?) The Android version of Brigadier has been updated to Lollipop. So, I decided to deal with the process of obtaining root on Android myself. ‘Two months ago I did not know anything about the Android internals (actually, now I don't know even more). Most of the knowledge was gained by reading the source code and by experiments, since there is a lack of information about the Android hacking on the Internet. The information below works on Android 4.4 KitKat, but I assume there is also a possibility to apply it on newer versions. I would like to draw your attention to the fact that the info described in this article is only my personal experience of Android hacking on a particular phone model, so be careful using it if you do not want to brick the phone. If you wish to root your phone using this article, I recommend that you forget that you are using your phone in everyday life, make a backup, and then perform a hard reset. This will protect your data in case of fatal mistakes. The article describes not only the actions that led to success, but also mistakes. I hope that my attempts to get to the desired result, and numerous fails, will be interesting to you. The research was conducted in the Linux environment, Dirtycow (CVE-2016-5195) In simple words dirtycow (working exploit for Android) allows you to replace the memory of any process (useful if you are familiar with the assembly), or any file available for reading, even if it is on the readonly filesystem. It is recommended to spoof the file which size is greater or equal to the size of the replacement. The main attack in dirtycow for Android is the /systen/pin/sun-as spoofing, It is some kind of sudo in Android which allows to debug applications. Since the android-19 API (see the table of matching API and Android versions) /eysten/bin/sun-as has CAP_SETUID and CAP_SETGID capabilities flags (in older versions suid bit is used - 6755 ) § geteap bin/ra egid, cap_sotuidtep MostIJ/CRACKINGIREVERSE%.20ENGINEERINGIacking%<20Android%20phone.%20How%20deep%20tne%.20-abbIM%420N0Ie%20g008. him 2/27 ariigate Hacking Android phona, How deep the rabbit hole goes. If the file system is mounted in read-write mode, everything which was spoofed by dirtycow will be written to the file system. Thus you have to make a backup of the original file and restore it after gaining the root access, or just don't remount the file system in read-write mode. Generally the /system partition in Android is mounted in read- only mode by default That is why dirtycow is considered to be one of the most serious vulnerabilities found in inux. And using the appropriate knowledge you can bypass all security levels of the Kernel, including SELinux, SELinux Beginners should know how the SELinux context works. There is a good article in the Gentoo wiki: https://wiki.gentoo.org/wiki/SELinux/Tutorials/How_does_a_process _getLinto_a_certain_context Ina nutshell, you should know the following: + SELinux process context can be changed if such an operation is described in sepolicy rules (context transition). Android 4.4 (KitKat) provides the possibility to elevate privileges by changing the SELinux context. Since Android 5.x it is not possible anymore, + There are file contexts + In addition to the process and file contexts, Android implemented its own property_contexts. + The rules look as follows: source context (application) is allowed to access target context (filesystem). In SELinux enforcement mode applications are allowed to do only the explicitly granted operations. The rest is forbidden. Adbd and console The only possible way to obtain a partly privileged shell in production Android devices—developer mode. Developer mode starts adbd daemon which can act as some kind of ssh / telnet server. In Android KitKat /sbin/acha binary is located in the initramfs and it is not readable for non-root users. Initially adbd is executed as the root user and it runs in u:rs init:s0 SELinux context (used by init and usually has more privileges than other contexts). If the /:niz.re has the explicitly specified process context, such as seclabel u:r:adbd:so, the MostI/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20tne%.20-abbIM%420NoIe%20g008. him 3127 ariigate Hacking Android phona, How deep the rabbit hole goes. process starts immediately in this context. In case of initializing, depending on compile options (user, userdebug or eng and Android settings (properties), adbd lowers the privileges: it changes the current user to shell, sets the SELinux context to u:r:shell:so and trims all system capabilities except CAP_SETUID and CAP_SETGID (that is required for debugging applications via rus-as ) Capability Bounding Set does not allow applications to escalate the capabilities, only to drop them. These privileges allow you to do a he little bit more than nothing. You can view capabilities of the current process with the following command cat /proc/sels/status | grep capsnd . And decrypt them with the caps command (not available on Android), for example.: § capsh --decode-oo0v001sseeeetee oxco0000isefresttfmcap_chown, cap de, cap_dac_read_s earch, cap_foxner,cap_fsetid, cap_Kill,cap_setgid,cap_setuid,e ap_se=peap, cap_1inux_innutable, cap_net_bind service, cap_not_ broadcast, cap net acnin,cap net raw,cap ipc lock,cap {pe own sp_sys_rawio, cap_sys_chreot,cap_sys_ptrac ¢,cap_ays_pacct, cap_ays_adnin,cap_sys_boot, cap_sys_n sys_resource, cap_sys_tine,cap_sys_tty_config, cap_mknod,cap_1 ase, cap_aud:t_write,cap_audit_control, cap_set‘c: verride, cap_rac_adnin, cap_syslog,cap_wake_alarn,cap block sa spend er, cap_sys_nodule, 6 2ap_ cap Maco You can view the current SELinux context using ia or ca /proc/sel*/atte/eurcent commands. Previous context could be viewed by cat /proc/self/attr/prev « View context of the files: is -2 View context of the running processes: ps -2 Get root access ‘The first thing I did was to use dirtycow for its intended purpose—to spoof the /systen/bin/run-as , which allows me to set UID / GID to 0 (same stuff ss does). However, [could not mount the file systems (as well as tmpfs), could not load kernel modules and view reag .T could not even browse the directory which had the 0700 permissions and belonged to other system users. I could only read and write to a block device. Viewing the files or directories was possible only when appropriate UID / GID were set to a specified user (invented my own wheel- ss alternative, which sets SELinux context and user / group. This helped me to understand internals). MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20te%.20-abbIM%20N0Ie%20g008. him 4/27 ariigate Hacking Android phona, How deep the rabbit hole goes. Then I made the dump of the entire firmware, boot and recovery: ardl/smcb1k0. ing foy-nama boo orage/adeardl frock v/bl: x/platfos 1/by-nane/x: You can examine the full dump using utilities such as ixeartx and sooackbooting . The ipartx -a nnbblk0.ing command creates a virtual block device which is available by /dev/mappe=/200p0_ path. You can work with your dump like with a regular block device. Dumps of the boot and recovery partitions can be unpacked using the enpackboot I Then | tried to zero the recovery, just to check whether write operations work, and then immediately restored recovery from the dump. If I could write into block devices, then I could also write the custom recovery. I found the TWRP of Brigadier, flashed it into recovery partition and restarted the phone: ad» rebo: -Ididn't see anything related to TWRP, only Android icon with an exclamation mark. It looked like a standard Android recovery, not like TWRP. I rebooted my phone into normal mode, ran the exploit and checked the hash of the recovery partiton—hash matched the original. I tried to write the data again—hash changed! Then I remembered about the Linux page cache and flushed it ( echo 3 > es ) ~ hash value matched the original again. Thus everything I wrote to a block device was “redirecte éev/nstt without any error and sometimes settled in the Linux cache. But how does the firmware update work? And how is the user data stored into the internal memory? I had to dig further. /proe/sys/vn/ dcop ot into Trying to disable SELinux At that time | thought that all the restrictions were caused by the lack of SELinux privileges (I totally forgot about the dropped capabilities). Tcould not view dmesg, logcat didn’t show anything relevant. I started to think how to disable SELinux. The first clue I could find: MosII/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20te%.20-abbIM%420NoIe%20g008. him 5/27 ariigate Hacking Android phona, How deep the rabbit hole goes. load_policy boot_initranfe/inst, fon property: selinux.reload policy = 1 rostart ueventd restart installa Source code says that when you change this option, init rereads and reloads the SELinux policy from the /sepoticy file Since I'm using dirtycow I can overwrite the /serciicy and execute the seterop selinux.seload policy 1 command to reload the updated policy. First of all you have to figure out what is inside the /sepoticy file. You can read its rules using the sesearch_ command ( setools package in Debian) 5 sosearch --allow sepolicy § sesearch --neverallow sepolicy 5 sesearch --auditaliow sepolicy § sosearch ~-dontaydit sepolicy In my case the /sepoticy_ file contained only allow rules which ‘means - when SELinux is in Enforcement mode applications are allowed to do only what is granted in the policy. And thus init process is allowed to reload the policy, but it is not allowed to change the enforcement mode allow init kernel: security load policy: My goal was to allow init context to set the enforcement mode into permissive (setenforce 0). The first step I did: built a standard policy from the stock Android KitKat, replaced the original /scpo1icy , loaded (being root: set»rop setinwe. reload policy 1 ) and received a message in the status bar that the phone was in the unprotected mode (more details about this notification later). After that the phone refused to run applications, became very thoughtful, besides I was still unable to set the MosIi:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20te%.20-abbIM%420h0Ie%20g00s. him 6/27 ariigate Hacking Android phona, How deep the rabbit hole goes. permissive mode and thus the phone eventually rebooted. A negative result is also a result,the /sopoiicy replacement worked. My first thought: the stock policy does not fit this phone and it starts, glitching due to lack of permissions. Then I decided to rebuild the original policy and add as much privileges to the shell context as possible. 1 found an article which explained how to “reverse engineer” the policy. I was able to resolve all the dependencies and run the se: utility. As a result I received a text file which I was able to compile back into the binary format ( chec policy.cont for KitKat) and even got the file with exactly the same ley -M -c 26 -0 sepoliey.new size as the original sepoticy , but different hex content. Loading of the new policy file caused exactly the same results as before - the phone rebooted after a couple of minutes. 1 decided to compile two policies from the following files: original decompiled cy.cont with all the privileges inside the a1iow init kernel: security , including setenforce. The comparison of these files could tell me which bytes I have to replace in the original sepo\ icy binary file. icy-conf and po Tt turned out that only two bytes were changed. I tried to find the match in the original sepolicy but I could not. Then I just wrote a brute force script which replaces two bytes to “oxFF, oxFF’, launches ep "desired result" and if it doesn't meet the result, tries to replace the bytes on the next incremented offset and so on, After a couple of minutes the script found the necessary offset in. the original policy. I replaced the bytes, spoofed the original policy on the phone. At this time it worked fine and didn't reboot. But I still could not disable the SELinux enforcement mode. Abit later I found a sepolicy-inject utility which could modify binary juicy file, It could add the new permissive SELinux context or add capability into the existing rule, While adding the permissive context increases the ego icy file, modification of the existing rule does not increase the size. Unfortunately, the utility adds only one permission per run. I had to write another script which granted all the capabilities to each rule. The new policy file size matched the original one. But again, the policy reload did not help. Then I noticed that Android had. 10. reloaded the policy from any path: oticy command which MostI/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20te%.20-abbIM%420N0Ie%20g008. him 7/27 ariigate Hacking Android phona, How deep the rabbit hole goes. # since / cwned by § in my arriinit:s0 load policy /data/local/tmp/sepolicy.new cal /enp/evn You can add any permissive domain, load the new policy and work in the context of this domain (by the way, supersu from chainfire works in the same manner for new Android versions). But even this didn’t give me the possibility to disable SELinux. I decided to dig in another direction, Investigating recovery I started from checking the difference between boot and recovery partitions. They were identical except for initramfs. The initramfs of the recovery partition has in: re which has only one service which executes -ecovery . Investigation of the ngs shin) wery | tess output and reading of the original recovery source code gave the following results: MosIi:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon9.%20How%20deep%20tne%.20-abbIM%420n0Ie%20g00s. him 8/27 ariigate Hacking Android phona, How deep the rabbit hole goes. + the default recovery simply displays the Android logo and then reboots after timeout + if you want to “enter” the recovery, you have to create the ‘cache/recovery/cosnand file with corresponding command inside, i.e. —-shov_toxt_ which will show the recovery menu. Iwrote the file and executed the act» rb: The phone rebooted and I was able to see the standard recovery ‘menu. At least some result, | tried to flash the supersu ZIP file via 2a» sidelosd . The operation terminated with an error. I did not really look at this error and started to investigate the recovery code responsible for the ZIP digital signature verification. scevery command, It turns out that the recovery initramfs contains a key in minierypt format which checks the ZIP file digital signature The public key appeared to be a standard Android fest key and so I can sign any ZIP file using this key. You can check this key using the commands below: keys public § Gift -u mykey res/xeys. 1 tried to install the ZIP directly from sdcard, but the recovery caused an error while mounting the sdcard. Investigation of the ete/recovery.fetab file showed the actual problem: the sdcard in the recovery mode was mounted as vfat: § grep mmeblk1 recovery/ramfs/ete/recovery. fstab /aev/black/nnels1kIpL/s My 64Gb sdcard was formatted in exFAT. I found an old 2Gb sdcard, reformatted it as vfat, wrote the ZIP and inserted it into the phone. This time the recovery was able to mount the volume and T could view its contents on the phone, However, the ZIP installation caused an error again: E: failed to set up expected mounts for install; aborting. MosIi:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%420How%20deep%20te%.20-abbIM%420N0Ie%20g00s. him 9127 ariigate Hacking Android phona, How deep the rabbit hole goes. The strings re hhad custom Kyocera strings, at least there were strings related to the eata partition wipe command. After reading the original source code I found that the error was caused in the s2:up function of the :octs.cep file, For some reason the recovery failed to ‘unmount all the partitions listed in ‘command showed that this recovery Investigating kernel sources Unlike the AOSP’s Apache license, the GPLv2 license requires from smartphones’ manufacturers to publish the Linux kernel source. Thanks to Linus and Stallman for this opportunity. Sometimes ‘manufacturers publish a fake source code, sometimes a correct one, but without the defcontis file, sometimes with defconfig and very rarely with the instructions on how to build the source code (e.g. LG) In my case the source code was distributed with the correct but without instructions. Thus I spent some time to build the kernel. After a long time of the source code investigation I stopped at two files: + hetps://github.com/kayrus/ke-s7o1-torque- kernel/blob/master/security/selinux/hooks.c + hutps://github.com/kayrus/ke-s7o1-torque- kernel/blob/master/arch/arm/mach-msm/restart.¢ hooks To increase the phone's security Kyocera just implemented custom SELinux hooks on potentially dangerous operations: insnoa_ (the only module allowed to be loaded is wisn and only if it is loaded by init process or non-root user) and some others. That's the actual reason why the recovery failed. It could not unmount the /systen partition! The mount/unmount operations of the /syscen partition are allowed only for the init process. In particular, I could not disable SELinux because this feature was disabled at the kernel compilation. These hooks could be bypassed only if the kernel was loaded with certain boot parameters (kedroidboot. mode=f-ksg or androidboot.mode=kefactory). MostIJ/CRACKINGIREVERSEY.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20te%.20-abbIM%420NoIe%20g00s. him 10127 ariigate Hacking Android phona, How deep the rabbit hole goes. restart This file describes possible reboot options for the phone: + adb reboot bootloader—fastboot mode, not available in my phone ( ox77668500 - oosse6e77 hex mark in sbi1_ partition) + adb reboot recovery—default Android recovery mode - 02556677 hex mark in spi1_ partition) ( ox776655: + adb reboot rtc—the so-called suas soor . I did not understand ‘what this was for, there was no hex mark in Probably it relates to hutps://developer.android.com/reference/android/app/AlarmMa pager: html + adb reboot oem-X (in my case oem, ox6=6 hex mark in se1 partition). The manufacturer defines what happens in this mode. According to the sources, the phone restarts into this mode in case of failed firmware files’ verification which are located in soden partition. + o1eassee + adb reboot edl—emergency download, reboots into a default Qualcomm download mode, The phone is identified as QHSUSB_BULK COM port, which can be used to boot a custom bootloader (but it should be signed by the private key corresponding to the phone model ), and perform low-level operations with your phone, including flashing, unlocking, ete. Usually used in conjunction with QPST application. For some phones these bootloaders have already leaked into the Internet. + Acertain download mode which could be triggered by kernel boot parameter. Looks quite interesting, Some info on how Qualcomm based phones are booted: Built-in ROM Qualcomm bootloader (pbl—primary bootloader) verifies and boots sb11 partition (secondary bootloader). sb11 verifies and boots 2 (trust zone), then ascot (Android boot, little kernel, 1k), Then aboot can boot into built-in fastboot maintenance mode, do the normal boot or boot into recovery or fota. Partition description involved at boot: + tz—Qualcomm Trust Zone. It performs low-level operations, including working with QFuses (rpmb secured mme partition) MosIi:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon9.%20How%20deep%20the%.20-abbIM%420noIe%20g00s. him 11/27 ariigate Hacking Android phona, How deep the rabbit hole goes. + tpm—Resource and Power Manager firmware. Firmware for specialized SoC, responsible for resources and power. + sdi—trust zone storage partition. The data which is used by ‘Trust Zone. All of these partitions are signed by a certificate chain. fota In some cases it is useful to ignore firmware updates. FOTA—firmware over the air. Unlike the boot or recovery, fota is an unofficial Android boot mode, Fota task is to update the firmware. Kyocera uses Red Bend proprietary solution which fits the whole update in 35Mb, It includes boot , 2, recovery systen partitions’ updated. That is why the /sys:en partition is available in read-only mode. If you modify this partition, the diff- based fota update can brick the phone. and even, ‘An update for my phone was available since September 2015. I didn't update my phone because I was afraid to loose an opportunity to root my phone. Now I can easily execute the update process since I have full access to cache partition and abort the update procedure at any time. After examining the source code of the responsible Java based update tool, it became clear to me how it functioned: + Java app downloads a special delta file into delta.bin , creates a /cache/delta/Alt- ot dicompiete file and verifies whether delta file was successfully downloaded. + When you confirm the update procedure it verifies the file again. + If previous verification succeeds then fotanag_ partition is modified using the iibjaiaito:a.so dynamic library. + Phone reboots. The reboot does not happen instantly, so I can delete a file before the reboot and see what will happen with the forsnng partition. I wrote the script which continuously made fotamng partition dump and renamed /cache/de1ta/boot_deita.bin file, Iran it immediately MostI/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20tne%.20-abbIM%420NoIe%20g00s. him 12/27 ariigate Hacking Android phona, How deep the rabbit hole goes. after the update confirmation. The phone rebooted into FOTA mode, showed an error and rebooted into normal boot mode. I started to investigate the dumped data. The /cache partition also contained a bonus: fota and dmseg logs! It appeared that fota boot could be initialized by couple of bytes set to 1" in sovanng partition: ‘ey-nane/fotanng seok-16 1 count=1 4 if=/data/local/enp/one, 0£=/dev/block/pLa -nane/fotanng seek: ta/local/=np/ot seek=191096 These bytes are cleared after the reboot. I also noticed the kedroidboot mode=f-ksg kernel parameter in fota dmesg logs. Here it is! Thus, bootloader removes the phone protection for fota boot and theoretically if I write a regular boot partiton instead of fota and reboot the phone into this mode, I will get the kernel with disabled Kyocera protection. But I still don’t have a write access to the system- related partitions. Investigating the little kernel (Ik) sources Little kernel or Android bootloader is located inside the aboot partition. Vanilla source code is available at: hitps://source.codeaurora.org/quic/la/kernel/Ik/ There you can find information on how to boot into some of the modes. For example, if you write the boot-recovery into the nisc partition, the next boot will be the recovery mode and there is no need to execute adb reboot recovery. When you boot into the recovery using this method the boot-recovery label If the recovery can not be booted, the phone will get the boot loop and you'll lose it. So be careful and preferably avoid this option to reboot. be reset You can also find the code which enables read-only protection of the the system-related emme area. This is an answer to the question why. itis impossible to rewrite the recovery partition. This protection can MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20tne%.20-abbIM%420NoIe%20g008. him 13/27 ariigate fle:INICRACKINGIREVERSEX.20ENGINEERING/Hacking!20Andeoid%20phone.%20How'%20deep%20theth Hacking Android phona, How deep the rabbit hole goes. be disabled in the Linux kernel. And such a module was already written by another guy who was interested in Kyocera phones. This, module works from time to time and sometimes hangs on mme claim function. Ideally it requires the detailed investigation. Here is how aboot verifies boot partitions: hitps://source.codeaurora.org/quic/la/kernel/Ik/tree/platform/msm eshared/image_verify.c7h=LA.BR.1.3.3.1b2.29 The first successes Google helped me to answer the question why I could not read the kernel log: /proc/sys/kernel/dmesq restrict . The value of this parameter is set to 1 while the phone boots. If the user does not have CAP_SYS_ADMIN capability, the logs are not available for it. uevent_helper In my case, surprisingly, I had the possibility to write into eiper . If you write the path to some executable, it will be executed under root user, init SELinux context and most importantly with full capabilities (shell script also works) /sys/kernel /uevent, I wrote the following script: #1 /systen/bin/ no 0 > /proc/sys/kernel/dnesg_rest Uploaded it on the phone, wrote its path into eiper and I got the possibility to read dmesg logst Patched adbd rabbi%20nole%20goes. html 14/27 ariigate Hacking Android phona, How deep the rabbit hole goes. Since I could not easily investigate the phone's internals because of the capabilities restriction I decided to build my own adbd with blackjack and hookers, To do this I had to download 70 Gb of Android source code (I didn’t want to mess with each dependency individually). I removed the check which drops the capabilities, compiled adbd, replaced the /sbin/ade and received a full root console. Now I can mount filesystems, read dmesg logs without messing with dmesg_restrict, easily view or edit files which are not owned by root, and much more. But I stil can not mount the /sysven partition and load modules into the kernel. By the way, this procedure can be avoided by compiling the Ish and writing its path into the /sys/kerne starting Ish wrapped in a script which sets the rar environment, otherwise you'll have to specify the full path to each command. avent_helper . I suggest WiFi ‘WiFi in my phone works through the kernel module. When WiFi is turned on—the module is loaded, When WiFi is turned off—the module is unloaded. If you replace the module file with your own and turn on WiFi—your spoofed module must be loaded. Fortunately, my phone doesn’t check modules’ digital signatures. The first thing I tried ‘was to compile and load the module which disabled the SELinux by replacing the kernel memory. The module was initially written for Amazon Fire Phone: https://github.com/chaosmaster/ford_selinux permissive You need to have a more or less appropriate kernel sources and Module. symvezs file in order to compile the module. If the source code explicitly corresponds to the kernel which is used in the phone, then you can use the woduie. generated during the kernel compilation process vere which is automatically If the kernel module complains on disagrees about version of symbol module layout, you will need to extract the Modis, symrers from the boot partition. This could be done using hitps://github.com/glandium/extract-symvers script: jot img -0 boot MosIiJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20te%.20-abbIM%420h0Ie%20g00s. him 18/27 ariigate Hacking Android phona, How deep the rabbit hole goes. ONE DOES NOT'SIMPLY, CES Ca aC Eerie Do you remember this list? The module should be called wian . Here is how I resolved this problem: + Created a wise.c symlink + Modified Makefile MODULE_NAME = wlan After applying these tricks and executing the svc wifi disable 6s ave wifi enable the module has successfully loaded (memory used bythe wan module reduced, it could be checked using 1ssoa command), but SELinux was not disabled The dmesg logs did not contain any information related to the new module. It was caused by another kernel option: /proc/sys/kernel/printk Which filters INFO logs including modules’ logs. I lowered the threshold for all logs: echo '8 8 8 8 > /pz0c/sye/kernet /prinzk , reloaded the module and it appeared that the module just could not find the required bytes pattern. I decided to write own kernel module Writing a module Disabling security protection Mosti:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20te%.20-abbIM%420h0Ie%20g00s. him 16/27 ariigate Hacking Android phona, How deep the rabbit hole goes. | failed to disable SELinux, but by analogy with https://github.com/chaosmaster/ford_selinux_permissive module I could try to disable Kyocera hooks. I just needed to set a ke_bootmode or ke_kbfm variable using the Linux kernel module. The Linux kernel has the possibility to get the pointers’ addresses of all the functions and variables: cat. /eroc/ka1 syns . By default, these addresses are displayed as 0. It is yet another kernel protection and can be disabled by the following command: echo 0 > Once you get the address of the desired function, you can call it with the appropriate parameter and function will set the corresponding variable to 1, I noticed that not all Linux kernels display addresses for the variables (d or D types, case says whether the variable is public or not) that is why I used function pointers, but not actual variable pointers. Perhaps it is determined by the coxrrc katzews ann option during the kernel compilation. First of all I had to declare the kernel function I'd like to call in the module: nt (* _ke_pootmode_setup) (char * buf) = (int (*) (0) ogi 9884; ‘And then call it: jotmeda_setup ("ikea") You can also determine the addresses dynamically: ke beotmode_setup = (Int (*} (char * buf)) kallsyns lookup name ( bo’ MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20tne%.20-abbIM%20H0Ie%20g00s. him 17/27 ariigate Hacking Android phona, How deep the rabbit hole goes. Tloaded the module and it disabled the protection! Now I can mount the /systen and load any kernel module regardless of its name. Protected eMMC area is still in read-only mode and it does not allow you to modify /systen partition on a regular basis. The files can be edited, but when you clean the kernel cache everything goes to its original state. Finally disabling SELinux Iwas already not required but just for fun, I decided to finally disable the SELinux. I could not modify the defined setinux enabled constant, but I could dereference the hooks pointers, 12 structure with This can be done by calling the reset_security ops function: void (* _reset_security_ops) (void) = NULE: peeea tet eerient eon Meets) kallsyms_lookup_name( £ (zeset_secarity ops! = NULL) { reeot_ security ope 0) inux hooks and functions, but the system still thinks that SELinux is enabled since se1inux enabled contains 1 integer value. Thus there may be some issues related to SELinux functions, ie. incorrect 1s -z output. Reboot into download mode bie dead mode) (char * ate) = (at (+) (0) The same operation works with downtoad mode Twrote above. After the module loading the phone reboot will boot it in a special mode which operates as USB mass storage device. Thus I have full access to all the phone's partitions! I tried to overwrite the recovery partition and it worked even after clearing the kernel cache Mosti:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20te%-20-abbIM%420h0Ie%20g00s. him 18/27 ariigate fleINICRACKINGIREVERSE%.20ENGINEERING/acking!20Andeoid%20phone.%20How%20deep%20the%20-abbit%20hole%20goes. him! Hacking Android phona, How deep the rabbit hole goes. Actually regular aa doesn’t work and phone's USB mass storage device disconnects and the writing stops. Perhaps this is a result of an internal cache overflow of the mass storage loader. I had to write a workaround, An advanced script for the heavy systen partition is available here: httws://github,com/kayrus/ke s701 break free/blob/master/inject_s upersu/write_rooted_system.sh. The primary trick is to read the data which you'd like to overwrite, Reading is much faster than writing, so I compare the source and destination hashes and if they differ I write new data. This saves lot of time and 1.2Gb modified partition can be flashed in 2-3 minutes instead of 35 minutes. Using this method | installed the supersu binaries into the downloaded /systen partition and flashed it back into the phone. The phone booted, but I got the following message in the notification bar: row security level. Inappropriate application may have been se uninstall it and reboot the phone. . [had already seen this message before when I loaded insecure SELinux policy. This notification also causes the permanent red LED blinking and the phone doesn’t turn off the screen on timeout (I guess to pay the user's attention that the phone was hacked). I spent some time and figured out that this notification was triggered by /systen/ve; daemon. It is a small daemon which monitors su / sudo binaries which can be found within rxrs , monitors SELinux state and en partition is mounted in read-write mode. It writes the security states into the /daca/sy jor /bin/akecd whether /sys r/aksed/out_4s.dat_ and triggers the notification mentioned above. I just disabled this service, but there should be a better fix to disable ss / sudo detection only and allow to monitor the /systen_ state since I still would like to control my phone's security. The initial task is completed: permanent root access and possibility to write into the external sdcard were obtained. In addition I wrote a utility which sets systen UID with the car_sys_soouse capability, uloads original wisn module then loads my false wian module which disables the security and finally loads the original via module again. My next goal was to boot custom kernel. I hoped there was no digital signature verification and I decided to boot my custom boot partition. Since it is dangerous to flash regular boot partition, I decided to flash it into the recovery partition and reboot into the recovery using adb reboot recovery command, Remember the aise partition, it is not recommended to boot into recovery through the boot 912 ariigate Hacking Android phona, How deep the rabbit hole goes. recovery entry in this partition, it can cause a boot loop. Unfortunately, the phone could not boot into recovery, it just vibrated and then rebooted into normal mode. Looks like I have to unlock the phone's bootloader. There is not much info on how to do this, but I found a couple of methods which worked for old phones: + hetps://github.com/beaups/SamsungCID. + hups://github.comy dirbliss/loki + hetps://bits-please.blogspot.com/2016/02/unlocking-motorola- bootloader.html Digital signatures of the aboot and boot Iwas curious how exactly aboot verifies the boot partitions. So I unpacked all the certificates from aboot partition ( inwatk ~« shoot ), extracted images signatures and looped over all the public keys trying to decrypt the signature. It turned out that all the boot images were signed using the same key. npackbootimg -i 09-boot.ing -0 boot # binwalk -¢ 05-aboot. img # openssl reautl ~raw -inkey <(openssl x509 —pubkey -noout ~ inform dex -in _0S-sboot.ing.excracted/46D2 2>/dev/nuil) ~pubin ~in signature.in 2>/dev/null | hd # print cert in text mode: openssl x509 inform der ~in 168R.crt text -noau {NAME} /nynew. img IMG) | awk ‘(print $1)" MostI/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon9.%20How%20deep%20te%.20-abbIM%420h0Ie%20g00s. him 20027 ariigate Hacking Android phona, How deep the rabbit hole goes. syonz¢_suna 2 then This script prints the following output: sha256 was decrypted using aboot.ing.extracted/31464.crt key ~ 0a? 56 si642 1994739403162¢7960 ove Verification of the aboot partition appeared to be more complicated. I ‘was able to extract and decrypt the sha2s6 signature of the image. But could not calculate this hash myself, Fortunately, Nikolay Elenkov, the author of the Android security internals helped and forwarded me to Qualcomm whitepaper: https://www.qualcomm.com/media/documents/files/secure-boot- and-image-authentication-technical-overview.pdf, It explains how target sha2s6 is calculated. The hash depends on im ro and sw 10 which are defined inside the certificate's subject, i.e. Subject: C=US, ST=CA, L=San Diego, OU=07 0001 SHA256, OU=06 001 MODEL_ID, OU=0s 00002000 SW_SIZE, OU=04 0039 OEM_ID, OU=03 0000000000000002 DEBUG, OU=02 009180E10039001F HW_ID, OU=o01 0000000000000009 SW_ID, (O=Kyocera wireless corp CSMS, CN=Ayano Nakamura ‘The working script is available in Nikolay’s github repository. Experimenting with the fota partition MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20tne%.20-abbIM%420H0I6%20g00s. him 21/27 ariigate fleINICRACKINGIREVERSE%.20ENGINEERING/acking!20Andeoid%20phone.%20How%20deep%20the%20-abbit%20hole%20goes. him! Hacking Android phona, How deep the rabbit hole goes. Since I know that boot/recovery and fota partitions are signed with the same key and the fota partition is booted with the disabled kernel security it’s worth trying to check whether flashing the boot partition into the fota partition can work, Itwas quite risky and I could get bootloop similar to recovery bootloop. The boot-in-fota sign is written into the rotaneg partition and if aboot did not boot the fota, it could try to boot it in the endless loop. Unfortunately, the boot partition written in fota could not be loaded, but fortunately LK resets fota bytes on boot and I did not face the bootloop. It is not clear why it doesn’t work, perhaps because of the different ramdisk and tag offsets (most probably they are hardcoded inside the LK) boot / recovery: tag: fota: tags: 0x0260000: Experimenting with the Brigadier bootloader For the experiments I ordered a Kyocera Brigadier with a broken screen. I checked the digital signatures of KC-S701 and Brigadier aboot partitions and it appeared that they were signed by the certificates with the same subject, so aboot partitions should be interchangeable. I decided to make an experiment: flash aboot from KC-S701 into the Brigadier. The bootloader successfully booted. Surprisingly, the eMMC write protection was not activated and I could easily restore the original bootloader (I suppose read-only flag can be set by QFuses) 22a ariigate Hacking Android phona, How deep the rabbit hole goes. ‘Then I tried to flash the aboot from Brigadier into the KC-S7o1. I could get the opportunity to use fastboot and boot any unsigned kernel. At this time the phone didn’t boot. At this point the story could end with the “phone didn’t boot” and a black screen. But, fortunately, this black screen was the “download mode”. I was able to flash the original aboot partition and the phone was resurrected. I still wonder why it didn't boot. Both certificate chains are valid and theoretically should be interchangeable. Most probably I faced this issue because Brigadier is based on msm8928 and KC-$701 is based on msms226 SoC. They are both from one So family but have some minor differences (msm8928 supports USB- ors). What should still be clarified Why sepolicy recompilation doesn’t work? Imperfect sepolicy decompiler? What does aboot partition hide? What hides behind the osm-1 reboot mode? Aboot partition contains the fastboot code, atleast: fash, erase, oem deviceint pteflash , oon snable-charger-sereen and oem disable-charger- screen commands. How can I enter the fastboot mode? How to disable camera shutter sound? ve found at least 3 options which somehow control camera shutter sound but none of these options works. The only way to disable it is to replace the /systen/ned‘a/audio/us/canera_click.oug file. But | don't like this solution and still want to find the way to disable this option in a more elegant way. Most probably it is controlled by proprietary Kyocera properties. Explanation Kyocera properties Kyocera along with Android system properties uses its own internal properties, I'm pretty sure there can be some tricky options which can influence the removal of bootloader protection or camera shutter sound which can not be disabled (oh man, 1 just realized how many restrictions are there in KC-S701). The phone has a libkejprop_jni.so dynamic library and the kejprop_daemon daemon. I can write an MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20tne%.20-abbIM%420h0Ie%20g008. him 23/27 ariigate Hacking Android phona, How deep the rabbit hole goes. app which will use this library, but comparing to other TODOs this task has low priority. Options are written into the filesystem and look like binary data: § 1s 1a /syaprop/k Kexec Kexec allows the Linux kernel to load another kernel. By default, the production kernel releases don't support Kexee, but it is possible to enable it using the kernel module. Then, using the user-end utility you can load any custom kernel which will replace the current one. It looks like a hack, but if you want to load your custom kernel and bypass digital signature verification—this is an option. QSEE vulnerability QSEE—Qualcomm TrustZone protection which could have a vulnerability to execute custom code within the TrustZone context: https://bits-please_blogspot.com/2016/o5/ qsee privilege-escalatior vulnerability.html. Looks like I have to build a specially formatted SCM command to burn the corresponding QFuse and unlock the bootloader. Still to be done Conclusion MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phon0.%20How%20deep%20te%.20-abbIM%420NoIe%20g00s. him 24/27 ariigate Hacking Android phona, How deep the rabbit hole goes. Every problem I resolve causes an amount of new problems and it is hard to predict how deep the rabbit hole goes. Modules’ source code, aboot loaders and the library to work with the Kyocera Properties are available in my github repo: httws://github,com/kayrus/ke s7o1 break free T would like to express my gratitude to the Kyocera developers for the excellent devices and high security. Otherwise, this article would not have been written, On the other hand, the lack of regular updates makes me really upset. If Kyocera has a new phone model with the ability to unlock the bootloader, 1 will certainly buy it. 1 still haven’t given up to unlock the bootloader. The most profitable time was on Christmas, but now it is hard for me to find some free time and focus on this problem. PS, Many thanks to Nikolay Elenkov. He explained to me how Android boot chain works and helped me with the aboot digital signature verification, MostI/CRACKINGIREVERSEY.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20te%.20-abbIM%20hoIe%20g00s. him 25/27 ariigate Hacking Android phona, How deep the rabbit hole goes. Mosti:/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20the%.20-abbIM%420hoIe%20g00s. him 26/27 ariigate Hacking Android phona, How deep the rabbit hole goes. MostIJ/CRACKINGIREVERSE%.20ENGINEERING/acking%<20Android%20phone.%20How%20deep%20tne%.20-abbIM%420N0Ie%20g00s. him 27/27

You might also like