Some Assembly Required 4
Problem
Solution
Note: This was a long and tedious challenge. Manually translating
wasmto python was difficult. Total time: approximately 9 hours.The new WebAssembly base64 string is as follows:
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's decompile it by first converting it to
wasmusingwrite_wasm.pyin../Some Assembly Required 2and 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 thewasm2coutput file because it shows a clear array of hex bytes while thewasm-decompileoutput 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:
picoCTF{~ l.5#pwiDWpb 4...wK_U".". 2.6WN?..Instead, we have to actually reverse the decompiled output to decrypt the flag. I'll be using the
wasm-decompileoutput file since it is easier to understand. We will convert thewasmc-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
wasmwill be as follows:Identify the purpose of each code block in the decompiled
wasmcode.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-decompileoutput 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-decompileoutput file into Python. I use comments on most of the lines of code to show the corresponding line from thewasm-decompileoutput file.script-2.py refactors script-1.py mainly by repairing the
if...elselogic.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...elsestatements.Finally, script-4.py decodes the output of any of the previous scripts as well as the output of the
wasmcode. 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
wasmcode: "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
Was this helpful?