WEBVTT

1
00:00:00.600 --> 00:00:07.375
Welcome. This tutorial covers how the library detects a repackaged or tampered copy of your own app.

2
00:00:07.825 --> 00:00:12.425
There are four tamper signals: two on Android, and two on iOS.

3
00:00:12.875 --> 00:00:18.050
They are all opt-in, because only you know what a genuine build of your app looks like.

4
00:00:19.667 --> 00:00:29.467
To tamper with your app, an attacker first obtains it: by decoding the Android package, or by dumping a decrypted iOS binary from memory.

5
00:00:29.917 --> 00:00:35.217
Then they patch it: remove your security checks, add ads, or bolt on malware.

6
00:00:35.667 --> 00:00:42.417
Rebuilding strips the original signature, so they must re-sign with their own key. That is the weak point.

7
00:00:42.867 --> 00:00:49.117
Finally they distribute the clone through sideloading, enterprise certificates, or look-alike stores.

8
00:00:50.733 --> 00:00:56.733
On Android, the signature check compares the app's signing certificate with the ones you expect.

9
00:00:57.183 --> 00:01:07.458
It reads the certificates from the package manager, honouring key rotation on newer Android versions, and hashes each one with SHA-256.

10
00:01:07.908 --> 00:01:16.308
If none of the digests is in your expected list, the app was re-signed, because repackaging always strips the original signature.

11
00:01:16.758 --> 00:01:24.433
Get the digest with keytool, or from the Play Console app signing page. For Play builds, use the Play App Signing key.

12
00:01:26.033 --> 00:01:32.883
The installer check asks who installed the app. A trusted store, like Google Play, is the normal source.

13
00:01:33.333 --> 00:01:45.108
You list the allowed installers, for example com.android.vending. A null or unknown installer, such as adb or a browser download, counts as untrusted.

14
00:01:45.558 --> 00:01:51.533
Enable it in release builds only, because every debug install through adb will fail it.

15
00:01:51.983 --> 00:01:59.233
The installer name can be spoofed by a session that claims to be the Play Store, so this is a medium-strength signal.

16
00:02:00.833 --> 00:02:07.408
On iOS, the Team ID check reads your app's signing team, and it does so through the keychain.

17
00:02:07.858 --> 00:02:15.808
It adds a throwaway keychain item, reads back its access group, whose prefix is the Team ID, and deletes the item.

18
00:02:16.258 --> 00:02:25.783
A re-signed build carries the attacker's team ID, not yours, so pinning the expected team catches sideloaded and enterprise-signed clones.

19
00:02:26.233 --> 00:02:32.158
Debug builds signed with a personal team will mismatch, so enable it for release builds.

20
00:02:33.767 --> 00:02:40.342
The decrypted binary check asks whether the main executable is still encrypted by Apple's FairPlay.

21
00:02:40.792 --> 00:02:50.542
It walks the Mach-O load commands and reads the encryption info. A cryptid of zero, or no such command, means the binary is plaintext.

22
00:02:50.992 --> 00:02:59.742
Reverse engineers get a plaintext binary by dumping it from memory after FairPlay decrypts it, then re-sign and redistribute it.

23
00:03:00.192 --> 00:03:07.467
Only enable it for App Store and TestFlight builds, never debug or ad-hoc builds, which are not encrypted.

24
00:03:09.067 --> 00:03:18.242
On Android, pass expected signing certificates: the SHA-256 digests, in hex, with or without colons.

25
00:03:18.692 --> 00:03:23.692
Pass allowed installers, such as the Play Store, and only in release builds.

26
00:03:24.142 --> 00:03:30.667
On iOS, pass your expected Team IDs, taken from your Apple Developer account.

27
00:03:31.117 --> 00:03:42.342
And set require encrypted binary to true, for App Store and TestFlight builds only. None of these run unless you pass them, and they never make a complete report incomplete.

28
00:03:43.967 --> 00:03:52.917
The signature check trusts the OS's answer. On a rooted phone, an attacker can hook the package manager and return your real certificate.

29
00:03:53.367 --> 00:03:59.342
The installer check can be spoofed by an install session that claims to come from the Play Store.

30
00:03:59.792 --> 00:04:06.817
The team ID check can be fooled on a jailbroken device by hooking the keychain query or the comparison.

31
00:04:07.267 --> 00:04:14.292
And the decrypted binary check can be beaten by patching the cryptid byte back to a non-zero value.

32
00:04:15.900 --> 00:04:22.450
Let us recap. One: repackaging always means re-signing, and that is the weak point we pin.

33
00:04:22.900 --> 00:04:27.350
Two: on Android, check the signing certificate and the installer.

34
00:04:27.800 --> 00:04:33.550
Three: on iOS, check the Team ID and whether the binary is still encrypted.

35
00:04:34.000 --> 00:04:41.625
Four: on a rooted or jailbroken device these answers can be faked, so back them with server-side attestation.

36
00:04:43.233 --> 00:04:49.408
Thanks for watching. The opt-in options are documented in the README, under tamper checks.

37
00:04:49.858 --> 00:04:53.258
Next, watch the debugger and emulator video.
