Some Assembly Required 4
Problem
Solution
Note: This was a long and tedious challenge. Manually translating
wasm
to python was difficult. Total time: approximately 9 hours.The new WebAssembly base64 string is as follows:
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
Let's decompile it by first converting it to
wasm
usingwrite_wasm.py
in../Some Assembly Required 2
and then usingwasm-decompile
. The decompiled c-like code is in wasm-decompile-output.c.We can decompile the compiled wasm to actual c code using
wasm2c
. The decompiled actual c code is in wasm2c-output.c.The encrypted flag is:
0x18, 0x6a, 0x7c, 0x61, 0x11, 0x38, 0x69, 0x37, 0x16, 0x0a, 0x73, 0x00, 0x67, 0x4f, 0x5f, 0x3b, 0x01, 0x47, 0x48, 0x7e, 0x30, 0x66, 0x1b, 0x55, 0x77, 0x05, 0x68, 0x45, 0x0d, 0x39, 0x0d, 0x4b, 0x4a, 0x2d, 0x3f, 0x3c, 0x49, 0x5a, 0x78, 0x02, 0x57, 0x00, 0x00
. This value is from thewasm2c
output file because it shows a clear array of hex bytes while thewasm-decompile
output file shows a slight mess.We cannot use the method from the last challenge where we find the key from knowing the start of the flag. If we try it we get this output:
Instead, we have to actually reverse the decompiled output to decrypt the flag. I'll be using the
wasm-decompile
output file since it is easier to understand. We will convert thewasm
c-like code to python, refactor the converted code, and finally write a new script that reverses the program.Our process for converting and reversing the
wasm
will be as follows:Identify the purpose of each code block in the decompiled
wasm
code.Map out the program flow for that section.
Convert the current block into python.
Reverse the python script by rewriting it bottom-to-top.
The
wasm-decompile
output file has comments along the way that explain what each component of the code does.script-1.py is the most literal translation of the
wasm-decompile
output file into Python. I use comments on most of the lines of code to show the corresponding line from thewasm-decompile
output file.script-2.py refactors script-1.py mainly by repairing the
if...else
logic.script-3.py is the final refactored form. Given an input, script-3.py will output the same thing as script-2.py and script-1.py. script-3.py combines all the functions into concise
if...else
statements.Finally, script-4.py decodes the output of any of the previous scripts as well as the output of the
wasm
code. Thus, it can be used to reverse the flag. Running script-4.py will outputpicoCTF{b9da2135bc2b724208745a4d74d232d2*M
. We can repair the last two characters manually (*M
-->}
) to get the flag.Here is some advice from a user in the PicoCTF Discord about the
wasm
code: "The code will never reuse some obscure variable from hundreds of lines prior. Nor will it ever rely on subtle and mean tricks relating to data overflowing into memory addresses used for other things. Nor will it have two pieces of code that look identical at first glance, yet have a very subtle difference that makes their behaviours completely different."
Flag
picoCTF{b9da2135bc2b724208745a4d74d232d2}
Last updated