Hunting for Web Shells

Web shells are nothing new, but their use continues to plague security professionals and their customers. With low anti-virus detection rates and few good tools to aid in discovery, how can you fight back?

A breach has occurred

On November 25th, 900 San Francisco Municipal Transportation Agency (SFMTA) computers were infected by a ransomware variant known as HDDCryptor. The ransom demand was 100 bitcoins (approximately $73,000). Due to the attack the SFMTA was temporarily unable to collect an estimated $50,000 in fares.

The immediate question is: “How did this happen?” In a press release, the SFMTA stated that their network “was not breached from the outside.” However, journalist Brian Krebs, in collaboration with Alex Holden of Holden Security Inc., reported that the SFMTA attacker “has been using a number of tools which enabled the scanning of large portions of the Internet and several specific targets for vulnerabilities” and that the “most common vulnerability used [was] ‘weblogic unserialize exploit’.”

Tenable is quite familiar with the various WebLogic deserialization exploits. The original vulnerability, CVE-2015-4852, was released as a zero day by FoxGlove Security. Further, Oracle’s original fix proved insufficient and led to CVE-2016-0638, CVE-2016-3510, and CVE-2016-5535 — the last of which was recently patched in October, nearly a year after the original FoxGlove Security disclosure.

Nessus Flagging Deserialization Vulnerabilities in WebLogic

WebLogic web shell backdoor

Despite the SFMTA’s reassurances, the ransomer further claimed to “still have backdoors in the SMFTA network.” While many may be disinclined to take the word of this criminal, I believe the SFMTA would do well to hunt for any possible backdoors.

If WebLogic was the entry point into the SFMTA network, then it would have been trivial to drop a web shell backdoor onto the server to facilitate future access. WebLogic is perfect for a web shell because it can interpret JavaServer Pages (JSP) files.

For example, I took the following JSP web shell from the ysoserial project and I put it in the directory where WebLogic’s console application stores its cascading style sheets:

I can then remotely execute shell commands from my browser via the WebLogic server:

Not only will this web shell provide backdoor access after WebLogic has been patched, but it also has a ridiculously low antivirus detection rate: 2/54.

Web shells: a wider problem

Web shells aren’t a WebLogic specific problem. Many web servers make great hosts for malicious shells. This has become such a problem that last year US-CERT issued an alert warning about the rising threat of web backdoors.

Web shells may seem obvious and unsophisticated, but advanced actors are using them as well. Deep Panda and Emissary Panda have both been known to use web shells like China Chopper. Crowdstrike wrote a very interesting article detailing a couple of Deep Panda’s backdoors that they encountered on an engagement.

But web shells aren’t just for sophisticated attackers. In my search for web shell samples, I used GitHub to search the many WordPress and Joomla! sites that are backed up there. Unsurprisingly, there are hundreds of these sites just riddled with backdoors. Consider this issue submitted by @tenacioustek:

A large chunk of the blame for that level of infection is not patching an Internet facing server. However, there are other problems that should be considered. For instance, where are the tools for detecting web shells? Certainly, some exist (web shell detector and LOKI), but are they getting used? How well would they operate at an enterprise level?

Another part of the problem is the bad AV detection rates. I already showed you a JSP web shell with a 2/54 rate. In an excellent article by dfir it!, they present this simple PHP shell:

This rule causes Nessus® to flag the web shell that I dropped onto the WebLogic server earlier in this blog:

More YARA rules

The problem with YARA is that you need rules for it to work. Unfortunately, Nessus doesn’t yet come with a rule set, but there are great projects like YARA Rules and LOKI that share their web shell rules with the world. Tenable has been working on a rule set that we hope to open source soon. Until then, here are a few of the more interesting web shells that we’ve created rules for.

This is an obfuscated version of PHP/Small.B that has a detection rate of 8/54 on VirusTotal. Just looking at the code, you probably assume that the eval(gzinflate(base64_decode()))) will unmask the web shell. However, that isn’t the case at all. Instead, this statement generates another eval(gzinflate(base64_decode()))) which will generate another and another and another - until eventually the web shell is finally exposed. You can find the deobfuscated version on GitHub.

I’m not entirely certain why this particular script uses GIF89GHZ. Far more popular is GIF89a as described here. Either way, you can see again that this script also relies on eval() and built-in PHP functions for obfuscation. Both the obfuscated and deobfuscated versions of this script have fairly low detection rates: 14/54 and 3/49 respectively.

Writing a rule to detect this type of obfuscation isn’t too hard if you are willing to accept that using eval followed by a string modifying function is an indicator of malicious intent:

The last web shell I want to share is this shell shared by @bartblaze that uses the Free Online PHP Obfuscator (FOPO) and has a 0/53 detection rate. The shell is too big to paste here, but we are only really interested in the start. It looks like this:

This might look a little weird but it is actually pretty straightforward. Cleaned up a bit this is really:

$g2a594c0=”base64_decode”;
@eval($g2a594c0(“…”);

Not too different from what we’ve seen in the previous obfuscated shells right? The only catch is that the Free Online PHP Obfuscator changes up how it encodes the base64_decode string. Here are some samples:

Conclusion

Malicious web shell use is widespread. If you are in charge of a web server, you must remain vigilant. Keep the server up to date with the latest patches and use any available tooling to ensure that no web shells are hiding on your server.