Fusion 5

Good day guys, Today we will work on Fusion 5. As far as I know, the only other solution for it online was done by my friend Ariel Koren in his blog. Ariel and myself have worked on it in the same time, and what is so cool in this field is that our solutions are completely different from one another. After you are done with reading my solution, go check out his solution to see different way to solve the same problems 🙂

The challenge ahead

Beautiful picture to get you to keep reading

As with the previews levels of this Fusion series, again we are faced with a server that receives connections, and again we need to find and exploit a few bugs in order to get a working Remote-Code-Execution (RCE). Again we face Position Independent Executable (PIE), Address Space Layout Randomization (ASLR), none-executable-stack and heap, and source fortification.

After reading the source, we know that we are dealing with a server that has 5 commands, we will have to find a bug in at least one of them in order to get our RCE. The commands are:

addreg - Registers a server in the dbsenddb - Sends the db to a chosen host and portcheckname - recives a server name and tells if it is indexed in the dbquit - Ends the session of our connectionisup - Tries to connect to all of the hosts in the db
sends each of them its db entry.

Each of those commands is executable by a “task” we know that because we see reference to the function “taskcreate” in the source. This is really bad news, for anyone who doesn’t know what is a task. I can tell that the definition is kinda fuzzy but usually when someone talks about tasks they mean user-mode-thread. If it is the case in here, we should know that:

Every task has its own stack.

All of the tasks share the same address space.

If we crash one task the whole program will crash.

If we are right about how the program works with tasks, After we will find a buffer overflow and crash the program, Our work will be 100 times harder than in the previews challenges in this series. Spoiler-alert, the internet is filled with solutions to Fusion:0, 1 ,2 ,3 ,4. Not for Fusion 5. But we are getting ahead of our selves.

Writing a working client

I write my client which is quit simple, I pulled my hair about why I don’t get response from this line:

printf("registration added successfully");

I connected with a debugger and made sure my input for addreg is working, and the printf is being called (It is optimized into puts). and then I saw

Which teaches us that we are not getting the output of stdout. That makes sense because the server supports multiple clients on the same process. And file descriptors are unique per process.

It is kind of working and I move on to search for the buffer overflow.

The Buffer overflow

After carefully reading the source I noticed he function senddb. The passes over all of the lines in the database (actually array of structregistrations) copies all of the non-empty entries in this array to a buffer and sends the buffer to a given server. What was weird in my eyes is that the buffer is in the size of 512 bytes, while every entry in the array is 6 bytes. 512 is not divisible by 6 (because it is not divisible by 3). which means something here is fishy. multiplying the size of the database (128) by the size of each entry(6) gives us 768 bytes. which means that we can overflow our buffer by 256 bytes. This should be pretty good. now let’s see how can we control the data in this array.

In order to add an entry into the array, we need to use the addreg command. This command receives a host name, ip and flags (short number), and adds this name into the database with its flags, the index in the database that would be used for this entry is a hash that is calculated on the host name. After thinking about it, we can “break” the hash by implementing the hash function in python, and finding a suitable name for every entry in the hash table (Simply by brute-forcing names.)

I did it, and now I can make sure the database struct is full with whatever I want in every index. This way I can control the data that I overwrite the struct with and I even managed to crash the program.

But, considering it more carefully, I can’t really write what every I want into this struct (and later the stack overflow) because of those 2 line inside addreg function:

it means that if the flags part of the entry can not have any bit that are not in 0x00e0 on. At first I thought I can maybe work out something with it, but it really complicates my work. basically it means I really control only 4 out of every 6 bytes of the overflow. After I banged my head against the wall trying to think of how do I continue from here.

On one hand, the previous levels all had some kind of pseudo-cryptographoic challenge. So it makes sense that I need to use this trick with the hash table. On the other hand, we don’t have the address of the main binary, we don’t have the address of libc- or any other lib for that matter. We don’t have the stack address, and we can’t brute-force address because the program will crash and that’s it.

Fuck it, We need another buffer overflow

We go back to the source code, and we try to find another buffer overflow. We find out that the function get_and_hash receives a buffer, max_size for that buffer and a separator. it copies the buffer into a local stack buffer until reaching the separator, but without considering max_size. Well max_size is only tested to make sure its not bigger than the length of the local buffer. The input buffer is not validated against max_size. As if the function assumes that no one will pass a buffer longer than max_size. Guess who passed a buffer longer than max size? That’s right, I did 🙂

This function is called from the command checkname on the name to be checked and returns a hash for this name. Unless of course we overflow it. I call this function from the main in my client while being connected with the debugger:

One Reply to “Fusion 5”

Post navigation

About Me

Hey, my name is Nadav Claude Cohen and this is my blog. Around here you can read some of my thoughts and work in the information security field. I am currently working as a Team Lead at ACE labs. Feel free to follow me on twitter.