daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

shizuku-privileged-api.md (19182B)


      1 ---
      2 title: "Shizuku Privileged API"
      3 section: "Mobile"
      4 sectionSlug: "mobile-pentesting"
      5 sourcePath: "src/mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Shizuku Privileged API
     14 
     15 Shizuku is an open-source service that **starts a privileged Java process with `app_process`** and exposes selected **Android system APIs over Binder**.
     16 Because the process runs with the same **`shell` UID capabilities that ADB uses**, an app that is explicitly authorised by the user can proxy Binder calls to system services **without rooting the device**.
     17 
     18 In practice, this means a Shizuku-enabled app can often exercise the same primitives as `adb shell`: package management, `appops`, `settings`, `cmd connectivity`, log collection, and many other shell-allowed Binder transactions. It is still **not root** and it is still constrained by **Android permissions, Linux UID checks, SELinux policy, Android version, and OEM-specific restrictions**.<sup>[[1]](#references)</sup>
     19 
     20 Typical use cases:
     21 * Security auditing from an un-rooted handset
     22 * On-device package management, debloating and split-APK installation
     23 * Collecting logs, package metadata and shell-visible network/process state
     24 * Building PoCs or helper tooling that need **ADB-grade** access but not a full root chain
     25 
     26 ---
     27 ## 1. Starting the privileged service
     28 
     29 `moe.shizuku.privileged.api` can be started in three different ways. The Binder interface exposed to client apps is the same, but the effective privilege depends on whether the backend is **ADB/shell** or **root**.
     30 
     31 ### 1.1 Wireless ADB (Android 11+)
     32 1. Enable **Developer Options -> Wireless debugging** and pair the device.
     33 2. Inside the Shizuku app select **"Start via Wireless debugging"**.
     34 3. The session survives until reboot unless the OEM ROM kills wireless debugging or revokes the debugging authorisation.
     35 
     36 ### 1.2 USB / local ADB one-liner
     37 ```bash
     38 adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh
     39 ```
     40 The same script can be executed over a **network ADB** connection (`adb connect <IP>:5555`).
     41 
     42 ### 1.3 Rooted devices
     43 If the device is already rooted run:
     44 ```bash
     45 su -c sh /data/adb/shizuku/start.sh
     46 ```
     47 
     48 ### 1.4 OEM quirks that matter during testing
     49 * **MIUI / HyperOS** often requires **USB debugging (Security settings)** in addition to the normal USB debugging toggle.
     50 * **ColorOS / OxygenOS** commonly requires disabling **Permission monitoring** or equivalent security wrappers.
     51 * On Android 11+, **Disable adb authorization timeout** reduces random Shizuku loss during long test sessions.
     52 * If wireless startup keeps failing, allow Shizuku to run in the background; several OEM ROMs suspend local-network discovery when the app is backgrounded.
     53 
     54 ### 1.5 Verifying that it is running
     55 ```bash
     56 adb shell dumpsys activity service moe.shizuku.privileged.api | head
     57 adb shell service list | grep shizuku
     58 ```
     59 A successful start returns a running service and exposes a Binder service related to `moe.shizuku.privileged.api`.
     60 
     61 ---
     62 ## 2. Binding from an application
     63 
     64 A Shizuku-enabled app does **not** use the raw Binder returned by Shizuku as if it were `IPackageManager`. The normal flow is:<sup>[[2]](#references)</sup>
     65 1. add the Shizuku API permission and `ShizukuProvider`,
     66 2. wait for the Shizuku Binder to appear,
     67 3. request Shizuku's runtime-style authorisation from the user,
     68 4. wrap the target system-service Binder with `ShizukuBinderWrapper`.
     69 
     70 Manifest requirements:
     71 ```xml
     72 <uses-permission android:name="moe.shizuku.manager.permission.API"/>
     73 
     74 <provider
     75     android:name="rikka.shizuku.ShizukuProvider"
     76     android:authorities="${applicationId}.shizuku"
     77     android:multiprocess="false"
     78     android:enabled="true"
     79     android:exported="true"
     80     android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
     81 ```
     82 
     83 Minimal Binder-wrapper example:
     84 ```java
     85 Shizuku.addBinderReceivedListenerSticky(() -> {
     86     if (Shizuku.checkSelfPermission() != PackageManager.PERMISSION_GRANTED) {
     87         Shizuku.requestPermission(1000);
     88         return;
     89     }
     90 
     91     IPackageManager pm = IPackageManager.Stub.asInterface(
     92         new ShizukuBinderWrapper(SystemServiceHelper.getSystemService("package"))
     93     );
     94 });
     95 ```
     96 
     97 That wrapper is what causes Binder transactions to be forwarded by the Shizuku service process instead of being executed with the caller app's normal UID.
     98 
     99 ### 2.1 UserService: when you need more than a single Binder call
    100 For anything more complex than direct Binder transactions, modern Shizuku development prefers **UserService** instead of the old `newProcess` helper. A UserService runs **your own Java/JNI code** in a separate process as **UID 2000 (`shell`)** when Shizuku was started via ADB or **UID 0** when backed by root.<sup>[[2]](#references)</sup>
    101 
    102 ```java
    103 Shizuku.UserServiceArgs args = new Shizuku.UserServiceArgs(
    104     new ComponentName(this, AuditService.class))
    105     .daemon(false)
    106     .version(1)
    107     .processNameSuffix("audit");
    108 
    109 Shizuku.bindUserService(args, conn);
    110 ```
    111 
    112 This is useful for offensive tooling that needs long-lived state, JNI helpers, or repeated Binder operations without paying the cost of spawning shell commands over and over. Remember that the service is **not a normal app process**: some `Context` methods do not behave like they do inside a regular Android application.
    113 
    114 ### 2.2 Boundaries that still apply
    115 * **ADB/shell and root are different privilege levels.** `Shizuku.getUid()` returns `2000` for shell-backed sessions and `0` for root-backed sessions.
    116 * Shell permissions **change between Android releases** and can also be trimmed by OEMs.
    117 * Shell still cannot directly read another app's private sandbox such as `/data/user/0/<package>`.
    118 * Hidden API restrictions still apply to code running in the normal app process; if you need non-SDK interfaces extensively, move the logic into a UserService or use a dedicated hidden-API bypass.
    119 
    120 ---
    121 ## 3. Rish - elevated shell inside Termux
    122 The Shizuku settings screen exposes **"Use Shizuku in terminal apps"**. Enabling it downloads `rish`, which opens a remote privileged shell backed by Shizuku.
    123 
    124 ```bash
    125 pkg install wget
    126 wget https://rikka.app/rish/latest -O rish && chmod +x rish
    127 
    128 # start elevated shell (inherits the binder connection)
    129 ./rish
    130 whoami   # -> shell
    131 id       # uid=2000(shell) gid=2000(shell) groups=... context=u:r:shell:s0
    132 ```
    133 
    134 Useful detail for Termux-heavy workflows: when Shizuku runs as ADB/shell, `rish` intentionally avoids preserving Termux's environment by default because the shell user usually cannot traverse Termux-private paths.
    135 
    136 ### 3.1 Useful commands from the `rish` shell
    137 * List running processes of a given package:
    138   ```bash
    139   ps -A | grep com.facebook.katana
    140   ```
    141 * Enumerate listening sockets and map them to packages:
    142   ```bash
    143   netstat -tuln
    144   for pid in $(lsof -nP -iTCP -sTCP:LISTEN -t); do
    145       printf "%s -> %s\n" "$pid" "$(cat /proc/$pid/cmdline)";
    146   done
    147   ```
    148 * Dump every application's logs exposed to shell:
    149   ```bash
    150   logcat -d | grep -iE "(error|exception)"
    151   ```
    152 * Bulk debloat (example):
    153   ```bash
    154   pm uninstall --user 0 com.miui.weather2
    155   ```
    156 * Inspect users and profile layout before multi-user abuse:
    157   ```bash
    158   pm list users
    159   dumpsys user
    160   ```
    161 
    162 ### 3.2 Modern abuse patterns enabled by shell-backed Shizuku
    163 
    164 #### AppOps and special-permission tampering
    165 Shizuku-enabled managers such as App Ops or App Manager are effectively wrapping shell-authorised `appops` and package-manager Binder calls. From `rish`, the same primitive can be used directly:
    166 
    167 ```bash
    168 cmd appops get com.target.app
    169 cmd appops set --uid com.target.app RUN_IN_BACKGROUND ignore
    170 cmd appops set com.target.app SYSTEM_ALERT_WINDOW allow
    171 ```
    172 
    173 This is useful during pentests to validate whether an app or MDM agent actually tolerates aggressive AppOps manipulation without requiring root.
    174 
    175 #### Per-app network isolation without VPN or root
    176 Recent Shizuku-based tools such as ShizuWall use the `connectivity` service's **chain-3** controls to block networking for selected packages:<sup>[[3]](#references)</sup>
    177 
    178 ```bash
    179 cmd connectivity set-chain3-enabled true
    180 cmd connectivity set-package-networking-enabled false com.example.agent
    181 cmd connectivity set-package-networking-enabled true com.example.agent
    182 ```
    183 
    184 For assessments, this gives you a fast way to test how a target app behaves when a competing security, telemetry or management package is selectively cut off from the network while the rest of the device remains online. The state is cleared on reboot.
    185 
    186 #### On-device advanced installs and split APK workflows
    187 Modern Shizuku installers such as InstallWithOptions or InstallerX-Revived use shell-backed `PackageInstaller` access to perform operations that are otherwise awkward from a normal app: split APK installs, test-only packages, batch installs, and some Android 14 package-install flags.<sup>[[3]](#references)</sup>
    188 
    189 From an offensive-testing point of view, the important part is not the GUI but the primitive: **Shizuku turns package installation back into an on-device shell-authorised action**, which is useful for persistence tests, downgrade checks and rapid deployment of helper payloads on a non-rooted handset.
    190 
    191 #### Work-profile and secondary-user boundaries
    192 Shell-backed Shizuku is still subject to Android's user restrictions. On managed profiles you will often hit errors such as:
    193 
    194 ```text
    195 INSTALL_FAILED_USER_RESTRICTED
    196 Shell does not have permission to access user X
    197 ```
    198 
    199 If you are specifically testing work-profile bypasses or required-app replacement, keep that material in the dedicated page instead of duplicating it here:
    200 [Android Enterprise Work Profile Required-App Replacement](/hacktricks/mobile-pentesting/android-app-pentesting/android-enterprise-work-profile-bypass)
    201 
    202 #### Accessibility-assisted local Wireless ADB pairing and Shizuku-style helpers
    203 
    204 Android 11+ supports Wireless Debugging pairing by code, and the paired host remains authorised until the user forgets it or revokes ADB debugging authorisations.<sup>[[6]](#references)</sup>
    205 
    206 Some Android RATs now replicate the **Shizuku architecture** instead of waiting for the user to start Shizuku explicitly. The interesting part is the **attack chain**, not Shizuku itself:<sup>[[4]](#references)</sup>
    207 
    208 1. A rogue [Accessibility service](/hacktricks/mobile-pentesting/android-app-pentesting/accessibility-services-abuse) navigates Settings, taps the build number seven times, enables **Developer Options -> Wireless debugging**, opens **Pair device with pairing code**, and reads the code directly from the UI tree while an overlay hides the workflow.
    209 2. An embedded ADB client then pairs with the same handset's own `adbd` over **`127.0.0.1`**, so the phone becomes both the **ADB host and target** with no PC or USB cable involved.
    210 3. After pairing, the malware launches a helper process under **UID 2000 (`shell`)** and talks to it over **Binder IPC** exactly like a Shizuku-enabled app would talk to a shell-backed UserService.
    211 
    212 A protocol-level variant automates the pairing dialog itself: Accessibility launches `Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS`, enables Wireless Debugging, and polls the **Pair device with pairing code** modal for both its dynamic port and six-digit secret. An embedded client then connects to `127.0.0.1:<port>`, establishes TLS, performs the PIN-backed SPAKE2 exchange, authenticates its generated ADB key pair, exchanges peer metadata, and finally submits ADB commands in the `shell` context. This is **not root**, and the exact post-pairing commands must be recovered from the sample or runtime traffic because the public analysis did not publish them.<sup>[[7]](#references)</sup>
    213 
    214 That gives the malware a non-root but still highly privileged execution context that can usually:
    215 
    216 - run arbitrary shell commands as `uid 2000`
    217 - grant itself `WRITE_SECURE_SETTINGS` and modify `Settings.Secure` / `Settings.Global`
    218 - silently install or uninstall APKs
    219 - grant runtime permissions without normal user approval flows
    220 - call shell-reachable Binder APIs and capture low-level input events
    221 - stream the screen through shell-accessible capture paths instead of depending only on MediaProjection consent dialogs
    222 
    223 This matters during assessments because a previously one-time Wireless Debugging approval can be converted into an **on-device privilege broker**. If the malware stores ADB pairing material, a `BOOT_COMPLETED` receiver can restore Wireless Debugging, reconnect to local `adbd`, and respawn the shell helper after every reboot.
    224 
    225 Observed keep-alive enhancements around this pattern include **1x1 foreground activities**, silent `MediaSession` playback, `WakeLock`s, two services in different processes that rebind each other with `BIND_AUTO_CREATE` / `onServiceDisconnected()`, periodic restart alarms, writes to `/proc/<pid>/oom_score_adj`, and `mlock()` to pin hot pages in RAM.
    226 
    227 #### Build-specific kernel exploit staging and KernelSU late-load handoff
    228 Another practical pattern is to use **shell-backed Shizuku only as the staging bridge** for a **build-specific local kernel exploit**, then hand the post-root workflow to **KernelSU/ReSukiSU**.<sup>[[5]](#references)</sup>
    229 
    230 A robust wrapper usually does all of the following **before** launching the native payload:
    231 
    232 1. Collect an **exact target profile** from JNI / shell-visible sources such as `getprop`, `/proc/version`, `uname`, `getconf PAGESIZE`, and `ro.build.display.id`.
    233 2. Match **codename + build ID + kernel version + ABI + page size** against an explicit allowlist (for example an embedded `profiles.json`) and **abort on mismatch**.
    234 3. Use a Binder-bound **Shizuku UserService** or similar helper to extract the matching native payload into **`/data/local/tmp`** and execute it as **UID `2000` (`shell`)**.
    235 4. If the exploit succeeds, immediately convert the one-shot kernel primitive into a **reusable local root channel** such as a privileged daemon or **Unix-domain socket** (for example `temp_su.sock`) so later steps do not need to rerun the kernel exploit.
    236 5. Stage a `ksud` binary matching the target **KMI** and late-load KernelSU:
    237 
    238 ```bash
    239 getprop ro.build.display.id
    240 getconf PAGESIZE
    241 uname -a
    242 ksud late-load --kmi <kmi>
    243 ```
    244 
    245 This pattern is useful because **Shizuku gives reliable ADB/shell execution and file-placement primitives on non-rooted devices**, while the fragile build-dependent exploit is kept inside a native payload selected only for the exact firmware. After the root channel is up, the workflow can verify KernelSU activation by checking artifacts such as **`/dev/kernelsu`**, **`/sys/kernel/kernelsu`**, and **`/data/adb/ksu`**.
    246 
    247 The same design is also a good detection model: watch for **Shizuku-authorised apps dropping native helpers into `/data/local/tmp`**, launching shell-owned payloads, creating local privileged sockets, and then invoking **`ksud late-load --kmi ...`** or triggering a **soft reboot / `system_server` restart** to stabilize the new root environment.
    248 
    249 ---
    250 ## 4. Security considerations / detection
    251 1. Shizuku needs **ADB debugging** or **root** first, so _Developer Options -> USB/Wireless debugging_ must be enabled on non-rooted devices. Unexpected enablement of **Developer Options**, **Wireless debugging**, or pairing-code dialogs on a production handset is already a strong signal.
    252 2. The service registers itself under the name `moe.shizuku.privileged.api`.
    253    `adb shell service list | grep shizuku` and `adb shell dumpsys activity service moe.shizuku.privileged.api` are reliable quick checks for benign tooling; malware variants may instead expose their own shell-owned Binder helper or native server.
    254 3. Capabilities are limited to what the current backend has. On ADB-backed sessions, that means the effective attack surface is the one exposed to **`com.android.shell`** on that Android build, plus whatever SELinux permits.
    255 4. A normal Shizuku session does **not** survive a reboot unless the device is rooted and Shizuku is configured as a startup daemon. However, malware that stores ADB pairing keys and can re-enable Wireless Debugging (for example via Accessibility + `WRITE_SECURE_SETTINGS` / `Settings.Global` abuse) may reconnect to local `adbd` after boot and recreate the shell helper without root.
    256 5. High-signal detection ideas for this abuse chain:
    257    - correlate Accessibility-driven taps on **Build number**, an `APPLICATION_DEVELOPMENT_SETTINGS` launch, Wireless Debugging activation, and immediate scraping of a six-digit pairing modal; this sequence is much stronger than any event alone.<sup>[[7]](#references)</sup>
    258    - local ADB TLS/SPAKE2 traffic or pairing attempts against **`127.0.0.1`**, especially to a port just read from the Settings UI.<sup>[[7]](#references)</sup>
    259    - shell-owned helper processes spawned from an app workflow (for example a native library acting as a local privileged server)
    260    - unexpected writes to `Settings.Secure` / `Settings.Global` or silent grants of `WRITE_SECURE_SETTINGS`
    261    - suspicious `BOOT_COMPLETED` receivers that restore debugging state or reload stored ADB keys
    262    - persistence helpers such as `1x1` activities, silent `MediaSession` playback, `WakeLock`s, cross-process `BIND_AUTO_CREATE` resurrection, writes to `/proc/<pid>/oom_score_adj`, or native `mlock()` use
    263 6. OEM "security" layers often break or silently reduce Shizuku functionality. If a command works via direct `adb shell` but fails through Shizuku, compare the current backend UID (`Shizuku.getUid()`), OEM debugging toggles, and whether the device trimmed shell permissions.
    264 
    265 ---
    266 ## 5. Mitigation
    267 * Disable USB/Wireless debugging on production devices.
    268 * Monitor for Binder services exposing `moe.shizuku.privileged.api`.
    269 * Enforce work-profile or MDM restrictions that remove debugging features from managed users.
    270 * Treat Shizuku-compatible tooling as **ADB-equivalent** during threat modelling; it is a post-exploitation force multiplier even when the device is not rooted.
    271 * Treat the combination of **Accessibility + Wireless debugging + shell-backed Binder helpers** as a high-risk chain, not as independent low-severity events.
    272 
    273 ---
    274 ## References
    275 
    276 - [1] [Shizuku Official Documentation](https://shizuku.rikka.app/)
    277 - [2] [Shizuku-API Developer Guide](https://github.com/RikkaApps/Shizuku-API)
    278 - [3] [awesome-shizuku - list of supported apps](https://github.com/timschneeb/awesome-shizuku)
    279 - [4] [RedHook Returns with a Dangerous Upgrade](https://www.group-ib.com/blog/redhook-android-rat-upgraded/)
    280 - [5] [Root My Pixel: Automated Temporary Root and KernelSU Late Loading on Google Pixel Devices](https://github.com/alex193a/Root-My-Pixel)
    281 - [6] [Android Debug Bridge: Connect to a device over Wi-Fi](https://developer.android.com/tools/adb#connect-to-a-device-over-wi-fi)
    282 - [7] [ToxicPanda Never Sleeps: ToxicPanda 2.0 Prepares Its Next Mobile Strike](https://zimperium.com/blog/the-toxicpanda-never-sleeps-toxicpanda-2.0-prepares-its-next-strike-on-mobile)