Babadook: Connection-less Powershell Persistent and Resilient “Backdoor”

At my previous company I used to prank the colleagues who left their stations unlocked. I call this my “internal awareness program”.

It was all fun and games at the beginning. I would leave post-its on their monitors with a friendly message “You could’ve been hacked” but it wasn’t giving the expected results. Some colleagues found it funny and started “collecting” my post-its. There was a guy in particular with 5 of them. It was evident harder measures had to be taken.

I’ve escalated the awareness program by replacing post-its to emailing the whole team with the message “I was reckless and left my computer unlocked”. Everybody would laugh about it but still wasn’t giving the needed outcome: People locking their desktops when away from the station.

Overcoming restrictions

I came to the conclusion that my colleagues would only learn the lesson if in fact they got hacked somehow, so I decided to make a backdoor so I’d be able to mess with their machines remotely.

Turns out that we were in a fairly constrained environment:

  • No direct connections between machines: VLAN isolation
  • User-only access, no admin privileges, cannot install anything
  • Corporate anti-virus in use, cannot use off-the-shelf solutions

So I started thinking what could I do with what I had in hands. As we were using Windows 7, one powerful tool came to my mind: POWERSHELL. Aw yiss!

I still needed to overcome some situations, no direct connections, inability to open sockets and so on.

As we were all members of the same team, we had access to the some shared folders and that was the vector that popped my mind. I would place a script on this shared folder and my backdoor would read this script and kinda eval() it. Simple and effective.

So by using the shared folder strategy and using powershell I’d solve the isolation problem AND the antivirus problem at once. I’ve added Clear-Content so the script would only run the code once.

I’ve skipped lunch for a day and rigged a quick and dirty POC. Tested on my machine, found a colleague that had left the machine unlocked and BAM, it was working.

After some days of fun, they started figuring out and killing my powershell process from the task manager. I needed to make the backdoor resilient.

Enter Babadook

The name came from an excellent scary movie (I trully recomend you to watch it!) I’d seen a while ago called The Babadook @ IMDB, which had the quote “If it’s in a word or in a look, you can’t get rid of the Babadook”.

That’s the motto I would follow to my backdoor. Make it unkillable as long as reasonably possible. Stealthiness wasn’t a big deal. Once I’d started playing the “Super Mario Theme Song” on their PC Speakers my presence would be spotted.

I kinda also wanted them to know and after some while after they came back to their stations and realized they had left it unlocked, they knew they had been pranked.

The Babadook

Multi-threading and the Watchdog routine

I quickly concluded that I’d needed to make my backdoor multi-threaded to have something watching my back while the main routine was waiting for commands. Powershell’s “Jobs” functionality would fit.

I’ve created a Watchdog function which were merely a while ($True) loop sending Stop-Process -processname taskmgr and ignoring errors (if the Task Manager wasn’t running).

I did the same for cmd.exe, wscript.exe and cscript.exe just to be safe.

This also effectively blocks running .bat and .vbs files since the interpreter has no chance to fully load before being killed by Babadook.

That worked for a while until IT released a GPO update blocking powershell remoting and thus blocking the use of powershell Jobs. *sadface*

So the quest for an alternative began and remembering how powershell and .NET integrate beautifully I was sure I could use some Somelongnamespace.Threading.Something .NET voodoo to accomplish that. Turned out the solution was way easier by using powershell’s Runspaces.

It worked as a charm! My watchdog was up again killing Task Manager immediatly as the window would (try) to appear. My colleagues were going crazy.

NOTE: Up to this moment I’ve been facing some issues with BeginInvoke which seems to fail to run ever once in a while, still debugging this issue. With Jobs I’ve never had this issue, instead I had issues where when the Job wasn’t properly stopped, it would run forever and required a reboot to die since the Watchdog wouldn’t let me open a powershell session.

There can be only one

In order to ensure that nobody would try to play smart and open a powershell window and try to use the Get-Process and Stop-Process to try to kill my backdoor, I’ve added the functionality to the watchdog to kill all powershell processes which were not his own. Upon start I’d save my process ID into a variable and use that to check the other powershell processes.

Also, no Powershell ISE here!

You can’t Run but I can hide!

At the same time my colleagues were desperately trying to kill Babadook, I was also doing the same to ensure I could cover the holes before they were able to get to it.

I’ve realized that someone could just invoke the taskill command directly from the “Run” dialog and that was bad (for me), so I needed a way to prevent that dialog from coming up. As this is a built-in dialog and not a process, I wasn’t able to take down on the classical way (with Stop-Process) so I’ve appealed to .NET extensions to grab some Windows API calls in order to enumerate the foreground window and if the title was what I wanted, kaboom!.

Hiding in plain sight

To add a sleight of fear, I’d thought it would be nice to hide my Babadook files since if my victim could find the command script on the shared folder, he could add some code there to kill Babadook and end my party, so a little code to get this sorted out was added to the Watchdog:

The last line adds an entry to the Registry turning on the option “Don’t display system and hidden files”. As this was on the While ($true) loop, even if the user turned that off, it would be turned back on immediately.

Take no shortcuts

With my anti-kill countermeasures in place, I was thinking on more ways to kill Babadook to improve the Watchdog, so it came to my mind that one could create a shortcut for taskill so I’ve made a little modification to my “Run Killer”:

That would take care of popping out the “Properties” dialog out of any file. Booya!

When everything else fails, reboot!

I’m sure there are some other ways to kill my process but that was enough for the moment (and I needed to get some lunch anyway). So people started realizing that a reboot was the only way to get rid of the Babadook.

I couldn’t leave this that way and needed a a persistence method. I first thought about the “Run” key on the registry but that might need admin privileges, so why not resort to our well known scheduled tasks?

Popped up a code to copy the Babadook script to the local machine with a random name and create the new task to run “At Logon”, “On Idle” and “Daily at 8AM”.

For more information on Task Scheduler options, check the MSDN Technet documentation.

That was working beautifully until I realized I needed some concurrency control. Of course my “There can be only one” code would kill the competitors but I needed something more elegant and Mutexes came to my mind. Added a code for that also:

And of course I needed to prevent them from opening the “Scheduled Tasks” dialog. Since a Stop-Process to the mmc process was giving me “Access Denied” (it runs in some kind of UAC), I needed to take the .NET approach. Modified my “IF” to consider that:

Recap

So far we got:

  • Connection-less command execution (full powershell language incl. .NET extensions + system()-like with Start-Process)
  • Watchdog / Userkit (userland “root”kit)
  • Persistence
  • Concurrency control

And that worked well enough for me :)

It’s not about the money

So if you read until here you might probably been wondering: “Did you really skipped those lunches just to mess up your colleagues?”

Well, kinda. It was a great learning and they surely got the message. No one now leaves their session unlocked. :)

When the news hit my team leader (how they called the Boss at the company) he saw this was a good way to show upper management and the other teams the dangers of an insider, how basic malware works and escalated the Babadook as a truly internal awareness program, so it turned out to be a great deal for everyone (except for a few really pissed off teammates).

Code

As always, you can get the Babadook source at my github.

Calling functions without their names in PHP

Strings. Ah juicy and precious strings! It is common for malware scanners and IDPS to look for suspicious strings in network traffic and files… but what if there are no strings to look for? (whaaa?)

Today I was wondering about some features found in many interpreted languages of listing its internal functions in some sort of list/array. This way we can enumerate the [index] => function_name relationship, replace all function_names on the code to their index and voilá!

You might ask: “But you can just put those indexes on the rulesets.” I answer: “Yes, that’s true”. But different server/PHP configurations might generate the different indexes. Besides, numbers are much more fun to obfuscate than strings.

PHP, because it’s widely used on the wild

I wasn’t remembering if PHP had this or not but I was pretty confident due to its nature. Turns out that get_defined_functions is there as expected. With the aid of call_user_func_array it enabled the calling of functions without writing down their names in any encoded form (but it is required that you enumerate them beforehand).

The Code

This snippet has fewer than 10 lines (and it’s optimized for readability) and is our indirect caller function.

Then you can call your functions like this:

The output

Just for illustration:

We can even make it a little more compact

But Jan, there are still tree other internal function names exposed in your code. (func_get_args, call_user_func_array and array_shift)

Heck, you’re right. Let’s make this better.

or even…

MOAR compact!

A simple silly backdoor

How the numbers could be obfuscated to bypass simple rules?

Well, with the very simple math stuff:

  • XOR/AND/OR all entries: $index^$key, $index&$key, $index|$key
  • SUM/SUB/DIV/MUL all entries: $index+$key,$index-$key, $index/$key, $index*$key

And so on.

So, what to do to prevent/catch those things?

Keep an eye for get_defined_functions.

Cya!

Shared-hosting accounts victims of lame directory permissions

From a few months some clients started to complain about their shared-hosting accounts being amazingly owned even if their PHP applications (WordPress mostly) were totally up to date.

The malware got into most of the PHP files including a PHP snippet that would eval and decode a base64-encoded string containing a script declaration loading Javascript from outside. This Javascript usually initiates download of .exe’s and stuff.

A friend’s account got hacked a few days back by this very same technique. He told me the attacker had left some files over so I asked him to hand me over so I could play a little and reverse-it.

Reversing

The code ended up being two times rendering 3 total ‘stages’.

Stage 1

Starts with two vars with random names containing hex-encoded strings that ended up being ‘create_function’ and ‘base64_decode’, two regular PHP functions.

Followed by that we have these vars called as functions

And it ends calling this assigned variable as a function…

The base64-encoded code is presented next at

Stage 2

What was base64-encoded is now a function that decodes content from another variable creating a payload string. The very first two variables are the most interesting because they are the “key” used to encode the payload, and the encoded payload.

All the characters of the payload string are presented as numbers that when put to the power of “key” will become the corresponding ascii character of the payload.

A very simple for loop makes the math and appends the string.

Stage 3

Well, what can I say, the decoded and evaluated string is a very simple PHP shell. It can run unix commands from a variety of techniques (popen, exec, system, passthru — the first available), can upload files, run php commands or connect to database hosts and run sql queries from the victim account.

Artifacts missing

The script actually used for the infection of the PHP file is missing. Unfortunately as it is a shared-hosting I can’t reverse the disk for deleted items but it’s not something very simple. What I deduce is a simple find looking for PHP files and then piping them to a custom-built parser that would add the evil line at the end or after some specific code.

I’ve seen variants that only infected WordPress’ footer.php template file (as it is included in every other page). This revealed to be a true application-targeted attack.

If there are no holes in the app, how the hell did he got here?

After some manual auditing on the client’s application I’ve stated that the compromise couldn’t be started by the application so I started probing the environment.

Nothing seemed really bad at first but then, when talking to a friend I’ve noticed the most primary mistake: Directory permissions. So I present you…

The attack vector

Some WordPress plugin developers make their plugins chmod upload directories world writable (chmod 777) to avoid problems. This is quite stupid but you might not know that most security-unaware developers do this quite often while having permissions issues.

We ran a quick find to see which directories where with write bit set on ‘other’.

Then, as expected, we got some entries…

Just having an account on the same machine is enough. The attacker simply copied the files over our writable directory and accessed via his browser.

As a hosting account with SSH access enabled is around 10 bucks/month, this is a really victim-untargeted, cost-effective attack.

Enumerating Victims

After we discovered the vector I jumped to my account and tried to ls /home but I was, as expected, denied.

So I though for a while and realized that /etc/passwd is readable. A little for function with some cut and the find above I was able to scratch down nearly 15.000 (YES, FIFTEEN THOUSAND!!!) world writable folders on this client shared-hosting machine.

Just stopped there because I’m on the light side ;)

Some nasty artifacts

The infection also affects .htaccess files. Even if you haven’t one, if you got owned this way, you probably have one now for each site you’ve hosted.

Google started to mark some sites as attack sites. The pointed out offending url is http://sweepstakesandcontestsinfo.com/nl-in.php?nnn=555. So I started grepping like there’s no tomorow. In instants my less become populated by some good eggs.

grep was pointing to many .htaccess files with strange RewriteRules statements. Then I opened the first one and there it was:

Apparently this malicious snippet is trying to hide itself from the site owner and direct hits, focusing only on hits arrived through search engines like Google, Bing, Yahoo! etc.

What the malware author missed and stood out like a shoot in the foot was that GoogleBot also got into that rule and started pointing out and alerting out users.

Just grep all your files for the URL mentioned on the report, or access your site from a search engine and see if it acts weird.

Fixing

The instant-fix is just runing an extended version of the above command.

The main reason this happens and have so many occurrences is that application developers often fail to properly configure the user account of the running application and the application’s filesystem folders so the application can only write to public directories or its user’s home (which the application is not located there).

Give the application’s folder owner and group permissions according to the application’s user and group, then give the application’s group to the accounts that need to rights to write on it (ex: developers, deploy daemons etc). Then, set up the permissions of the folders accordingly.

It could be worse

If the whole home directory is 777 (if this wasn’t bad enough by itself) (and we found some home directories like that on our probe) the attacker could put his key under ~/.authorized_keys and gain direct shell access to the account. And then it could be even worse…

I strongly recommend everyone that has a shared-hosting account to do this little test. It may save your life.

HTH!

Endpoint DLP: Is hardware access control enough?

I’ve stumbled on this article about using a custom-built hardware to bypass hardware enforcement on most DLP solutions available on market.

The solution uses an Atmel’s AVR microcontroller (the same on the Arduino‘s I’ve been playing around lately) and the V-USB library to create a virtual USB device and is crafted to announce itself as HID (Human-interface device). What common hardware fits this description: the keyboard. As you are not likely to forbid keyboard access to your users (or else they wouldn’t be able to type and thus work), this will gracefully pass through many enforcements.

The HID protocol allows bi-directional communication and this makes a perfect vector for data transfer.

The HID protocol allows communication in both directions by sending and receiving reports and feature requests. I’ve utilised this control channel to allow the PC to transfer files over the HID protocol to the device (…)

Thomas Cannon (the article author) had made experiments with a USB drive and other with an micro SD module attached to the custom-built hardware in order to store the transfered data since the AVR internal memory is quite short (maybe it’s fine for Bill Gates).

White-listing

While I’ve already seen some DLP solutions enforcing pendrives accesses through its vendor and model, I dunno if some had already made a way to enforce a unique fingerprint for each device (maybe yes, sounds feasible).

Can you trust drive signatures? What about the data they traffic?

What if drives signatures cannot be trusted anymore? We are left with the only enforcement left at input level: data monitoring.

Network IPS/IDSs are employed to detect (and sometimes stop) rogue data running on wires. Application IDS/IPSs are employed to detect (and sometimes stop) rogue data that come over inputs. Why not deploy IDS/IPSs at HID level? They are inputs, aren’t?

Suppose you have the latest DLP solution blocking all your USB drives, CD drives, Floppy drives, ZIP drives, iPhone etc etc. You also have all your network connections, email servers, HTTP traffic monitored.

An badly intentioned user won’t be able to upload malware through the drives nor download from web or network but what would stop him from actually TYPING the payload into notepad? Every hex or worse, every bit? Yes, sounds crazy and would take lots of time but hey – never doubt a determined person.

Things can be automated

Ok, so you think ‘Hey Jan, this would never happen, you are crazy. It would be very very very hard to keep track of every 0 or 1 typed’. Sure, I completely agree. The AVR-based hardware thus, does not.

This little beauty needs a piece of code on the host machine to make the data transfer possible so it has a stage where you simply open a notepad and the microcontroller (since he is actually a keyboard) will type it for you! Wow, zero work huh?

Seems that Moore was right after all

There are lot of microcontroller kits like BasicX, Arduino, Parallax and Pololu, just to name a few. Earlier at the São Paulo’s Hackers to Hackers Conference (H2HC) I’ve seen people using and R/C quad-copter holding an embedded system to crack WEP keys. Now we have a ‘robot-keyboard’.

Hardware is getting cheaper, fast as hell. A system is as secure as the complexity need to crack it. Cheaper hardware, more processing per second, greater the complexity has to be.

I wouldn’t be surprised if the next hackers cracking machines will be actually, machines.

Anatomy of the W32.Stuxnet SCADA threat

Symantec released an in-depth analysis of W32.Stuxnet, reviewed through IDA-PRO. The analysis shows off the staged infection process, the unusual injection of legitimate services instead of issuing LoadLibrary calls, core encryption and exported functions.

Tofino Security (specialized on SCADA security) has released an excellent white paper on the case (requires [free] registration). If you are a Malware Researcher / Reverse Engineer or just curious, I totally recommend it.

There’s code, great explanation, images, graphs and such explaining it all the process from infection, rooting and the propper malware code.

Stuxnet targets SCADA systems via USB drives vectors

Microsoft disclosed a zero-day flaw on Windows Shell on Friday and Stuxnet (W32.Stuxnet) is already exploiting it to gain access to SCADA systems through its attack vector.

Since SCADA systems are updated mainly by CDs or pen drives, the attack vector fits as a glove. The malware targets Siemens’ Simatic WinCC software and intends to steal information like projects schematics and upload them to an external website.

From CNet:

Once the malware locates the data it is looking for it encodes it and attempts to upload it to a remote server. The malware waits for a response from the server, which may contain more commands, he said.

Along with the data steal, Stuxnet also provides a trojan backdoor aiming Siemens services and a rootkit (to hide it from the system).

Once the machine is infected, a Trojan looks to see if the computer it lands on is running Siemens’ Simatic WinCC software. The malware then automatically uses a default password that is hard-coded into the software to access the control system’s Microsoft SQL database. The password has been available on the Internet for several years, according to Wired’s Threat Level blog.

Sophos has also released a video on YouTube showing a SCADA system compromised by Stuxnet.

The spreading is done by using stolen/spoofed signed digital certificates:

The malware includes a rootkit, which is software designed to hide the fact that a computer has been compromised, and other software that sneaks onto computers by using a digital certificates signed two Taiwanese chip manufacturers that are based in the same industrial complex in Taiwan–RealTek and JMicron, according to Chester Wisniewski, senior security advisor at Sophos. (Sophos has posted a video showing how a computer is infected on YouTube.) It is unclear how the digital signatures were acquired by the attacker, but experts believe they were stolen and that the companies were not involved.

Adding to this scenario, SCADA admins are not able to change the default password because it would break up software apart.

SCADA systems rely on the fact of being unplugged from networks and as Schneier said, “would YOU like to be the guy that breaks all installed systems controlling valves and such by adding security that nobody demands?”.

It seems that SCADA will demand closer attention from now on since I agree with other professionals that doubts that this is the first SCADA malware.