We're provided with a zip-file "script.zip" (note the filename !!)
Inside it is an EXE file; also named "script.exe"
Once we extract it, we see the file's icon... looks familiar? yup!! it's an autoIt script, compiled into an EXE.. hence the file names containing the word "script"
To be 100% sure, we could scan it with any PE-tool. Interestingly, PEinfo could not identify it as an autoIt script, but EXEinfo PE detected autoIt signatures in the EXE file 😉 Not only that, it also suggests using a tool called EXE2aut - autoIt 3 decompiler to decompile the EXE -> autoIt script .au3
Before attempting to decompile it, lets take a snapshot of our VM, and run the EXE to see what it does.
Maybe that's the encrypted flag or something :hmm emoji:
I downloaded EXE2aut, dragged our EXE on it. It shows a warning because it's going to execute the EXE file in the process of decompiling it. I clicked OK, of course after taking a snapshot in the VM (so that we could revert back to it later). It successfully decompiles the EXE. Here is the full code to the script.
Lets copy all, and paste into notepad++.
That looks ugly, lets choose the language as autoIt (From Notepad++'s menubar; Language->A->AutoiT), or maybe save it as a file with an AU3 extension so that notepad++ will automatically detect the language as autoIt.
Syntax highlighting, that looks A LOT better.
As shown, the code looks complicated (probably contains a ton of garbage code, and libraries and dependencies). So, we need a starting point.
Most of the stuff we see here is function-declarations and variable-assignments. Where does the execution start? Where is the entry point?
At this point, I used a regex in notepad++ to search and replace all function declarations with nothing. To remove all the function declarations, and to find at least one function's execution. (of course take a backup copy of the file before clicking Replace-All )
We could do the same too for variables, but we probably wont need to.🤞
Now lets dig into this function line by line..
First line declares a global variable. But if we search for its name, we wont find any other occurences of it, so it's safe to say it's garbage code (to hinder our analysis). Lets comment-out or delete this line and go on. (comments in autoIt start by a semicolon ; )
Two more lines with the same concept.
Ok, now that we've got that out of our way, let's start reversing.
We should start from the end. We can see that a MessageBox function is called with 3 arguments, leading to that strange (encrypted flag) message that we saw earlier. Lets check this function's definition from the autoIt documentation
As you notice, the local variable "texjyuus_kxmczmsui_waowsej" is declared in the 1st line, then its value is used as-is in the last line. So what the hell happened in the 2nd line?
Here we have 2 possibilities:
- The local variable is passed by-reference. So its value will be changed without changing its name.
- The local variable is passed by-value (noramlly), and the result of that function (maybe the flag we want) is stored in "var_1044".
The answer is pretty obvious. We can clearly see that "texjyuus_kxmczmsui_waowsej" 's value assigned in the 1st line is the same one that was output by the message box function on the 3rd line (when we ran the script.exe).
Also for confirmation, lets check whether the function on the 2nd line takes the 2nd argument by-reference:
Ok. What to do next?
Maybe try to output "var_1044" instead of "texjyuus_kxmczmsui_waowsej" in the Msgbox function on the 3rd line?
Let's try it:
I commented out the original 3rd line, and copied it on the 4th line, then changed the last argument to "var_1044".
Save this file as "anything.au3", and install autoIt then run it.
Boom! let's try this flag on the CTF's website....
A deeper look
Now lets take a look at the function on the 2nd line to hone our reversing skills 🏴☠️
As we saw before, it takes 3 arguments as an input, and returns a string as an output (because "2k__c7vruxrccotz_7o_sziyu" is initialized to an empty string on line 816)
We also notice a couple of things:
First: it has initialized the autoIt's crypt libraries; using _crypt_startup() at the function's start, and _crypt_shutdown() before the function's end.
Second thing: The 1st arg is some sort of flag, to decide whether you want to encrypt or decrypt data.
If this flag is true, we'll encrypt data using a autoIt's built-in function _crypt_encryptdata()
If it is false, we'll do the opposite
And by looking at both encryption functions, we conclude that the 3rd arg ("var_1987") passed to this function ("asdasfcyzncmmkxdiasd") is the encryption key.
So in our case, we wanted to decrypt the encrypted flag, that's why we passed "Flase" as the 1st arg of this function ("asdasfcyzncmmkxdiasd"). Pretty easy.
Anyways, I just wanted to take some time to dive a bit deeper into autoIt. It could've been a bit more challenging if the author switched this flag to True on line 784, so that you would have to inspect this function and find out the function of this flag and toggle it off.