Archive for the 'python' Category

PDF CVE-2010-0188

While analyzing a recent pdf sample exploiting the TIFF vuln it used a known technique to obfuscate it’s content: it appends a pdf to the first one after a bunch of of “garbage” (that contains the dropped executables)

%PDF-1.6
...
%%EOF
[GARBAGE]
%PDF-1.6
...
%%EOF

I tried to run my extractor on the sample to retrieve all the streams decompressed but i didn’t found the one containing the famous exploit

The reason why i wasn’t able to recover the exploit is that the second pdf redefined an object (0 1) and so the first dumped stream was overwritten by the last one thus hiding the exploit.

I just did a little modification to preserve all the streams extracted even if there is a id collision, you can download it

here.

WoW Infostealer

Just a quick analysis of a WoW infostealer (md5: D214BD51E47DFD3DEA97B5A2ED28CBF5 / ThreatExpert).

The program is a simple dropper, there are no antidebug tricks nor it uses complex obfuscation techniques, it just extracts the DLL (md5: 7DEFE341246BB1DE68A7AFB233FB8CAF) that contains the core of the virus. The dll itself is sprayed on multiple (scrambled) resources inside the dropper:

The resoures are extracted and concatenated to form the dll in: C:\Windows\System32\msnjkwfb.dll, and after that the dropper invokes a function in the dll responsible for the installation and deletes itself.

The installer registers the dll for autorun, retrieves the WoW path, and copies inside it the dll under the name msvcr70.dll, after, it injects code into the WoW exacutable (wow.exe): adds a section (.ngaut) and changes the program entrypoint to its code. The injected code just loads msvcr70 and gives control back to the original entrypoint.

When the dll is loaded by wow.exe it starts searching for the main window, and then does some checks on the window’s title “World of Warcraft” and class “GxWindowClassD3d” if both checks succeeded it acquires the SeDebugPrivilege and spawns a thread that collects the information using static offsets into the program. Once all the information is gathered it sends a HTTP request to:

with the following request:

?WOWID=%s&Area=%s&WU=%s&WP=%s&MAX=%d/%d&Gold=%d&Serv=%s&rn=%s&key=%s

the site is still up at this time, so be careful WoW gamers πŸ˜›

p.s. for those interested here the py script to descramble and merge the extracted resources

Another Python PDF Parser

(edit): updated screenshots πŸ˜‰

It’s not a full PDF parser, I just needed to extract streams and javascript from a pdf so it has few options :

  1. list objects
  2. extract all streams
  3. extract javascript
  4. dump object

1. list all objects

2. extract streams

you will found one file named: sample_stream-9-0.txt in you dir.

3. extract javascript

check the directory and you’ll find a file named: sample_js-2-0.txt

you can further inspect objects using the dump command, let’s try it on the object containing the javascript (2 0) :

you can download the tool here

and that’s it πŸ˜‰

PDF Exploit Malware #1

Today we take a look at a pdf exploit malware (md5 is 1cf1128b9190d7344c200e1e944d7abf).

First of all let’s open the pdf file with a text editor and dig into it:

rawpdf

As we can see from the object definition, we have a stream compressed with zlib:

rawpdf1
We can code a small python script that will do all the dirty work (decompress and make code readable) for us.

The following is our stream after decompression:

f1

The above javascript code, retrieves the second stream located in the first page of the pdf file and handles this stream.

To locate the second stream, it uses the syncAnnotScan method in order to scan all the annotations in the document and then it uses getAnnots to retrieve the list of annotation and then picks up the first one, our second stream.Β  For details about javascript/acrobat, please take a look here.

It decodes this stream by replacing (using a global replacement ‘z’ with ‘%’) with the regexp “/z/g,’%’” so it calls unescape and finally it calls eval.

Our uncompressed stream fixed is (click on the following images to enlarge):

f2p1f2p2

Ok, let’s have fun with this joyful and clear javascript function 😦

The first parameter (FfVKaBvcfE3268e) is set to 0 and the second one (JJ140q) is obviously an encoded code string. As we can see, this function handles the encoded code string (full dump here) in order to deobfuscate the code itself. The code is another javascript, as we can see from the eval (eval(n__YJ78gI18RI)) call at the end of this second function.

At the beginning of the function, we have an anti-debug trick:

f2callee

This trick is discussed here. It uses its own javascript code (by using the arguments.callee) as the key to deobfuscate the code string discussed above.

If we take a closer look at this function, we can notice that the key is built only by using the number chars into this function code. Here is a small python script that extracts the key:

key = ""

for i in range(0, len(data)):
 if data[i] >= '0' and data[i] <= '9':
  key += data[i]

print key

Let’s look at the final functions (we just focus on the relevant parts).

First of all, the exploit is related to an old version of Adobe Reader as we can see in the following snippet:

Another interesting part is this function in which it handles the shellcode:

We can obtain the website which it connects to download the malware from the shellcode:

At this time this website seems to be offline, so no further analysis can be done on the downloaded malware.

The exploit used is related to an old vulnerability that is reported here.

Ok that’s all… see you next post πŸ™‚

Quick Offset Finder

Hi all,

just a quick post… I was following a patching topic on a friend’s forum where someone asked for a fast way to find the offset of a known pattern in a PE file. So I just wrote down this small python script that works by using pefile and pydasm.

So here is a 2-minutes python code: it searches for a given pattern in a PE file and it shows both “offset and instructions” for each match.

Here is an example of the output:

find offset

Here is the source code:

# by ratsoul

import pefile
import pydasm

#your PE file target
TARGET  = r""
#your pattern
PATTERN = "\xC4\xFF\xE0"
#number of instructions showed for each offset
NUM_INSTR = 5

lenPattern = len(PATTERN)
pe = pefile.PE(TARGET, fast_load=True)
codes = {}

for idx in xrange(len(pe.__data__)):
    if PATTERN in pe.__data__[idx:lenPattern+idx]:
        off = idx
        count = 0
        code = ""
        while count  " + pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, off) + '\n'
            off += i.length
            count += 1
        codes[idx] = code

print "[*] Found: %d" %len(codes)
for offset in codes.keys():
    print "\t[+] %08X:" %offset
    for c in codes[offset].split("\n"):
        print "\t\t%s" %c

The code is available here.

Sorry for the short post because I’m a little bit busy in this period… see you next post πŸ™‚

ESP trick in PyEmu

ESP trick is an old way to defeat some packer, this procedure is really simple: first look for a PUSHAD near the entrypoint, step over the PUSHAD, follow ESP into memory and then set an hardware breakpoint on access to this location. Wait for a POPAD which accesses this location and then look for a near JMP.

How to do this within a debugger is quite obvious but this time we want achieve this objective in a different way, we wanna use PyEmu.

Ok warm-up ended… let’s code…

Step 1, define our PUSHAD instruction handler:

def pushad_instruction_handler(emu, instruction, eip, op1, op2, op3):
    #get and save ESP
    global _esp_
    _esp_ = emu.get_register("ESP") - 4
    #set our memory handler
    emu.set_memory_access_handler(memory_access_handler)

    return True

Step 2, define our memory access handler:

def memory_access_handler(emu, address, value, size, type):
    global _esp_
    if address == _esp_ and type == "read":
        #set JMP handler
        emu.set_opcode_handler(0xE9, jmp_instruction_handler)

    return True

Step 3, define our JMP instruction handler:

def jmp_instruction_handler(emu, instruction, address, op1, op2, op3):
    #stop emulation
    emu.emulating = False
    #print OEP
    raw_input("[*] OEP: 0x%08x" % address)

    return True

Step 4, put all together:

_esp_ = None

def pushad_instruction_handler(emu, instruction, eip, op1, op2, op3):
    #get and save ESP
    global _esp_
    _esp_ = emu.get_register("ESP") - 4
    #set our memory handler
    emu.set_memory_access_handler(memory_access_handler)

    return True

def memory_access_handler(emu, address, value, size, type):
    global _esp_
    if address == _esp_ and type == "read":
        #set JMP handler
        emu.set_opcode_handler(0xE9, jmp_instruction_handler)

    return True

def jmp_instruction_handler(emu, instruction, address, op1, op2, op3):
    #stop emulation
    emu.emulating = False
    #print OEP
    raw_input("[*] OEP: 0x%08x" % address)

    return True


emu = PEPyEmu()

if not emu.load(EXE_TO_UNPACK):
    print "[!] unable to load target exe: %s" % EXE_TO_UNPACK
else:
    #library
    emu.set_library_handler("LoadLibraryA", LoadLibrary)
    emu.set_library_handler("GetProcAddress", GetProcAddress)
    emu.set_library_handler("VirtualProtect", VirtualProtect)

    #opcode
    emu.set_opcode_handler(0x60, pushad_instruction_handler)

    #misc
    emu.execute(start=emu.entry_point, end=-1)

This program has been tested versus an UPX packed exe, so maybe that with a different packer it will not work fine. Full source code is available here.

I hope you enjoyed this little trip into PyEmu… see you next post 8)

PyQt and Connection Dropper

Continuing the Py* tradition of this this blog, i’ll present a simple GUI for the connection dropper, just to get some confidence with the PyQt.

Connection Dropper GUI

There is nothing much to say, the code is straightforward and should be intuitive, so fire up the program (cdrop.pyw) and have fun!

Connection Dropper

Today I was playing with python and ctypes to build a connection dropper… cause we (me and swirl) need a small lib to embed in an our tool.

Before to proceed we need to know how the following windows functions works: GetTcpTable (the GetTcpTable function retrieves the IPv4 TCP connection table) and SetTcpEntry (the SetTcpEntry function sets the state of a TCP connection).

Well so all we have to do is to retrieve the connections list by using GetTcpTable,Β select the connection we want to drop and then change its status to MIB_TCP_STATE_DELETE_TCB by using SetTcpEntry. Easy… let’s code…

First we have to create some defines…

#connection dropper - defines.py
# by ratsoul

from ctypes import *

BYTE      = c_ubyte
WORD      = c_ushort
DWORD     = c_ulong

ERROR_INSUFFICIENT_BUFFER = 122

CONNECTION_STATUS = {
  1 : "closed",
  2 : "listen",
  5 : "estab",
  9 : "closing"
  }

DROP = MIB_TCP_STATE_DELETE_TCB = 12

class MIB_TCPROW(Structure):
    _fields_ = \
                [
                ("dwState", DWORD),
                ("dwLocalAddr", DWORD),
                ("dwLocalPort", DWORD),
                ("dwRemoteAddr", DWORD),
                ("dwRemotePort", DWORD)
                ]

class MIB_TCPTABLE(Structure):
    _fields_ = \
                [
                ("dwNumEntries", DWORD),
                ("table", MIB_TCPROW * 4000)
                ]

class S_UN_B(Structure):
    _fields_ = \
                [
                ("s_b1", BYTE),
                ("s_b2", BYTE),
                ("s_b3", BYTE),
                ("s_b4", BYTE)
                ]
class S_UN_W(Structure):
    _field_ = \
                [
                ("s_w1", BYTE),
                ("s_w2", BYTE)
                ]

class S_UN(Union):
    _fields_ = \
                [
                ("s_un_b", S_UN_B),
                ("s_un_w", S_UN_W),
                ("s_addr", DWORD)
                ]

class IN_ADDR(Structure):
    _fields_ = [("s_un", S_UN)]

Then we can proceed with the main code…

#connection dropper - cdrop.py
# by ratsoul

from ctypes import *
from defines import *
import socket

#dll
iph = windll.Iphlpapi
ws2 = windll.Ws2_32
msv = windll.msvcrt

#struct
ipaddr = IN_ADDR()
mtable = MIB_TCPTABLE()

#misc
size   = c_ulong(sizeof(mtable))
connections_list = {}

#GetTcpTable
ret = iph.GetTcpTable(byref(mtable), byref(size), True)
if ret == ERROR_INSUFFICIENT_BUFFER:
    #no problem..
    mtable = MIB_TCPTABLE()
    iph.GetTcpTable(byref(mtable), byref(size), True)

mt = mtable.table
id = 0
print "> Connections list:"
for i in range(mtable.dwNumEntries):
    t = mt[i]
    #get status info
    try:
        status = CONNECTION_STATUS[t.dwState]
    except:
        status = "unkn"
    #get local info
    ipaddr.s_un.s_addr = t.dwLocalAddr
    local_address = socket.inet_ntoa(ipaddr)
    local_port = t.dwLocalPort
    #get remote info
    ipaddr.s_un.s_addr = t.dwRemoteAddr
    remote_address = socket.inet_ntoa(ipaddr)
    remote_port = t.dwRemotePort
    #skip local
    if not (remote_address == "0.0.0.0" or  remote_address == "127.0.0.1") :
        #save current MIB_TCPROW
        connections_list[id] = t;
        #print some info about current MIB_TCPROW
        try:
            print "\t%d) link: %s -> %s" %(id, socket.gethostbyaddr(local_address)[0], socket.gethostbyaddr(remote_address)[0])
        except:
            print "\t%d) link: %s -> %s" %(id, socket.gethostbyaddr(local_address)[0], remote_address)
        id += 1
print "> ---"

val = int( raw_input("> connection to drop [0-%d]: " % (len(connections_list)-1)))
conn2drop = connections_list[val]
conn2drop.dwState = DROP
#SetTcpEntry
if iph.SetTcpEntry(byref(conn2drop)):
    print "[!] unable to drop selected connection id=%d (on Vista run as Admin)" % val
else:
    print "[*] bye bye connection id=%d" % val

Full source code here.

Have fun πŸ˜‰


Categories