This is part 2 of the Flare-On 5 CTF writeup series.
4 - binstall
It is time to get serious. Reverse Engineering isn't about toys and games. Sometimes its about malicious software. I recommend you run this next challenge in a VM or someone else's computer you have gained access to, especially if they are a Firefox user.
Similar to the last challenge, binstall.exe is a .NET PE. However this time it has been obfuscated using ConfuserEx.
All original method names and removed and strings are encrypted. Running de4dot gives somewhat a clean assembly.
Strings are still encrypted. For example,
ExpandEnvironmentVariables takes a string as an argument which is decrypted at runtime. De4dot supports string decryption by specifying the method token of the decrypter. However, the author was not able to get it to work likely because the decryptor methods were generic which de4dot doesn't seem to support.
Decryption of strings is not a priority as we can always debug the binary and get the strings at runtime. However, let's do it anyway. ConfuserEx being quite a popular obfuscator there are many public (and private) deobfuscators sparing us from writing our own decrypter. A tool named "ConfuserEx Static String Decryptor" was able to decrypt all the strings and we get a clean assembly as shown below.
With the obfuscation out of the way, let us begin analysis.
Main first calls
smethod_7. Note that this is not the original name of the method. The obfuscator removed original method names during the obfuscation process. Consequently, since de4dot cannot guess the original name it generates a name based on the method signature.
smethod_2 opens the FireFox profiles.ini file and removes all occurrences of the string
Path=Profiles/ from it. Additionally, it also clears the FireFox cached files.
smethod_3 clears off the Chrome browser cache.
smethod_1 are helper methods to delete a directory and a file respectively.
smethod_4 clears the Internet Explorer cache.
Going back to
Main the next call is to
smethod_5 with path constructed from the
%APPDATA% environment variable and ending in
smethod_5 decodes a piece of base64 encoded data and decrypts it by xoring it with
0x33. The decrypted data is written to the file
This method adds
browserassist.dll to the
AppInit_DLLs registry key. The
AppInit_DLLs are a set of Dynamic Linked Libraries (DLL) that are loaded upon startup into the address space of every executable that links with
user32.dll. Essentially, this means everytime a GUI application is run,
browserassist.dll would also be loaded into it. This is a typical modus operandi of malware.
browserassist.dll is easy. We can either copy the base64 text and decrypt ourselves or run the malware in a virtual machine and copy the dropped DLL from the said location.
As its name suggest, browserassist.dll must be intended to be loaded in a Web Browser. However, being registered as an AppInit DLL it will be loaded in all GUI applications. Naturally, the DLL is likely to check whether it is running in the correct process before it begins its operations.
Analyzing the disassembled code there is indeed a call to
GetModuleFileNameA to retrieve the full path of the process in which the DLL is loaded.
The filename is then passed to a function which calculates a hash value from it. For success, the hash must match
The hashing algorithm is simple, the decompiled code of which is shown below.
We can reimplement the same algorithm in C.
For the string "firefox.exe" this yields the same hash as expected by it. This explains why the challenge description recommends running this on a system where Firefox is installed.
$ gcc hash.c -o hash $ ./hash firefox.exe firefox.exe -> 4932B10F
If the hash matches, it compares the File Version Info.
In particular, the major version must be less than 55. If all of the conditions match it proceeds to start a thread. The thread function constructs a string on stack byte by byte.
The string is then xored with
The xored string is passed to another function which looks to decrypt something.
At this point let us switch to dynamic analysis. We install an old version of Firefox like 34.0 from https://ftp.mozilla.org/pub/firefox/releases/34.0/win32/en-US/ in a Virtual Machine. Running binstall.exe drops browserassist.dll which is also added to the list of AppInit DLLs. We can now start Firefox under x32dbg, set it up to break on module load. In this way, x32dbg pauses whenever a new DLL is being loaded. Once browserassist is loaded, set a breakpoint on the
When the breakpoint is hit, stepping over the call we can get the decrypted data.
The decrypted data looks to be a URL
pastebin.com/raw/hvaru8NU. Navigating to the URL we find another base64 blob.
The data is encrypted and the same call to
CryptDecrypt decrypts it.
Analyzing the injected code
We can dump the code to a text file for further analysis. Formatting using a JSON beautifier we get the following.
which when displayed in a tree view looks like
Essentially the JSON code is a webinject config. Visiting any URL beginning with
http://flare-on.com/ is the homepage of the FLARE challenges. It is modelled like a Linux a shell and supports commands like
cd to navigate etc.
If we take a diff between the original js files (by opening the URL in a clean browser) and the modified one we can quickly zero in on the changes.
A new command
su is added in
controller.js, but executing the command requires a password. The password is checked by the function
cp in the same file.
The code is lightly obfuscated. After formatting and simplifying we get
The root password is
k9btBW7k2y. However, typing the password at the
su prompt does not give us the flag. Looking again at the diff we can find the
changeDir function is modified too.
cd command it is checking whether the directory name matches with something. Running the code separately we can find that the dir name is
Navigating to the directory and typing
ls gives us the flag.
Continue with the next part: Flare-on 5 CTF Write-up (Part 3)