Reverse Engineering / Sea of Secrets CTF 2026
Ghost Ship Unloaded
The files are Remittance_Manifest.jar, captains_log.enc, and ship_manifest.json. The jar contains three encrypted blobs under assets/ and no QaZagne class, which is loaded at runtime.…
Reverse Engineering, Hard, 300 pts
flag{gh0st_sh1p_j4v4_d3c0d3d_q4z4gn3_unm4sk3d_9f4c8a} (lowercase flag{, as printed by the vault)
The files are Remittance_Manifest.jar, captains_log.enc, and ship_manifest.json. The jar contains three encrypted blobs under assets/ and no QaZagne class, which is loaded at runtime. Every key can be recovered statically.
Master key. Header.RAW_CHART is an int array. Each element is XORed with 90 and then with (i*17+3)&255, giving:
KEY:BlackMeridian171|IV:SargassoSea2026!|SEED:9942Both are 16 bytes, so AES-128-CBC.
Resources. assets/manifest.idx decrypts with that key/IV and names the log salt C4PT41N_V4N3_SALT_1718, derivation SHA256(MasterKey + Salt)[:16]. assets/payload_alpha.bin decrypts to a class file (CAFEBABE), which is QaZagne. Its unlockTreasureVault(vault, token, seal) uses:
- key =
SHA256(token + ":" + seal)[:16] - iv =
SHA256(seal + ":" + token)[:16]
Token. captains_log.enc is AES-128-CBC with SHA256("BlackMeridian171" + salt)[:16] as the key. The first 16 bytes of the file are the IV (this one is prefixed, unlike the jar assets). The log contains NAV-TOKEN-CAPTAIN-VANE-7701.
Seal. manifest_seal in ship_manifest.json: MERIDIAN-SEAL-1718-X99. The verification_hash next to it is not used.
Feeding the token and seal into unlockTreasureVault's derivation decrypts assets/vault.dat to the treasure manifest and the flag. Using the verification hash as the seal instead gives garbage.