Insomnihack Teaser 2022: Herald
Read more writeups at kitctf.de
Challenge description:
Our lab administrator has just passed out from a strange virus. Please help us find the password to his messaging app so we can identify what he was working on and save his life.
We are given an apk (Android Package) starting it, it asks for username and password to enter. It does not require any network connection, so it is a classical CrackMe.
apks are just zips, so we can get the contained files by just renaming it to Herald.zip
and unzipping. Looking at the source, it becomes clear, that this a React Native application. The real source is of a React Native application is located in assets/index.android.bundle
. This used to be just minified JavaScript in a webpack bundle. With the file
command however, we can see, that it is a modern app with Hermes bytecode. Judging by the challenge name, it is about that.
index.android.bundle: Hermes JavaScript bytecode, version 84
There is hbctool that can disassemble Hermes bytecode. The code for version 76 works well for our purposes.
hbctool disasm index.android.bundle labasm
This gives us a 275284 line file of disassembly. Searching through it, we find the Function<tryAuth>4087(3 params, 13 registers, 0 symbols)
function. It seems to call all the relevant functions and do the checks. We invert the marked (EOL Comments are patches) checks in order to get access.
Function<tryAuth>4087(3 params, 13 registers, 0 symbols):
LoadThisNS Reg8:2
GetByIdShort Reg8:0, Reg8:2, UInt8:1, UInt8:121
; Oper[3]: String(121) 'state'
GetById Reg8:0, Reg8:0, UInt8:2, UInt16:4142
; Oper[3]: String(4142) 'username'
LoadConstString Reg8:1, UInt16:801
; Oper[1]: String(801) 'admin'
JStrictNotEqual Addr8:38, Reg8:0, Reg8:1 ; > JStrictEqual Addr8:38, Reg8:0, Reg8:1
GetByIdShort Reg8:0, Reg8:2, UInt8:1, UInt8:121
; Oper[3]: String(121) 'state'
GetById Reg8:3, Reg8:0, UInt8:3, UInt16:4120
; Oper[3]: String(4120) 'password'
GetById Reg8:4, Reg8:2, UInt8:4, UInt16:3485
; Oper[3]: String(3485) 'decodedText'
NewArrayWithBuffer Reg8:0, UInt16:28, UInt16:28, UInt16:9398
Call2 Reg8:0, Reg8:4, Reg8:2, Reg8:0
JStrictEqual Addr8:105, Reg8:3, Reg8:0 ; > JStrictNotEqual Addr8:105, Reg8:3, Reg8:0
GetByIdShort Reg8:0, Reg8:2, UInt8:1, UInt8:121
; Oper[3]: String(121) 'state'
GetById Reg8:0, Reg8:0, UInt8:2, UInt16:4142
; Oper[3]: String(4142) 'username'
JStrictEqual Addr8:45, Reg8:0, Reg8:1 ; > JStrictNotEqual Addr8:45, Reg8:0, Reg8:1
GetEnvironment Reg8:0, UInt8:1
LoadFromEnvironment Reg8:0, Reg8:0, UInt8:6
GetById Reg8:3, Reg8:0, UInt8:5, UInt16:4460
; Oper[3]: String(4460) 'Alert'
GetById Reg8:0, Reg8:3, UInt8:6, UInt16:5067
; Oper[3]: String(5067) 'alert'
LoadConstString Reg8:1, UInt16:1772
; Oper[1]: String(1772) 'Wrong Username/Password combination'
Call2 Reg8:0, Reg8:0, Reg8:3, Reg8:1
GetById Reg8:0, Reg8:2, UInt8:7, UInt16:3904
; Oper[3]: String(3904) 'setPrint'
Call2 Reg8:0, Reg8:0, Reg8:2, Reg8:1
Jmp Addr8:66
GetEnvironment Reg8:0, UInt8:1
LoadFromEnvironment Reg8:0, Reg8:0, UInt8:6
GetById Reg8:3, Reg8:0, UInt8:5, UInt16:4460
; Oper[3]: String(4460) 'Alert'
GetById Reg8:1, Reg8:3, UInt8:6, UInt16:5067
; Oper[3]: String(5067) 'alert'
LoadConstString Reg8:0, UInt16:800
; Oper[1]: String(800) 'You are not the admin, Liar!'
Call2 Reg8:0, Reg8:1, Reg8:3, Reg8:0
GetById Reg8:1, Reg8:2, UInt8:7, UInt16:3904
; Oper[3]: String(3904) 'setPrint'
LoadConstString Reg8:0, UInt16:1312
; Oper[1]: String(1312) 'Attack attempt detected'
Call2 Reg8:0, Reg8:1, Reg8:2, Reg8:0
Jmp Addr8:21
GetById Reg8:1, Reg8:2, UInt8:8, UInt16:3839
; Oper[3]: String(3839) 'decodedFlag'
NewArrayWithBuffer Reg8:0, UInt16:43, UInt16:43, UInt16:9512
Call2 Reg8:0, Reg8:1, Reg8:2, Reg8:0
GetEnvironment Reg8:0, UInt8:1
LoadFromEnvironment Reg8:0, Reg8:0, UInt8:6
GetById Reg8:1, Reg8:0, UInt8:9, UInt16:3819
; Oper[3]: String(3819) 'Keyboard'
GetById Reg8:0, Reg8:1, UInt8:10, UInt16:3822
; Oper[3]: String(3822) 'dismiss'
Call1 Reg8:0, Reg8:0, Reg8:1
LoadConstUndefined Reg8:0
Ret Reg8:0
EndFunction
We can reassemble it, repackage the apk and sign it.
hbctool asm labasm ./Herald/assets/index.android.bundle
apktool b Herald/
java -jar signapk.jar certificate.pem key.pk8 ./Herald/dist/Herald.apk signed.apk
Running the app and logging in with KITCTF
, KITCTF
gives us the flag.
INS{Y0u_Kn0W_aB0uT_Th3_Her4ld_0F_the_G0ds?}