We found really funny device. It was broken from the beginning, trust us! Can you help with recovering the truth?
Solution
Given flashdump.bin, parse the executable using this parser. There will be issue if we use the newer version of esptool library, use this patch to solve the issue. First, take a look on available partition on the flashdump.bin
As we can see on line 12 there is code like an string builder that result <h2>Flag: ??? </h2>. So we can assume that auStack_6c is the variable that store the flag. auStack_6c copied from auStack_49 that constructed from FUN_400d293c. Take a look on FUN_400d293c.
FUN_400d293c do xor for two static values which are DAT_3ffbdb68 and DAT_3ffbdb8d. To get the flag we just need to do xor for those static values.
a = [0xEE,0xCE,0x48,0x21,0x63,0xA8,0x1C,0xB8,0xA8,0x61,0x61,0x0D,0x8B,0x36,0xF0,0x07,0x25,0x85,0x5C,0xB0,0x6A,0x4B,0xC6,0xEF,0xBB,0x74,0x80,0x06,0x67,0x44,0xED,0x2A,0xD3,0x26,0xF7, 0xC6]
b = [0x84,0xBB,0x3B,0x55,0x20,0xFC,0x5A,0xC3,0xD1,0x0E,0x14,0x52,0xF3,0x06,0x82,0x58,0x48,0xE0,0x03,0xC2,0x5B,0x2C,0xAE,0x9B,0xE4,0x06,0xB0,0x73,0x09,0x20,0xB2,0x48,0xE7,0x44,0x8E,0xBB]
flag =b""for i inrange(len(a)): flag +=bytes([a[i] ^ b[i]])print(flag)
Flag: justCTF{you_x0r_me_r1ght_r0und_b4by}
Budget SoC (363 pts)
Description
We've obtained a mysterious device. Our forensic team tried to retrieve the original source code, but something went wrong. Fortunately, we managed to dump the memory into a file. Can you find what we need?
Solution
Given flashdump.bin, parse the executable using this parser. There will be issue if we use the newer version of esptool library, use this patch to solve the issue. First, take a look on available partition on the flashdump.bin.
So the ciphertext are processed on function FUN_400d296c, next take a look on function FUN_400d296c. There are some constant in the function so it nice to search it on github.
From above code we can see that the constant is actually from aes decrypt process. Looking at another function looks like it is same like in the app0.elf function. So the last step is basically finding the key and the ciphertext used by the function in app0.elf.
From the caller function we get the key, which is on the fifth argument (DAT_3ffbdb68). The ciphertext is on second argument and it allocated from function allocation_ that we assume the data is from _DAT_3ffc3e38.
Looking at ELF file, we know that _DAT_3ffc3e38 is not stored on it.
So we assume that the data is maybe on runtime memory. Because we have the flashdump.bin we try to directly find the ciphertext by bruteforcing all 32 bytes value in the flashdump.bin. Below is our script to do bruteforce.
from Crypto.Cipher import AESf =open("flashdump.bin", "rb").read()key = [0x33,0xBD,0xFB,0x72,0x4C,0x22,0x87,0x33,0x62,0xFF,0x75,0x41,0xD5,0x14,0xF6,0xFD]bytes_key =bytes(key)for i inrange(0, len(f) -32): cipher = AES.new(bytes_key, AES.MODE_ECB) tmp = f[i:i+32] res = cipher.decrypt(tmp)ifb"just"in res:print(i, res)
Looks like we got partial flag, so the mode should be not ECB. The next step we do is trying to use AES CBC with iv null bytes, because the first block is already correct plaintext.