Some Assembly Required 4
Last updated
Was this helpful?
Last updated
Was this helpful?
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: AGFzbQEAAAABEwRgAABgAn9/AX9gAAF/YAJ/fwADBQQAAQIDBAUBcAEBAQUDAQACBjEIfwFBsIoEC38AQbAIC38AQYAIC38AQbAKC38AQYAIC38AQbCKBAt/AEEAC38AQQELB6EBDAZtZW1vcnkCABFfX3dhc21fY2FsbF9jdG9ycwAABnN0cmNtcAABCmNoZWNrX2ZsYWcAAgVpbnB1dAMBCWNvcHlfY2hhcgADDF9fZHNvX2hhbmRsZQMCCl9fZGF0YV9lbmQDAw1fX2dsb2JhbF9iYXNlAwQLX19oZWFwX2Jhc2UDBQ1fX21lbW9yeV9iYXNlAwYMX190YWJsZV9iYXNlAwcKoA4EAgAL5wIBKn8jgICAgAAhAkEgIQMgAiADayEEIAQgADYCGCAEIAE2AhQgBCgCGCEFIAQgBTYCECAEKAIUIQYgBCAGNgIMAkADQCAEKAIQIQdBASEIIAcgCGohCSAEIAk2AhAgBy0AACEKIAQgCjoACyAEKAIMIQtBASEMIAsgDGohDSAEIA02AgwgCy0AACEOIAQgDjoACiAELQALIQ9B/wEhECAPIBBxIRECQCARDQAgBC0ACyESQf8BIRMgEiATcSEUIAQtAAohFUH/ASEWIBUgFnEhFyAUIBdrIRggBCAYNgIcDAILIAQtAAshGUH/ASEaIBkgGnEhGyAELQAKIRxB/wEhHSAcIB1xIR4gGyEfIB4hICAfICBGISFBASEiICEgInEhIyAjDQALIAQtAAshJEH/ASElICQgJXEhJiAELQAKISdB/wEhKCAnIChxISkgJiApayEqIAQgKjYCHAsgBCgCHCErICsPC/EKAaUBfyOAgICAACEAQRAhASAAIAFrIQIgAiSAgICAAEEAIQMgAiADNgIMAkADQCACKAIMIQQgBC0AsIiAgAAhBUEYIQYgBSAGdCEHIAcgBnUhCCAIRQ0BQQAhCSACKAIMIQogCi0AsIiAgAAhC0EYIQwgCyAMdCENIA0gDHUhDkEUIQ8gDiAPcyEQIAogEDoAsIiAgAAgAigCDCERIBEhEiAJIRMgEiATSiEUQQEhFSAUIBVxIRYCQCAWRQ0AIAIoAgwhF0EBIRggFyAYayEZIBktALCIgIAAIRpBGCEbIBogG3QhHCAcIBt1IR0gAigCDCEeIB4tALCIgIAAIR9BGCEgIB8gIHQhISAhICB1ISIgIiAdcyEjIB4gIzoAsIiAgAALQQIhJCACKAIMISUgJSEmICQhJyAmICdKIShBASEpICggKXEhKgJAICpFDQAgAigCDCErQQMhLCArICxrIS0gLS0AsIiAgAAhLkEYIS8gLiAvdCEwIDAgL3UhMSACKAIMITIgMi0AsIiAgAAhM0EYITQgMyA0dCE1IDUgNHUhNiA2IDFzITcgMiA3OgCwiICAAAsgAigCDCE4QQohOSA4IDlvITogAigCDCE7IDstALCIgIAAITxBGCE9IDwgPXQhPiA+ID11IT8gPyA6cyFAIDsgQDoAsIiAgAAgAigCDCFBQQIhQiBBIEJvIUMCQAJAIEMNACACKAIMIUQgRC0AsIiAgAAhRUEYIUYgRSBGdCFHIEcgRnUhSEEJIUkgSCBJcyFKIEQgSjoAsIiAgAAMAQsgAigCDCFLIEstALCIgIAAIUxBGCFNIEwgTXQhTiBOIE11IU9BCCFQIE8gUHMhUSBLIFE6ALCIgIAACyACKAIMIVJBAyFTIFIgU28hVAJAAkAgVA0AIAIoAgwhVSBVLQCwiICAACFWQRghVyBWIFd0IVggWCBXdSFZQQchWiBZIFpzIVsgVSBbOgCwiICAAAwBC0EBIVwgAigCDCFdQQMhXiBdIF5vIV8gXyFgIFwhYSBgIGFGIWJBASFjIGIgY3EhZAJAAkAgZEUNACACKAIMIWUgZS0AsIiAgAAhZkEYIWcgZiBndCFoIGggZ3UhaUEGIWogaSBqcyFrIGUgazoAsIiAgAAMAQsgAigCDCFsIGwtALCIgIAAIW1BGCFuIG0gbnQhbyBvIG51IXBBBSFxIHAgcXMhciBsIHI6ALCIgIAACwsgAigCDCFzQQEhdCBzIHRqIXUgAiB1NgIMDAALC0EAIXYgAiB2NgIEAkADQCACKAIEIXcgAigCDCF4IHcheSB4IXogeSB6SCF7QQEhfCB7IHxxIX0gfUUNASACKAIEIX5BAiF/IH4gf28hgAECQCCAAQ0AIAIoAgQhgQFBASGCASCBASCCAWohgwEgAigCDCGEASCDASGFASCEASGGASCFASCGAUghhwFBASGIASCHASCIAXEhiQEgiQFFDQAgAigCBCGKASCKAS0AsIiAgAAhiwEgAiCLAToACyACKAIEIYwBQQEhjQEgjAEgjQFqIY4BII4BLQCwiICAACGPASACKAIEIZABIJABII8BOgCwiICAACACLQALIZEBIAIoAgQhkgFBASGTASCSASCTAWohlAEglAEgkQE6ALCIgIAACyACKAIEIZUBQQEhlgEglQEglgFqIZcBIAIglwE2AgQMAAsLQQAhmAFBsIiAgAAhmQFBgIiAgAAhmgEgmgEgmQEQgYCAgAAhmwEgmwEhnAEgmAEhnQEgnAEgnQFHIZ4BQX8hnwEgngEgnwFzIaABQQEhoQEgoAEgoQFxIaIBQRAhowEgAiCjAWohpAEgpAEkgICAgAAgogEPCz8BBX8jgICAgAAhAkEQIQMgAiADayEEIAQgADYCDCAEIAE2AgggBCgCDCEFIAQoAgghBiAGIAU6ALCIgIAADwsLMgEAQYAICysYanxhEThpNxYKcwBnT187AUdIfjBmG1V3BWhFDTkNS0otPzxJWngCVwAA
Let's decompile it by first converting it to wasm
using write_wasm.py
in ../Some Assembly Required 2
and then using wasm-decompile
. The decompiled c-like code is in .
We can decompile the to actual c code using wasm2c
. The decompiled actual c code is in .
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 the because it shows a clear array of hex bytes while the 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 since it is easier to understand. We will convert the wasm
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 has comments along the way that explain what each component of the code does.
is the most literal translation of the into Python. I use comments on most of the lines of code to show the corresponding line from the .
refactors mainly by repairing the if...else
logic.
is the final refactored form. Given an input, will output the same thing as and . combines all the functions into concise if...else
statements.
Finally, 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 will output picoCTF{b9da2135bc2b724208745a4d74d232d2*M
. We can repair the last two characters manually (*M
--> }
) to get the flag.
Here is some advice from a user in the 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."
picoCTF{b9da2135bc2b724208745a4d74d232d2}