This is a look into the short-lived piece of malware called Gazorp, and how its creators placed a backdoor within its command & control panel. I'll be looking at the code and how the backdoor was created and hidden.
I would like to begin by saying that I apologize for the lack of content recently. The planned post did not end up working out due to some unforeseen issues, but I believe that this post is a worthy replacement. A lot of credit for this story goes to hexlax (twitter). He let me know of this backdoor and shared his research into it, although the research presented in this post is my own and was carried out in light of his discoveries.
Gazorp was a piece of malware distributed around late 2018. This malware was shared through a free to use builder that was hosted on an onion site. On this site, anybody could build a ready to go copy of Gazorp and use the included C&C (C2) panel to receive the logs of their freshly built malware. When built, the site would prompt you to download a zip file which included your built malware. The panel, along with instructions on how to set up the panel were also included. The panel login looked like this.
As word of a new free to use malware spread across forums, threat researchers were quick to discover that Gazorp was just AZORult v3.0 with a reskinned panel. For their part, the creators of Gazorp claimed that they had redesigned the AZORult panel and fixed multiple vulnerabilities/flaws. Because Gazorp ended up just being AZORult, it was made clear the creators had cracked an original build of the malware and were changing strings within the build to point it to a new C2. You may now be asking, why would anyone put in the effort of re-coding a C2 and then distributing it for free? Well, it was obviously too good to be true.
Because hexlax had discovered the backdoor when the malware was still being used, he managed to snag seven separate builds of Gazorp. These were incredibly helpful in my research, as they allowed me to make comparisons of what was changing between builds. At first, I used a free service called Intezer to check if the builds were in fact AZORult.
There was no surprise that the malware had a 92% match with AZORult. Because I had seven builds, I began comparing them in HxD and found that there was nothing different besides their targeted C2s. Due to this, I decided to move on and look at the panel which is the more interesting of the two items. Using another file comparison tool I found out that a constant within the PHP code was changing.
These changes were very weird, as they were in a class that was used to get the location of a given IP. Usually these libraries are just included and do not differ from their original source, but in this case the constant was changing every build. Another thing that was changing was the gate name. This gate name was randomly generated, and is where the malware is pointed to when you put in your domain into the web builder. I wanted to verify that the builds were hitting this PHP file so I spun up my instance of Cuckoo sandbox and ran one of the samples.
The build sends a POST to the gate, along with some encrypted data that is unimportant, and is related to how AZORult functions. So now that I know my entry point, let's see how I can find my way into the 'IP2Location' file that contains the changing constant. The gate looks like so:
We can see that the gate receives the POST data and then decodes it with an XOR key, we will discuss this key later. The results of that decryption are then compared with the string reportdata, and if reportdata is within the decrypted input, then the decrypted data is sent into the parse_bot_report function. This function is unimportant for our intentions, and contains two lines which will bring us closer to the backdoor.
The function tries to get the ip of the bot, and try to deduce the country from this. Let's take a quick peek into the "get_bot_ip" function:
Within this function we see the first of the checks implemented to stop others from by mistake triggering the backdoor. The constant BOT_IP_HEADER is actually just set to another string.
The string HTTP_CLIENT_IP is a header that can be set within a web request to denote the client's IP. So why does the code go to this extent to hide the possibility of a bot setting its own IP? Well, AZORult never uses this functionality, and because of this we can guess it's not intended to be used by the built malware. The next function called from parse_bot_report is the get_isocode function where the IP in the header is used as a parameter. Let's take a look at it:
So this is the function that calls us into the PHP file containing the backdoor. It includes the IP2Location file and then creates a new instance of the database included with the library. Once that's done, the function calls us into the lookup function that has a parameter of which if you remember, is possible to be set through including the HTTP_CLIENT_IP header within our request. The lookup function is where the magic happens, so let's take a look at it and follow where our parameter of is used.
Our variable of IP is compared to a constant called IP_ROOT. This constant is set to "0.0.0.0" within the config. So this comparison is checking if the IP of the bot is equal to "0.0.0.0", but this IP would never be set by the malware. So this must be a check for a manual request, which was setting its own IP through the get_bot_ip function. So where does the fields_h bool get used?
Well, the variable is used to place us into this comparison. This time, another request header is checked against another constant, but this constant is different. If you remember from my initial discovery of the backdoor, it was through a changing constant in each of the panels. Well IP_HASH is that changing constant, in the case of this build, it is set to a random string.
In the case of the panel, it was set to a seemingly random string, which was different in each of the seven different panels I had. It is important to note once again, these checks are comparing request headers that are never used by AZORult, so they must be intended to be checking a request that wasn't made by the malware. Again, a constant is set to true. In this case, it is named code_h. Like we did with fields_h, following this variable we find the backdoor.
The first line within the backdoor is setting a variable to a constant that is defined in the IP2Location file. The EXCEPTION_FUNCTION constant is set to create_function. If you look at create_function then you find it is a method of creating a function by setting arguments as the first parameter, and then code within the second parameter. In this case the code is parsed through the cookie countrycode. An @ symbol is then used on the created function to suppress all errors. Once the function has been created, and the variable country_hair has been set to it, then the created function is called.
Now that we covered how everything works let's recap, here are the steps needed to get to the backdoor.
XOR encrypt reportdata and POST it to the gate
Set the Client-IP header in the POST request to '0.0.0.0' to get past the first check
Set the HASH header to the string in the IP_HASH constant 'a01f2b04a7' to get past the second check
Set the countrycode cookie to a PHP payload of your choice
Because I wanted to accomplish this exploit with ease I created a Python script to trigger the backdoor.
An important thing to note is that because Gazorp was using a cracked version of AZORult, and was only changing the gate URL, It was not changing the encryption used for its POST request. Hence, this script will work with all Gazorp panels. The PHP payload must be URL encoded as well, in order for it to work.
Gazorp was a short-lived piece of malware created for the sole purpose of backdooring its users. The Gazorps onion site has been down for ages now, and AZORult has become a useless piece of malware due to the ways browsers encrypt their store data. I have not been able to find any live instances of this malware, and hence have decided that it is a good time to show this backdoor. I'd like to again say thank you to hexlax & a huge thanks to Steved3 (twitter) for editing! Lastly and most importantly thank you for reading this post. Until the next time, goodbye.