Tag: OLE

Since support for the RTF file format has been added very recently with the version 0.9.4 of the Profiler, it’s a good idea to test it against real malware. I downloaded a pack of RTFs from contagiodump.blogspot.com and as I promised in the last post chose a more recent vulnerability: CVE-2012-0158. The reason why I picked a certain RTF from the pack is because most of the RTFs were automatically recognized and analyzed by the Profiler, while the following sample offers us a chance for some nice interactive analysis.

The first problem as you can see from the screenshot is that the RTF is not being automatically identified as such. That is because the signature is incomplete: the last two letters are missing. The next version of the Profiler will improve the detection in this regard. However, we can easily load it as RTF ourselves.

The RTF contains a lot of foreign data (meaning data which is not part of the RTF itself). Looking at the pattern an educate guess would be that it’s an encrypted payload.

The OLE stream contained in the RTF is flagged as containing possible shellcode. The Profiler detects it correctly. However, it’s actually the object embedded in the OLE stream which contains the shellcode. But wait, there’s no embedded object visible. This is because the extraction of the object failed, since the format of the OLE stream (which is undocumented) is different than usual. This is not a problem, we can just as easily load the object ourselves as the signature is easily recognizable.

This last step was not strictly necessary, since we had already a detected shellcode in the OLE stream, but it increases the completeness of the analysis.

Since this is the header of the OLE stream:

1

2

3

4

5

Offset0123456789ABCDEFAscii

0000000001050000020000001B0000004D53436F............MSCo

000000106D63746C4C69622E4C69737456696577mctlLib.ListView

000000204374726CCtrl

Another educated guess would be that this is the component affected by the vulnerability. Let’s go back to the detected shellcode.

The initial instructions make sense and the following ones not. Let’s take a closer look.

Assembly (x86)

1

2

3

4

5

6

7

8

9

10

11

12

13

00000920:nop

00000921:nop

00000922:nop

00000923:nop

00000924:jmp0x936

00000926:popedx

00000927:decedx

00000928:xorecx,ecx

0000092A:movcx,0x2da

0000092E:xorbyteptr[edx+ecx*1],0xee

00000932:loop0x92e

00000934:jmp0x93b

00000936:call0x926

This portion of code is easily recognizable as being a decryption loop for the code that follows. This is usually implemented to avoid detection. Didn’t work this time.

Let’s select the encrypted shellcode.

And decrypt it with the xor filter. We can confirm the correctness of the decryption by adding the ‘disasm/x86‘ filter.

Back to the decrypted bytes, we use the script presented in the previous post to create an executable from the shellcode.

The debugger was necessary only to check which APIs are retrieved by the shellcode and from there static analysis was easy. To sum up the shellcode decrypts two files, an executable and a doc file, executes the first directly and opens the second with the same program which is executing the shellcode.

From the shellcode we can retrieve the ranges of the encrypted payloads:

1

2

offset:0x283bsize:0x1c400

offset:0x1ec3bsize:0x8e00

Now we can open the encrypted payloads and apply the simple decryption code.

Python

1

2

3

4

5

6

7

8

9

fromPro.UI importproContext,ProView

view=proContext().getCurrentView()

ifview.isValid()andview.type()==ProView.Type_Hex:

b=view.readBytes(0,view.getSize())

forxinrange(len(b)):

ifb[x]!=0andb[x]!=0xFC:

b[x]=b[x]^0xFC

view.setBytes(b)

We save the decrypted payloads to disk. In the near future this won’t be necessary as such a filter will be easily created and used to load files inside the workspace of the Profiler itself.

We can use the safe text preview of Word Documents in the Profiler to view the text of the document opened by the shellcode.

From the text it seems to be directed at something gov: “My Esteemed Colleagues; Members of the Board of Governors of the Indian Business Chamber in Vietnam”.

The reason for opening the second document is clearly that the instance of the original program which ran the shellcode would’ve crashed and was therefore terminated cleanly with ExitProcess by the shellcode itself. Spawning a second instance with a clean document doesn’t make the user suspicious, from his point of view he just opened a document and a document has indeed been opened.

The executable is not protected by any means and so it’s just a matter of opening it with IDA Pro and spend a few hours understanding the whole code. But that’s beyond the scope of this demonstration.

The work on the upcoming 0.9.4 version of the Profiler has just begun, but there’s already an addition worth mentioning in depth: the support for RTF files. In particular there are two things which are quite useful: the preview of raw text and the extraction of OLE objects.

Let’s start with the first one which is very easy.

The same text can be retrieved programmatically with the following code:

Python

1

2

3

4

5

sp=proContext().currentScanProvider()

rtf=sp.getObject()

out=NTTextBuffer()

rtf.Output(out)

print(out.buffer)

And now the more interesting part about embedded OLE objects. While RTF is usually regarded as a more safe format than its DOC counterpart, it is able to embed foreign objects through the OLE technology. This technique can be, and is, used by malware authors to conceal the real threat.

Let’s take a look at a file with two embedded objects (a DOC and a PPT).

What is being viewed in the image above is the metadata of a JPEG contained in a PPT contained in a OLE Stream contained in a RTF file. Nice, isn’t it?

It should be noted that OLE objects in RTF files are stored as OLE Streams an undocumented format (as far as we know). The Profiler is able to parse it nonetheless and it can be observed how this format can contain some interesting information.

Apart from the original file name we can observe paths which include the user name.