Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
- [Intent Injection](mobile-pentesting/android-app-pentesting/intent-injection.md)
- [Make APK Accept CA Certificate](mobile-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md)
- [Manual DeObfuscation](mobile-pentesting/android-app-pentesting/manual-deobfuscation.md)
- [Play Integrity Attestation Bypass](mobile-pentesting/android-app-pentesting/play-integrity-attestation-bypass.md)
- [React Native Application](mobile-pentesting/android-app-pentesting/react-native-application.md)
- [Reversing Native Libraries](mobile-pentesting/android-app-pentesting/reversing-native-libraries.md)
- [Shizuku Privileged Api](mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md)
Expand Down
2 changes: 2 additions & 0 deletions src/mobile-pentesting/android-app-pentesting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Sometimes it is interesting to **modify the application code** to access **hidde
## Other interesting tricks

- [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md)
- [Play Integrity attestation spoofing (SafetyNet replacement)](play-integrity-attestation-bypass.md)
- [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.md)
- [Exploiting Insecure In-App Update Mechanisms](insecure-in-app-update-rce.md)
- [Abusing Accessibility Services (Android RAT)](accessibility-services-abuse.md)
Expand Down Expand Up @@ -878,6 +879,7 @@ AndroL4b is an Android security virtual machine based on ubuntu-mate includes th

## References

- [Play Integrity API: How It Works & How to Bypass It](https://m4kr0.vercel.app/posts/play-integrity-api-how-it-works--how-to-bypass-it/)
- [https://owasp.org/www-project-mobile-app-security/](https://owasp.org/www-project-mobile-app-security/)
- [https://appsecwiki.com/#/](https://appsecwiki.com/#/) It is a great list of resources
- [https://maddiestone.github.io/AndroidAppRE/](https://maddiestone.github.io/AndroidAppRE/) Android quick course
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Play Integrity Attestation Bypass (SafetyNet Replacement)

{{#include ../../banners/hacktricks-training.md}}

## What Play Integrity Does

**Play Integrity** is Google’s SafetyNet successor for **app attestation**. The app calls the API, Google Play Services gathers software/hardware signals, sends them encrypted to `googleapis.com`, and Google returns a **JWT** that is *signed and encrypted* by Google. The app forwards the token to its backend, which validates the signature with Google’s public key, decrypts the payload, and enforces policy based on the verdict fields:

- **`appIntegrity`**: APK build/signature match (no repack/tamper).
- **`deviceIntegrity`**: genuine & certified device, locked bootloader, no root/system tamper.
- **`accountDetails`**: installation via Google Play.

Key verdict flags commonly enforced:
- `MEETS_BASIC_INTEGRITY`: token generated by genuine Play Services (not emulator/tampered transport).
- `MEETS_DEVICE_INTEGRITY`: genuine/certified device, bootloader locked, no root/system tamper.
- `MEETS_STRONG_INTEGRITY`: requires `DEVICE` plus **recent security patches on all partitions (OS + vendor)**.

## Bypass Model

Instead of forging Google’s JWT, **spoof the signals Google evaluates** so they correspond to a different, legitimate device profile. The attack chain:
1) Hide root so local checks and Play Services probes don’t see Magisk/su.
2) Replace the **key attestation certificate chain** (`keybox.xml`) with one from a genuine device so Play Integrity sees a certified/locked device.
3) Spoof the **security patch level** to satisfy `MEETS_STRONG_INTEGRITY`.

Google mitigates by **revoking abused keyboxes**; rotation is required when a keybox is blocked.

## Prerequisites & Tooling

- **Root hiding:** [ReZygisk](https://github.com/PerformanC/ReZygisk) (or ZygiskNext). Disable Zygisk, enable Magisk Hide, install module, reboot.
- **Key attestation spoofing:** [TrickyStore](https://github.com/5ec1cff/TrickyStore) + [Tricky Addon](https://github.com/KOWX712/Tricky-Addon-Update-Target-List) (Magisk modules).
- **UI helper:** [KSU Web UI](https://github.com/adivenxnataly/KsuWebUI) to drive TrickyStore.
- **Validation:** [Play Integrity API Checker](https://play.google.com/store/apps/details?id=gr.nikolasspyr.integritycheck) and [Key Attestation](https://github.com/vvb2060/KeyAttestation) APKs.
- Optional background on attestation key material: <https://tryigit.dev/android-keybox-attestation-analysis>

## Achieve `MEETS_BASIC_INTEGRITY` + `MEETS_DEVICE_INTEGRITY`

1. **Install modules & reboot:** Flash *TrickyStore* and *Tricky Addon* in Magisk, reboot.
2. **Configure TrickyStore (via KSU Web UI):** Select `TrickyStore` → `Select All` → `Deselect Unnecessary` → **Save**.
3. **Inject a valid keybox:** In `Keybox`, choose **Valid** to download/apply a new `keybox.xml` (vendor attestation credentials). This file underpins hardware key attestation and is now spoofed from a certified/locked device.
4. **Verify:** Run *Play Integrity API Checker* → `MEETS_BASIC_INTEGRITY` and `MEETS_DEVICE_INTEGRITY` should pass. In *Key Attestation* the bootloader appears **locked** because the attestation chain is replaced.

## Achieve `MEETS_STRONG_INTEGRITY` (Patch-Level Spoof)

`STRONG` fails on outdated patch levels. TrickyStore can spoof a modern security patch date for all partitions:

1. In TrickyStore, pick **Set Security Patch** → **Get Security Patch Date** → **Save**.
2. Re-run *Play Integrity API Checker*; `MEETS_STRONG_INTEGRITY` should now pass.

## Operational Notes

- **Revocation risk:** Hitting the API repeatedly with the same `keybox.xml` can flag and block it. If blocked, replace with a fresh valid keybox.
- **Arms race:** Publicly shared keyboxes burn fast; keep private copies and track community module updates (XDA/Telegram/GitHub) for new working chains.
- **Scope:** This bypass only spoofs attestation inputs; backend signature verification by Google still succeeds because the JWT itself is genuine.

## References

- [Play Integrity API: How It Works & How to Bypass It](https://m4kr0.vercel.app/posts/play-integrity-api-how-it-works--how-to-bypass-it/)
- [ReZygisk](https://github.com/PerformanC/ReZygisk)
- [TrickyStore](https://github.com/5ec1cff/TrickyStore)
- [Tricky Addon](https://github.com/KOWX712/Tricky-Addon-Update-Target-List)
- [KSU Web UI](https://github.com/adivenxnataly/KsuWebUI)
- [Play Integrity API Checker](https://play.google.com/store/apps/details?id=gr.nikolasspyr.integritycheck)
- [Key Attestation](https://github.com/vvb2060/KeyAttestation)
- [Android keybox attestation analysis](https://tryigit.dev/android-keybox-attestation-analysis)

{{#include ../../banners/hacktricks-training.md}}