Eulerian Tour

Standard

I suck at algorithms. Discrete math in general actually :) But you know, it’s working outside of your comfort zone what makes you progress, so I’m taking Udacity’s course on Algorithms.

One of the first assignments is to find an algorithm to find an eulerian tour and implement in Python. An eulerian tour is path that begins and ends on the same node of a graph and traverses all edges only once.

Well, is one of the first problems, so how difficult can it be, right?

After several notebook pages it turned out to be not that trivial (at least to me). I think I worked on it for a week and tried several different approaches “this can be solved using depth first search for sure…”, “maybe some recursion will help…”

Come on, it can't be that difficult

This is… madness!

Some approaches worked for simple graphs but failed when tested against bigger ones (20 nodes or so).

Then I thought again about the conditions a graph must fulfill in order to have an eulerian path: it must be connected and all the nodes must have even degree

I realised that this would happen if you construct a graph fusing several single loops together. The nodes belonging to only one single loop will have degree 2 (one in, one out), the nodes pertaining to two loops will have degree 4 (twice in and out), etc. In general the degree of a node is 2 * N (where N is the number of single loops it belongs to)

So i decided to write an iterative algorithm that looks for a single loop (A -> B -> C -> A), saves it, removes it from the graph, then looks for another loop on the remaining graph and so on. Until the graph is null, that is, no edges present.

Afterwards is just a matter (tricky code, though) of “piercing” the loops together by their common nodes.

The code is here:

# Find Eulerian Tour
#
# Write a function that takes in a graph
# represented as a list of tuples
# and return a list of nodes that
# you would follow on an Eulerian Tour
#
# For example, if the input graph was
# [(1, 2), (2, 3), (3, 1)]
# A possible Eulerian tour would be [1, 2, 3, 1]

################################################################
# Auxiliary
################################################################    

def get_degrees(edge_list):
    ''' This returns a dictionary of 
        nodes and their degrees '''

    degrees = dict()    
    for u, v in edge_list:
        degrees[u] = degrees.get(u, 0) + 1
        degrees[v] = degrees.get(v, 0) + 1

    return degrees

def get_highest_degree_node(edge_list):
    degrees =  get_degrees(edge_list)
    sorted_degrees = sorted(degrees, key = lambda k: degrees[k], reverse = True)

    return sorted_degrees[0]

def get_branches(edge_list, node):
    ''' Returns all nodes reachable from a node '''
    branches = []
    for u, v in edge_list:
        if u == node:
            branches.append(v)
        elif v == node:
            branches.append(u)
        else:
            pass

    degrees = get_degrees(edge_list)

    # Sort this by ascending degree
    # Meaning: lower degree nodes get visited earlier        
    return sorted(branches, key = lambda k: degrees[k])

def remove_branch(edge_list, current_node, branch):
    # Remove the branch, since it has been traversed already
    if ((current_node, branch)) in edge_list:
        edge_list.remove((current_node, branch))
    elif ((branch, current_node)) in edge_list:
        edge_list.remove((branch, current_node))
    else:
        pass

    return edge_list

def next_node(current_node, edge_list):
    ''' I don't need anything else 
        * where I am 
        * what is left unexplored 
        @return: new node '''

    branches = get_branches(edge_list, current_node)
    if branches != []:
        branch = branches[0]
        edge_list = remove_branch(edge_list, current_node, branch)
        return branch
    else:
        return None

def fusion_loop(original_list, element, new_element):
    ''' It fuses two loops by a common element '''
    idx = original_list.index(element)
    left = original_list[:idx]
    right = original_list[idx + 1:]

    new_list = left + new_element + right

    return new_list

def rotate_around(original_list, element):
    ''' It cycles the list so the cycle starts at element '''
    idx = original_list.index(element)
    if idx == 0:
        return original_list
    else:
        return original_list[idx:] + original_list[1:idx] + [element]

def find_common_element(list1, list2):
    ''' Returns the FIRST OCURRENCE of a common element '''
    for e1 in list1:
        if e1 in list2:
            return e1

    return None

################################################################
# The algorithm itself
################################################################

def find_eulerian_tour(edge_list, loops_list = []):

    while edge_list != []:

        branch = None    
        current_node = get_highest_degree_node(edge_list)
        nodes_visited = [current_node]

        print "\nStarting in node %d (degree: %d)..." % (current_node, get_degrees(edge_list)[current_node])

        while branch != nodes_visited[0]:
            branch = next_node(current_node, edge_list)
            nodes_visited.append(branch)
            current_node = branch

        loops_list.append(nodes_visited)

    ########################################################
    # Post-processing of loops_list
    print "loops_list:", loops_list
    eulerian_tour = loops_list[0] # kind of arbitrary
    loops_list.remove(loops_list[0])

    while loops_list != []:
        for loop in loops_list:
            common_node = find_common_element(eulerian_tour, loop)
            if common_node:
                cycled_loop = rotate_around(loop, common_node)
                eulerian_tour = fusion_loop(eulerian_tour, common_node, cycled_loop)
                loops_list.remove(loop)
                print "* eulerian_tour:", eulerian_tour

    return eulerian_tour

################################################################
# Tests
################################################################
def test(my_graph):
    print my_graph, "len:", len(my_graph)
    my_eulerian_tour =  find_eulerian_tour(my_graph)
    print my_eulerian_tour, "length:", len(my_eulerian_tour)

test([(1, 2), (2, 3), (3, 4), (4, 1), (2, 5), (5, 2)])
test([(1, 2), (2, 3), (3, 4), (4, 1), (2, 5), (5, 4), (4, 2)])    
test([(0, 1), (1, 5), (1, 7), (4, 5), (4, 8), (1, 6), (3, 7), (5, 9), (2, 4), (0, 4), (2, 5), (3, 6), (8, 9)])
test([(1, 13), (1, 6), (6, 11), (3, 13), (8, 13), (0, 6), (8, 9),(5, 9), (2, 6), (6, 10), (7, 9), (1, 12), (4, 12), (5, 14), (0, 1),  (2, 3), (4, 11), (6, 9), (7, 14), (10, 13)])
test([(8, 16), (8, 18), (16, 17), (18, 19), (3, 17), (13, 17), (5, 13),(3, 4), (0, 18), (3, 14), (11, 14), (1, 8), (1, 9), (4, 12), (2, 19),(1, 10), (7, 9), (13, 15), (6, 12), (0, 1), (2, 11), (3, 18), (5, 6), (7, 15), (8, 13), (10, 17)])

The walking 0xDEAD

Standard

TitleSlide

I thought about opening this post writing “Sorry I haven’t posted in a long time…” Then I realized most probably nobody cares, so I didn’t.

tl;dr: Binary reverse engineering and zombies. Success is guaranteed :)

Recently I got through a friend the opportunity of presenting a short (one day) training involving binary reverse engineering and some malware analysis. Since I’ve been thinking about putting together this kind of training for a while, I thought it would be a great opportunity to create a raw version and get a first round of valuable feedback.

As I mentioned, due to time constraints mainly, the slides are a bit on top of each other and it’s very rough around the edges. I’ll have to work out some kinks in next versions and if you are an experienced reverser, I’m sure you will spot a couple of embarrasing mistakes…

That said, the training went pretty well. Although some people had only a first knowledge of the topic (well, that’s why you go to a training, isn’t it?) they were, luckily for me, very competent people. They were actually absorbing information at an alarming rate!

There was a complementary software package that had to be installed in a VM to be able to follow along and spend some time with a couple of short exercises. At the end two malware samples were analyzed and typical tricks used by malicious code were presented. Along the lines “If you see this and that, be pretty sure this software is up to no good…”

Without the software package or the proper explanation the slides are sometimes difficult to follow but anyway they look nice :P

NOTE: I realize that I may have broken all kind of copyrights, past, present and future but since there was no financial profit involved and this is for the community, I’m sure the people of AMC will find room in their hearts to forgive me.

NOTE2: I tried to give proper credit where I took something from the internet. If it’s not on the slide self, it’s on the related code on the software package. If not, I just forgot and I’m a jerk. Drop me a line and I’ll add it.

I know, less talking and more showing the slides. They are here: The Walking 0xDEAD slides

Show me your IoCtlCodes!

Standard

tl;dr: If you want to get a list of valid IoCtlCodes reverse the binaries that talk to the driver from userspace.

Knock, Knock. This is userspace.

In a nutshell, programs that install drivers on your OS (let’s say AV, packet sniffers, etc.) install userland software as well. This software needs to talk to the driver (in kernel space). The glue allowing those two programs, living in different worlds, to talk to each other is implemented via the DeviceIoControl API.

BOOL WINAPI DeviceIoControl(
  _In_         HANDLE hDevice,
  _In_         DWORD dwIoControlCode,
  _In_opt_     LPVOID lpInBuffer,
  _In_         DWORD nInBufferSize,
  _Out_opt_    LPVOID lpOutBuffer,
  _In_         DWORD nOutBufferSize,
  _Out_opt_    LPDWORD lpBytesReturned,
  _Inout_opt_  LPOVERLAPPED lpOverlapped
);

This is pretty easy, just open a handle to the device from userland, call the function with this handle and a couple of buffers: one for the input data, an0ther for the output one.

Sounds easy, doesn’t it? Well, not that fast. There are a couple of issues here…

One of them is the IoControlCode. What the hell is that?

Think about this like a network port, something that allows you to multiplex. So you sent data to a driver, but how does it know what it was intended for? I mean, a driver is a complex piece of software, sure it can do more than one thing with the data in your buffer!

Now, if you checked carefully the DeviceIoControl declaration, you have notice that this number is 32bits long. It goes without saying, is going to be difficult to try random values and hope you got the correct one. It’s necessary to get a list of valid codes somehow.

This is rather easy if you have the binaries of the userland application. Just look for calls to DeviceIoControl and read the second parameter. As you will see sometimes this would be an indirect reference (like for example, “edx”) but anyway is a good way to get an initial list very quickly.

With this in mind, a first version of an IDA Pro script implementing exactly this could be:

# Find the IoControlCodes corresponding to
# calls to DeviceIOControl within a binary

from idaapi import *
from idautils import *
from idc import *

##########################################################
# This class implements a fifo queue
class fqueue(list):
	def __init__(self, n):
		self.n = n

	def push(self, a):
		self.append(a)
		if len(self) > self.n:
			self.pop(0)

##########################################################

gpRegList = ['eax', 'ebx', 'ecx', 'edx']
ioccList = []
callerList = []
pushQueue = fqueue(2)

dioc_ea = LocByName("DeviceIoControl") # EA

print "DeviceIoControl found at 0x%08x" % dioc_ea

for caller in XrefsTo(dioc_ea, True):
	# This is the address (within a function)
	# where the reference was made
	caller_ea = caller.frm

	if caller_ea not in callerList:
		# IDA Pro shifts duplicates, get rid of them
		callerList.append(caller_ea)
		print "xref @ 0x%08x (%s)" % (caller_ea, GetFunctionName(caller_ea))
	else:
		continue

	# The dwIoControlCode must be the second 
	# PUSH xxx before the CALL instruction
	# So we need to keep track of the PUSH instructions
	for ins in FuncItems(caller_ea):
		disasm = GetDisasm(ins)
		if "push" in disasm:
			# Save the PUSH instruction's operand
			pushQueue.push(GetOpnd(ins, 0))
		elif ins == caller_ea:
			# At this moment we hit the corresponding CALL instruction
			# First item in Queue is second "oldest" push
			iocc = pushQueue[0]

			if iocc in gpRegList:
				print "NOTE: IoControlCode was %s at 0x%08x. Check manually" % (iocc, caller_ea)
			else:
				if pushQueue[0] not in ioccList:
					ioccList.append(pushQueue[0])
		else:
			pass

# Print all the gathered IoControlCodes

print "%d IoControlCodes found!" % len(ioccList)

for io in ioccList:
	print "[*]", io

delivering such output:

DeviceIoControl found at 0x650320e4
xref @ 0x6500c19a (AavmDetectionsHaveChanged)
xref @ 0x6500c30b (sub_6500C220)
xref @ 0x6500c62b (sub_6500C220)
xref @ 0x6500c945 (sub_6500C220)
xref @ 0x6500caff (sub_6500CA80)
xref @ 0x6500cc03 (sub_6500CA80)
xref @ 0x6500cc5e (sub_6500CA80)
xref @ 0x6500ccd8 (sub_6500CA80)
xref @ 0x6500cd03 (sub_6500CA80)
xref @ 0x6500cf20 (sub_6500CE90)
xref @ 0x6500cfb1 (sub_6500CE90)
xref @ 0x6500f823 (AavmStart)
xref @ 0x650102bf (AavmStop)
xref @ 0x65016a30 (sub_65016900)
xref @ 0x650274fb (sub_65027480)
xref @ 0×65027792 (sub_65027480)
xref @ 0x6502797d (sub_65027850)
xref @ 0x65027e92 (sub_65027E70)
xref @ 0x65027f67 (sub_65027EA0)
xref @ 0x65029f16 (sub_65029EF0)
NOTE: IoControlCode was edx at 0x65029f16. Check manually
xref @ 0x65029fd1 (sub_65029F40)
xref @ 0x6502a0af (sub_6502A030)
xref @ 0x6502a1d5 (sub_6502A0E0)
xref @ 0x6502a4fb (sub_6502A430)
xref @ 0x6502a6a7 (sub_6502A610)
xref @ 0x6502a7bb (sub_6502A6E0)
xref @ 0x6502fba2 (sub_6502FB70)
xref @ 0x6502fbf3 (sub_6502FBC0)
19 IoControlCodes found!
[*] 0B2C88028h
[*] 0B2D60030h
[*] 0B2D60034h
[*] 0B2D60028h
[*] 0B2D6002Ch
[*] 0B2D60014h
[*] 0B2D6001Ch
[*] 0B2D6000Ch
[*] 0B2D600A4h
[*] 0B2D600B4h
[*] 0B2D600C0h
[*] 0B2D600B8h
[*] 82AC805Ch
[*] 82AC0050h
[*] 82AC0054h
[*] 82AC8120h
[*] 82AC8214h
[*] 82AC8218h
[*] 80002008h

Excellent. Now the following problem arises. Which is the name of the device(s) I need to get a handle for? And in the probable case there are more than one… which IoControlCodes correspond to which devices?

But now is time for breakfast, so this is left for an update, should I find a way to automate it :)

Detecting VMWare

Standard

Disclaimer: I guess this is an old trick, but anyway…

I am learning some malware analysis using the *awesome* “Practical Malware Analysis” book from Michael Sikorski and Andrew Honig.

In case you haven’t done it already… go and buy it right now! (http://nostarch.com/malware). You won’t regret it :)

One cool thing about this book is the amount of exercises left to the reader, “practical” remember?

What takes me to the point of this brief post. At the end of chapter 0×05 we have to analyze a malicious DLL. One of the questions ask us to find the occurrence of the x86 ASM instruction “in” (0xED). This is used to read data from a port and one of the parameters is a magic number which serves as an identifier for that specific port.

In this particular case the “magic number” is 0x564D5868 (VMXh in ASCII). Apparently this is only present on VMWare systems and therefore can be used to check if we are running inside a VMWare machine. This is very important for malware developers since they don’t want to run inside malware analyst machines, for obvious reasons…

The code can be found within this function, which I conveniently renamed to cgp_checkVMWARE:

As you can see, the register ebx is initialized to zero and the magic number gets loaded into edx. After the “in” instruction gets executed the register ebx must be overwritten with the magic number value if it successfully connected to the port (that is, we are inside VMWare).

I found this trick really neat so I wanted to write a small program that performs exactly this check. But since I don’t understand exactly what is happening and I don’t know how to query the port from C using the Windows API… I took the shortest path.

It’s obvious that this malware is performing this check successfully so why don’t canibalize this code?

My first idea was to write a small C skeleton and embed this assembly, something like this:

#include <stdio.h>

int
main(int argc, char* argv[])
{
unsigned int vm_flag = 1;

/* The check will set the VM Flag to ZERO if successful */

__asm
{
mov eax, 0x564D5868 ; ascii: VMXh
mov edx, 0×5658 ; ascii: VX (port)
in eax, dx ; input from Port
cmp ebx, 0x564D5868 ; ascii: VMXh
setz ecx ; if successful -> flag = 0
mov vm_flag, ecx
}

if(vm_flag == 0)
printf(“Inside VMWARE!!! 8-X\n”);
else
printf(“VMWARE environment NOT detected\n”);
return 0;
}

It compiled fine but to my surprise it crashed in my laptop (native Win7, outside VMWare).

Hmmmm… maybe I did something wrong… So I fired up Immunity Debugger and traced the code. The problem was by the execution of the “in eax, dx” instruction and the exception was “0xC0000096: Privileged Instruction“.

Apparently the OS doesn’t like that Ring-3 code (user code) tries to access the hardware directly :)

But how does this work for the malware? Easy, I just needed to open my eyes and look what the function does before executing the forementioned code:

It is setting a SEH frame and registering a handler. Check Wikipedia for information about what lies at fs:[0]

This exception is expected to happen outside VMWare and therefore there is code to handle it. So could it be that easy? It turns out it can ;)

The modified code, with a {__try, __except} block to catch the exception is this:

#include <stdio.h>
#include <windows.h>
#define OOPS_PRIVILEGED_INSTRUCTION 0xC0000096
int
main(int argc, char* argv[])
{
unsigned int vm_flag = 1;

/* The check will set the VM Flag to ZERO if successful */

__try
{
__asm
{
mov eax, 0x564D5868 ; ascii: VMXh
mov edx, 0×5658 ; ascii: VX (port)
in eax, dx ; input from Port
cmp ebx, 0x564D5868 ; ascii: VMXh
setz ecx ; if successful -> flag = 0
mov vm_flag, ecx
}

if(vm_flag == 0)
printf(“Inside VMWARE!!! 8-X\n”);
}
__except(GetExceptionCode() == OOPS_PRIVILEGED_INSTRUCTION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
printf(“VMWARE environment NOT detected\n”);
}
return 0;
}

It works as expected, here is an screenshot of it running natively in my laptop (Win7) and within VirtualBox.

And here a screenshot of the program detecting VMWare Player 5 in this case.

It is straightforward to compile this code using Visual Studio but anyway here is the executable.

NOTE: WordPress doesn’t allow to upload .zip files so I change the extension to .pdf, just change it back to .zip and you are good to go! ;)

checkVM.zip

“How I met your pointer” (the hidden slides)

Standard

This is the (extended) presentation I gave at BruCON 2012 in Gent.

How I Met Your Pointer (the hidden slides)

It contains a couple of slides that I had to hide due to time constraints but essentially is the same thing. It looks sometimes funny in PDF because you can’t see the animations…

Anyway the videos will be released shortly I guess and then everything will make sense :)

 

I hope you enjoy it!

BruCON 2012

Standard

In a couple of weeks I’ll be at BruCON (Gent, Belgium) enjoying some talks, meeting interesting people and partying at Sioux (Nerdcore FTW!). Ah, and I will be giving a talk as well ;)

Since I got an unfortunate slot (yes, that’s me right at the end :)) I thought it would be a good idea to give a short sneak peek. This way you can better decide if this is something of interest for you or you want to hit the road instead.

The talk is called “How I met your pointer. Hijacking client software for fuzz and profit”.

An approach to the problem of fuzzing proprietary protocols will be shown, focusing on network protocols and native software (you know, the stuff that is neither an android/iphone app nor a web one).

The main idea behind it is very simple: “in a client/server architecture, the client knows how the protocol works.”

In the course of this talk I will need to combine several methods in order to force the client software to work as a “double agent” against the server. Since several topics will be touched, several people can pick a couple of ideas here and there maybe.

 

All the code for the presentation will be available online and there will be a demo experiment as well showing how to abuse a  contrived program I wrote for the purpose.

 

All in all, it will be an interesting and entertaining talk (with maybe a culinary surprise too :P).

 

I hope to see you there.

 

P.S. The topic can be a little dry for people that haven’t had previous contact with it so I like to do all my presentations as dynamic as possible and very “colourful”. I’ll let here a couple of slides so you get the look and feel ;)

Small and Cute Execution Tracer

Standard

A couple of months ago I wrote a small tool to help me find the functions hit during the execution of an arbitrary program. It became obvious that with some small modifications it could be used to perform differential debugging, analog to what Zynamics BinNavi does. This little tool is based on the awesome WinAppDbg from Mario Vilas, a Python interface to the Windows Debugging API.

After developing a little bit more than initially intended, it turned out pretty nice so I decided to write about it. Maybe it could be useful to somebody.

The following screenshot shows the options available:

Here are a couple of things you can do with it:

Differential Debugging

Generating some noise

s:\> python Tracer.py –noise -p putty.exe -f putty_exported_functions.txt

The option (-p, –program) is mandatory in every case and references the name of the executable to analyze. No path is necessary, only the program’s name.

The options (-n, –noise) and (-s, –signal) are the most relevant for this mode. They do esentially the same, that is, logging the functions hit during execution to a file. The only difference is which file they log to, signal.txt or noise.txt.

Now, the (-f, –funcfile) parameter refers to a file containing all the program’s function addresses. In order to instrument every function and log whether it has been hit it’s necessary to know the function addresses beforehand. This is obviously the main drawback of this technique. There are more sophisticated methods involving DBI but this is not the topic right now.

How to get this list of function addresses? Well, IDA Pro comes to the rescue!

Open the executable in IDA Pro and once the initial autoanalysis is finished, run the following Python code:

filename = idc.AskFile(1, "*.*", "File to export functions to?")

f = open(filename, "w")
print "Exporting function addresses to %s\n" % filename

idx = 0

# The string format is:
# 0xAAAAAAAA-0xBBBBBBBB {ea_start, ea_end}

for function_start in Functions():
    function_end = GetFunctionAttr(function_start, FUNCATTR_END)
    # Below I've just stripped the leading '0x' chars
    addr_interval_string = str(hex(function_start)).split('0x')[1] + '-' + str(hex(function_end)).split('0x')[1]

    f.write(addr_interval_string + '\n')
    idx += 1

f.close()

print "%d functions written to disk" % idx

You can save this to a file and execute the script within IDA with “File/Script File” or Alt+F7. This will generate a text file with all the function addresses, ready to be processed by Tracer.py

Now the signal

Let’s generate another file containing the addresses of interesting functions. Remember that in this context, interesting means “responsible for a feature we are interested in”, for example “which functions are being executed when I click this button?”.

Similarly to the last paragraph:

s:\> python Tracer.py –signal -p putty.exe -f putty_exported_functions.txt

Of course the output file (signal.txt) will contain the interesting functions along with several others implementing all kinds of irrelevant functionality (initialization, GUI stuff, etc.) How are we going to filter out these? Very easily.

Filtering out the noise

Although doing this is about ten lines of python, there’s another very convenient switch (-c, –compare):

s:\> python Tracer.py -c

Execute this on the same directory as the previous noise.txt and signal.txt since by default the program will look for these two and write the output to specific_functions.txt

And here you are! It was rather easy, wasn’t it?

It’s not a bullet-proof method but it can be useful in some situations. For a nice example check this other post.

Another goodies

I plan to extend this tool with a couple of other useful options, one of them the ability of dereference arguments during function calls and look for specific ASCII strings. The syntaxis is as follows:

s:\>python Tracer.py -a -w string_to_look_for -p putty.exe -f file_with_func_addresses

The two new parameters are (-a, –argument) which indicates I want to trace and dereference addresses instead of the normal mode. The parameter (-w, –search_pattern) specify the ASCII string to look for.

Check this screenshot where I look for a certain username being used as argument:

The method is far from perfect. Since I don’t know how many arguments each function has I just dereference the first 5 DWORDS on the stack after the saved EIP.

Clumsy and prone to false positives but it could point you in the right direction during an initial analysis.

A way to improve this is to export the number/type of arguments in IDA Pro and use this info to better target our search . It’s on my TODO :)

Do you want to play?

In case you want to play with it, you will need the following:

  • WinAppDbg 1.4 (downloadable here)
  • Python (I tested it with 2.5 and 2.7 under Windows)
  • The code for Tracer.py itself! (download from GitHub)

Have fun!