Mobile / Sea of Secrets CTF 2026
The Cursed APK
The challenge pushes you towards Frida and an emulator-hiding setup, but the root/emulator checks aren't a gate. They change a number that goes into the key, so on a "wrong" device you…
Mobile Security, Hard, 300 pts
FLAG{d34d_m3n_t3ll_n0_t4l35_fr1d4_unl0ck5_th3_cur53d_v4ult}
The challenge pushes you towards Frida and an emulator-hiding setup, but the root/emulator checks aren't a gate. They change a number that goes into the key, so on a "wrong" device you just get garbage out. You can skip the device entirely and compute the clean-device key offline.
Honeypot has a decoy flag (y0u_f0und_f00ls_g0ld_matey). The real logic is in VaultCore.
Oath. getSeaOath() builds the passphrase in three parts: bytes [30,31,27,30,5,23,31,20,5] XOR 90 give DEAD_MEN_, a literal TELL_NO_, and ints minus 50 give TALES_1718. The oath is DEAD_MEN_TELL_NO_TALES_1718.
Tide token. calculateTideToken returns 322420958 on a clean device. It returns a different constant if Sentry.isRooted, and XORs with 48879 if Sentry.isEmulator. In hex the clean value is 1337c0de.
Key and IV.
- key =
SHA-256(oath + ":" + tokenHex), AES-256 - iv = first 16 bytes of
SHA-256("SALT_CARIBBEAN_TIDES_1718:" + tokenHex) - mode: CBC, PKCS5
I tried all four combinations of root/emulator and only the clean one (1337c0de) decrypts to something that starts with FLAG{. The other three give random bytes, which is the "curse" in the story.