Latest Entries »

Forensic Challenge 8 – “Malware Reverse Engineering”

I am pleased to announce the next forensic challenge: Forensic Challenge 8 – “Malware Reverse Engineering”.

The challenge has been created by Angelo Dell’Aera and Guido Landi from the Sysenter Honeynet Project Chapter.

Submission deadline is June 15th and we will be announcing winners around the third week of July. We have a few small prizes for the top three submissions.

Have fun!

Angelo Dell’Aera
The Honeynet Project

In late December I was taking a look at some Neosploit instances serving PDF sploits. I soon realized they were the exploit servers responsible for Mebroot diffusion.

I tought “Cool! What a great opportunity to spend some time reversing Mebroot and his preferred payload Torpig!”. While playing with Torpig I noticed something strange with some of his C&C’s.

As you may probably know, Torpig makes use of a domain generation algorithm to locate C&C servers. Each time it needs to contact his C&C, it generates a domain name and appends to it three different TLD (com, net, biz) and, subsequently, tries to connect to each of the three domains generated.

The strange thing I noticed is that some domains (two out of three), while active, were pointing to a couple of servers that didn’t respond correctly to the requests sent by the Torpig bot. They accept the data sent by the bot but they never send the response back.

While trying to understand what was going on, I found that those domains are all handled by two DNS servers with a curious name:

ns1.torpig-sinkhole.org
ns2.torpig-sinkhole.org

The whois record for those domains is even more strange:

registrant-firstname: Torpig
registrant-lastname: Cabal
registrant-street1: Holand 10b/5
registrant-pcode: 22225
registrant-city: Afula
registrant-ccode: IL
registrant-phone: +9.7254786002
registrant-fax: +9.7254786002
registrant-email: the.torpig.cabal@googlemail.com

At this point I started understanding what was going on. Someone is taking over the Topig botnet by registering the Torpig domains with .net and .com extensions. Again. And looking at IP addresses and domains whois records, it seems that 1&1 and Deutsche Telekom with the help of someone in Israel are responsible for the “sinkhole”.

So I started looking for informations about the take over but all I was able to find is this, where they blame Damballa because:

“Damballa reportedly didn’t take into consideration sinkhole domains [...] and 1&1 has implemented a large number of these sinkholes, for instance for the Torpig banking trojan. [..] Damballa should really know about such defence mechanisms, as they themselves use this technology to analyse botnets”

Note that the real purpose of such a “sinkhole” is not to block the communication between bots and C&C because the Torpig bot, after receiving no answers from the .com and .net domains, tries the .biz one that is controlled by the “bad guys” and hosted on a fast-flux network.

A couple of questions come to mind:

  • How can you distinguish a real C&C from a fake one?
  • Is just using esotic names for servers and whois records enough to look legitimate?
  • How many independent researchers are wasting their time on those fake C&C’s if even the security industry is getting fooled?
  • And what about all the personal data, belonging to worldwide users, that is sent to the fake C&C’s?

In short: shouldn’t operations like this be documented somewhere?

Another challenge is ready to be tackled by forensic analysts, students, hackers and alike. This time, we present you with an attack vector that has become quite successful: malicious PDF files!

For challenge 6 of our series (provided by Mahmud Ab Rahman and Ahmad Azizan Idris from the Malaysia Honeynet Project Chapter) we present you with a pcap file that contains network traffic generated by the following scenario: An unsuspecting user opens a compromised web page, which redirects the user’s web browser to a URL of a malicious PDF file. As the PDF plug-in of the browser opens the PDF, the unpatched version of Adobe Acrobat Reader is exploited and, as a result, downloads and silently installs malware on the user’s machine.

We prepared a set of questions that requires you to dive deep into the portable document format. Submit your solution by November 30th 2010. The top three submissions will receive small prizes.

Enjoy!

Christian Seifert
Chief Communications Officer
The Honeynet Project

The first one writing about this new threat was Marco Giuliani. So, Murofet or Zeus++?

Taking a look at a couple of samples we were able to identify:

- Same API hooks
- Same encryption routine for configuration file (RC4)
- Pretty much the same configuration file format

Here you can take a look at a decrypted configuration file. It’s possible to realize that it makes use of the same block-based structure of Zeus configuration files. Just like any other Zeus it has a block with id 0x214e (at offset 0x1c) where the version of the builder used to create the bot is stored (at offset 0x2c). In our case that is 2.1.0.7.

So what about calling it just Zeus 2.1 ?

Trojan Carberp

I’m interested in infostealers and specifically in banking-trojans so I didn’t want to miss this one. Samples of Carberp are floating around at least since last spring but in late September we saw such numbers increasing.

Taking a look at how Carberp hooks API it looks like yet another Zeus “clone”. What I found interesting is how it hooks system calls. This is how a normal syscall looks like

MOV EAX,0xce // ZwResumeThread syscall id
MOV EDX,0x7FFE0300 // pointer to KiFastSystemCall
CALL DWORD PTR DS:[EDX]
RETN 0x8

And this is how the hooked syscall looks like

MOV EAX,0xce
MOV EDX,0x00152958 // pointer to fake KiFastSystemCall
CALL DWORD PTR DS:[EDX]
RETN 0x8

Instead of overwriting the first instruction(s) with a JMP/CALL to redirect the execution flow to the hook, Carberp substitutes the pointer to KiFastSystemCall. This is nothing new but it is actually enough to hide such hook from most of the “anti-rootkit” products out there (including rkunhooker).

– “it bypasses DEP and ASLR using impressive tricks and unusual methods” – Vupen

– “it uses a previously unpublished technique to bypass ASLR” – Metasploit Blog

- “exploit uses the ROP technique to bypass the ASLR and DEP” – ZDnet/Kasperky

– “it’s so scary I ran away screaming” – anonymous

Is that PDF so scary? I don’t think so.

DEP is an hardware feature that prevents execution of data, it obviously works if software sets the execution flag only on memory pages containing code.

If you VirtualAlloc all of your memory with PAGE_EXECUTE_READWRITE DEP can’t help.
If you opt-out, it can’t help.
If you disable it system-wide.. guess what.

Is “directly executing injected data” the only way to get “arbitrary code execution”? Answer is: nope.

It is possible to get “arbitrary code execution” by taking advantage of the call/return mechanism of x86. This was called ret2libc more than ten years ago and it works by injecting fake stack frames instead of code. The return addresses of those stack frames are used to jump to code already in memory that belongs to main executable or libraries. By chaining stack frames, if enough functions are present in memory, you can achieve “arbitrary code execution”.

Since windows is pretty happy to give you memory with write and execution permissions and there are even a few api to programmatically disable DEP, there’s no really need to use ret2libc to implement the entire shellcode. Instead you use it to call just a couple of functions or “pieces of functions”(gadgets) to ask for +RWX memory, copy the shellcode there, jump to it. All you need is the addresses of those functions/gadgets.

Is that a DEP bypass? nope. but it’s smart and convenient, isn’t it?
Is it something new, at least in the wild? nope.
ret2what? ret2libc, but cool guys now call it ROP.

ASLR is a software feature that randomizes memory allocations and should stop ret2libc because it makes hard to guess the location of a piece of code. It works if software does not give the attacker too much control over memory allocations.

If software does leak pointers ASLR can’t help.
If you don’t opt-in, it can’t help.

How that scary exploit works? It uses heap-spray to fill the memory with fake stack frames and ret2libc to “bypass” DEP as describe above, the addresses of functions/gadgets used to put the shellcode in an +rwx area come from a DLL that does not opt-in to ASLR.

Is that an ASLR bypass? nope, it’s sounds to me like bypassing ASLR when ASLR is disabled.

Forensic Challenge 5 – Log Mysteries is now live! This challenge takes you into the world of virtual systems and confusing log data. Figure out what happened to a virtual server using all the logs from a possibly compromised server.

Challenge 5 has been created by Raffael Marty from the Bay Area Chapter, Anton Chuvakin from the Hawaiian Chapter, and Sebastien Tricaud from the French Chapter. It is a bit more open ended than the last challenges, so I am really looking forward to some creative answers!

Submission deadline is September 30th and we will be announcing winners around October 21st. We have a few small prizes for the top three submission.

Enjoy!

I’ll tell you the truth: Export Address Table Filtering, the feature of the upcoming release of EMET, “designed to break nearly all shell code in use today”, intrigued me a bit.

Since I wasn’t able to find docs about the actual implementation, I started to think about how that could be done and I wrote a simple POC that uses VirtualProtect to flag the relevant pages of the .data section of ntdll and kernel32 with PAGE_GUARD to intercept read operations over the PEB.Ldr. A Vectored Exception Handler is then used to handle the exception and to check if the faulting address is within the code section of a module(MEMORY_BASIC_INFORMATION.Type == MEM_IMAGE). Here is the pseudo-code:

BOOL WINAPI DllMain(...)
{
    [...]
    AddVectoredExceptionHandler(1, VectoredHandler);
    VirtualProtect(PLDR,
        PAGE_SIZE,
        PAGE_READWRITE|PAGE_GUARD,
        &old_protect);
    [...]
}
LONG CALLBACK VectoredHandler(
    __in PEXCEPTION_POINTERS ExceptionInfo)
{
    [...]
    if(ExceptionInfo->ExceptionRecord->ExceptionCode ==
        STATUS_GUARD_PAGE_VIOLATION)
    {
        VirtualQueryEx(GetCurrentProcess()	,
            (LPVOID)ExceptionInfo->ExceptionRecord->ExceptionAddress,
            &lpMemInfo,
            sizeof(MEMORY_BASIC_INFORMATION)))

        if(lpMemInfo.Type != MEM_IMAGE)
            ShellcodeDetected();
    [...]

Yesterday I found this .doc. It explains pretty much everything: they use hardware breakpoints to intercept read operations and a Vectored Exception Handler to check if the faulting address belongs to a module…. pretty much the same thing, isn’t it?

Then I started to think about how EAT filtering could be bypassed, obviously there are many ways to find the address of a function without touching the EAT, but I was looking for a quick way to just fix existing shellcodes and make them working under EMET. Since EMET is going to use hardware breakpoints it will be probably faster than the PAGE_GUARD approach because while you can put a breakpoint on a single DWORD using debug registers, the granularity of VirtualProtect is PAGE_SIZE.

But hardware registers can be zeroed out, disabling the protection, by taking advantage of the Structured Exception Handling and without even using a single API. And so, I thought, you can easily add to a metasploit shellcode something like this:

START:
    call +0                  // poor's man get_pc()
    mov eax, [esp]
    add eax, HANDLER_OFFSET
    push eax               // install SEH handler
    push fs:[0]
    mov fs:[0], esp
    xor eax, eax
    mov byte [eax], 1	// oops
    [...]

HANDLER:
    xor eax, eax
    mov ebx, [esp+0xc]	// context
    add [ebx+0xb8], 3	// eip += len("mov byte [eax], 1")
    mov [ecx+0x4], EAX	// clean debug registers
    mov [ecx+0x8], EAX
    mov [ecx+0xc], EAX
    mov [ecx+0x10], EAX
    mov [ecx+0x14], EAX
    mov [ecx+0x18], EAX
    ret

right? Well, not quite really! Because this is not gonna work with SAFESEH enabled! :)

Btw, is there a way to quickly disable PAGE_GUARD using only position independent code and without touching EAT?

A new improvement in PHoneyC DOM emulation code was committed in SVN r1624. The idea is to better emulate the DOM behaviour depending on the selected browser personality. Let’s take a look at the code starting from the personalities definition in config.py.

39 UserAgents = [
40     (1,
41      "Internet Explorer 6.0 (Windows 2000)",
42      "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
43      "Mozilla",
44      "Microsoft Internet Explorer",
45      "4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
46      "ie60",
47     ),
48     (2,
49      "Internet Explorer 6.1 (Windows XP)",
50      "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
51      "Mozilla",
52      "Microsoft Internet Explorer",
53      "4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
54      "ie61",
55     ),
56     (3,
57      "Internet Explorer 7.0 (Windows XP)",
58      "Mozilla/4.0 (Windows; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)",
59      "Mozilla",
60      "Microsoft Internet Explorer",
61      "4.0 (Windows; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)",
62      "ie70",
63     ),
64     (4,
65      "Internet Explorer 8.0 (Windows XP)",
66      "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; (R1 1.5); .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
67      "Mozilla",
68      "Microsoft Internet Explorer",
69      "4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; (R1 1.5); .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
70      "ie80",
71     ),
72 ]

It’s important to realize that each personality was added a tag (i.e. ie80). Taking a look at DOM/Window.py the following code can be seen.

229     def __init_methods(self):
230         for attr in dir(self):
231             prefix = “_Window__window_%s_” % (config.browserTag, )
232             if attr.startswith(prefix):
233                 p = attr.split(prefix)[1]
234                 self.__dict__['__cx'].add_global(p, getattr(self, attr))
235                 self.__dict__['__cx'].execute(“window.%s = %s;” % (p, p, ))

Let’s consider an example and assume the Internet Explorer 8.0 personality was selected. It’s easy to realize that the prefix would assume the value _Window__window_ie80_. A few simple wrappers were created, one per personality, to each method as shown in the following code.

340     def __window_back(self):
341         “”"
342         Returns the window to the previous item in the history.
343         Syntax
344
345         window.back()
346
347         Parameters
348
349         None.
350         “”"
351         pass
352
353     def __window_ie60_back(self):
354         self.__window_back()
355
356     def __window_ie61_back(self):
357         self.__window_back()
358
359     def __window_ie70_back(self):
360         self.__window_back()
361
362     def __window_ie80_back(self):
363         self.__window_back()
364
365     def __window_firefox_back(self):
366         self.__window_back()

This is a quite simple situation but what if you want to define addEventListener method just for Firefox personalities and attachEvent just for Internet Explorer ones? Really simple to do!

1191     def __window_attachEvent(self, sEvent, fpNotify):
1192         if dataetc.isevent(sEvent, ‘window’):
1193             self.__dict__[sEvent] = fpNotify
1194
1195     def __window_ie60_attachEvent(self, sEvent, fpNotify):
1196         self.__window_attachEvent(sEvent, fpNotify)
1197
1198     def __window_ie61_attachEvent(self, sEvent, fpNotify):
1199         self.__window_attachEvent(sEvent, fpNotify)
1200
1201     def __window_ie70_attachEvent(self, sEvent, fpNotify):
1202         self.__window_attachEvent(sEvent, fpNotify)
1203
1204     def __window_ie80_attachEvent(self, sEvent, fpNotify):
1205         self.__window_attachEvent(sEvent, fpNotify)
1206
1207
1208     def __window_detachEvent(self, sEvent, fpNotify):
1209         if sEvent in self.__dict__ and self.__dict__[sEvent] == fpNotify:
1210             del self.__dict__[sEvent]
1211
1212     def __window_ie60_detachEvent(self, sEvent, fpNotify):
1213         self.__window_detachEvent(sEvent, fpNotify)
1214
1215     def __window_ie61_detachEvent(self, sEvent, fpNotify):
1216         self.__window_detachEvent(sEvent, fpNotify)
1217
1218     def __window_ie70_detachEvent(self, sEvent, fpNotify):
1219         self.__window_detachEvent(sEvent, fpNotify)
1220
1221     def __window_ie80_detachEvent(self, sEvent, fpNotify):
1222         self.__window_detachEvent(sEvent, fpNotify)
1223
1224
1225     def __window_addEventListener(self, type, listener, useCapture = False):
1226         if dataetc.isevent(type, ‘window’):
1227             self.__dict__[type] = listener
1228
1229     def __window_firefox_addEventListener(self, type, listener, useCapture = False):
1230         self.__window_addEventListener(type, listener, useCapture = False)
1231
1232
1233     def __window_removeEventListener(self, type, listener, useCapture = False):
1234         if type in self.__dict__ and self.__dict__[type] == listener:
1235             del self.__dict__[type]
1236
1237     def __window_firefox_removeEventListener(self, type, listener, useCapture = False):
1238         self.__window_removeEventListener(type, listener, useCapture = False)

Moreover this approach could allow to insert specific code within the wrappers if needed while implementing the method functionalities in the higher level __window_<method_name> wrapper.

“Dionaea is meant to be a Nepenthes successor, embedding Python as scripting language, using libemu to detect shellcodes, supporting IPv6 and TLS” (taken from Dionaea homepage). Besides being the most interesting project for trapping malware exploiting vulnerabilities, Dionaea supports a really cool feature which allows it to log to XMPP services as described here. TIP now exploits this feature receiving and storing such logs (really thanks to Markus Koetter for his help and support). Just an example of what happened today…

2010-08-11 10:44:21+0200 [XmlStream,client] [Malware Sample] MD5: e4736922939a028384522b17e9406474
2010-08-11 10:44:21+0200 [XmlStream,client] [Malware Sample] SHA-1: 920b67cb250abdb593b1104a9922e2468b0fe252
2010-08-11 10:44:21+0200 [XmlStream,client] [Malware Sample] PEHash: 40891becb5ec8780f1c5e51f3971c9fb2cc17dab

Another great step forward was taken. Stay tuned!

Bad Behavior has blocked 82 access attempts in the last 7 days.