This post is a short demonstration of Doppler’s binary analysis capabilities. We show the basics of Doppler’s functionality and demonstrate its ease-of-use by analyzing (and reversing) a Flare-On challenge binary. The file challenges us to enter the correct password, and we leverage Doppler to do so.
Run DopplerSetup.exe to begin the installation process. When prompted, enter your installation password, then navigate through the installer until you see the Install button. Click Install, and when the installation is complete, make sure Launch Doppler is checked and select Finish. Alternatively, you can find Doppler in the Start menu.
Download the Flare-On 3 zip file, which contains challenge1.exe. The password for the zip file is flare.
When running challenge1.exe from the Command Prompt, we get a prompt asking us to enter the correct password:
In Doppler, Click File > Open File and navigate to wherever challenge1.exe is stored, then select challenge1.exe and click Open.
The analysis will begin immediately. After the analysis completes, you will be brought to the start function in Doppler’s Control-Flow Graph (CFG) View. This view provides a high-level overview of the program’s execution flow.
Our goal is to enter the correct password into challenge1.exe. Thus, our first task is to figure out where in the binary the user is prompted to enter the password. Finding this location will better enable us to understand how the password is being checked.
Go to the sidebar and expand the Strings section. Immediately, we can see the following strings: “Enter password:”, “Correct”, and “Wrong password”.
The one we are interested in at the moment is “Enter password:”, so right-click “Enter password:” and select Xrefs To… to identify all the locations where this string is used. Near the top of Doppler, a selection box should appear that contains exactly one address, 0x40144e. Click this value to be brought to the instruction that uses this string.
Thanks to Doppler’s Decompilation feature, we can get an approximation for what the original source code of a given function. To view the generated source code for a function, we can right-click inside any one of the basic blocks within the CFG and select Switch to Source View.
From the generated source, we observe that kernel32.writefile is printing “Enter password:” to the user, and the call to kernel32.readfile is reading the user’s input. Then there is a call to sub_401260, and finally a strcmp call. If strcmp returns 0, then we have entered the correct password. The first argument to strcmp is the string “x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q”, and the second argument is the result of sub_401260, which itself takes the user’s input string as a parameter.
The real substance lies within the call to sub_401260. Double-click on sub_401260 to get the generated source code for this function. Scrolling down a bit, we find some interesting bit-shifting code with a long alphabet-like string.
When one is faced with the unknown, a good first thought is to consult Google. The fifth search result when googling >> 18 & 0x3f revealed the algorithm implementation for Base64 encoding. Compare the above decompiled code with the following Ruby implementation of Base64:
The Ruby code snippet above shows that Base64 utilizes the character string:
“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”,
but the generated source code in Doppler reveals a slightly different character string:
“ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/”.
This suggests Base64 encoding with, but with a different alphabet.
From our hypothesis, it follows that the inputs to strcmp are Base64 encoded strings. Thus, we can try to decode “x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q” (one of the inputs to strcmp) using the custom alphabet. Googling Base64 Custom Alphabet yields a website that offers Base64 encoding/decoding with a custom alphabet string. By plugging in the custom alphabet and Base64 encoded data, we arrive at the correct password:
Doppler’s primary strength is its ease-of-use. Both novices and professionals stand to gain from the clear and efficient workflow that Doppler provides. By gaining a higher-level understanding of the challenge binary, our task was made much simpler. Features that other binary analysis tools provide as plugins or add-ons, Doppler provides out-of-the-box (e.g. Decompilation and Control-Flow Graphs).
Doppler was easily able to analyze the important parts of the binary, and we were able to complete the challenge from start to finish without the assistance of other binary analysis tools. Doppler helped us analyze the relevant functions within the binary, largely in part to the Source Code View. Looking at the binary-level functions in a higher-level reconstruction allowed us to quickly draw conclusions during our analysis, aiding our semantic understanding of the binary as a whole.