Okay. Super late write up right here.
Anyway, as you, dear reader, may not be aware of, me and some friends participated in the Hack the Vote CTF 2016 this last November. I wasn’t able to work on the puzzles as much as I wanted to because of work obligations, but I was able to solve a really interesting reverse engineering problem that I think you might find interesting.
Reversing 100 (Consul)

As a greenhorn in the magnificent field of reverse engineering, this was the only one that I was able to manage in the short amount of time that the challenge was open, but it’s better than nothing I guess, and I believe that other greenhorns such as myself would learn very much from this very simple example of reverse engineering. And so, off we go!
Requirements
- REC Decompiler (a decompiler obviously)
- gdb (a debugger)
Process
- Download the ELF binary by clicking the “consul” link the description of the challenge and try running it. We want to be able to observe what the binary does normally before we break it down into tiny little pieces.

Sad - Nothing useful from there. Go ahead and decompile the ELF binary with the REC Decompiler, and then locate the main function.

- Alright. Now let’s look at the other interesting functions above the
mainfunction.




- These, aside from the main function, are the only ones whose names are not gibberish, so it may be possible that the solution to the problem might indeed be in one of these functions, but if you look at the main function again, it doesn’t seem to access any of the functions above.

- Luckily for us though, we can arbitrarily call functions from ELF binaries by using the wonderful tool called “gdb” – also known as the GNU Debugger. So just go pass the ELF as a parameter to the tool in question, and we’ll be doing the magic along the way.
- So, first, we’d want to be able to get a hold of the application in it’s initial state, so we are going to have to stop at the
mainfunction once the application execution gets there. To do this, just do abreak mainafter entering gdb in order to schedule the suspension of the application’s execution immediately after entering themainfunction, and then do arunto start the program’s execution.

- Now, let’s try calling some functions. You can arbitrarily call functions in the ELF binary using a really neat command called
call.

- Only
real_helpseems to work. I think it was trying to give people a clue. Something about the Fibonacci sequence, but I never really understood the purpose, and I was able to finish the challenge even while ignoring it. - Let’s just take a closer look at the other functions and see where they fail.
- Let’s do the
dont_call_mefunction first. Since we already called the other functions, let’s start gdb again and call thedont_call_mefunction so we’d avoid any of the possible unintended modifications that the other functions may have made to the environment when we tested them previously.

- The
dont_call_mefunction failed as expected. By observing the back trace using thebtcommand, we can see that the program stopped inside a function that is inside thesub_41F2function. Now, thesub_41F2function only contains a handful of calls to other functions, so it would only be one of the following.

- Let’s see if it’s the
strlenfunction. To check, simply add abreaktostrlenand then call thesub_41F2function.


- As you see, the program stopped at the start of
strlen. We then entered thefinishcommand so that the program would execute until thestrlenfunction finished. There doesn’t seem to have been any problems with thestrlenfunction because the segmentation fault occurred AFTER it finished (as indicated by the segmentation fault message). That means, the problem occurs either on them0function, or the otherstrlenfunction. - Let’s check the
m0function next. As you can see in the code below,m0is actually a variable meant to contain a pointer to a function which is supposed to be called on the*m0();line below.

- However, upon inspecting the contents of the
m0variable using thepcommand, it seems that it contains a reference toNULLso naturally the program WILL throw a segmentation fault for attempting to callNULLas a function.

- A quick search in the source code reveals that the
m0variable is initialised inside thec55function.

- However, the
c55function is never actually called anywhere and directly calling thec55function causes and infinite loop.

- Let’s restart gdb to get rid of the breakpoints and then let’s try setting the
m0variable directly.

- Now let’s try calling the
dont_call_mefunction again.

- Looks like it’s still broken. Buuuuuuut… look carefully at the decompiled code. There’s another
mallocfunction there residing on a different address. This might be themallocfunction that’s being set to them0variable.

- Now let’s set
m0to that address. Good thing the decompiler outputs the addresses of decompiled functions (as indicated in the comment below the declaration of themallocfunction).

- Now let’s call
dont_call_mefunction again.
- >mfw

MOM, GET THE CAMERA! #MLG #360NOSCOPE #GITREKT - It works. But there doesn’t seem to be anything useful in the
dont_call_mefunction. Let’s try the other functions.

Illuminati Confirmed? [Insert X-Files Theme Music] - It seems the other functions started working once we set the
m0variable to the right value. Now search form0in the source code and you will find that the functions that referencem0aresub_41F2,sub_9F36, andsub_198A. The functions that, in turn, reference these functions aredont_call_me,help,c8, andfake_help. We haven’t triedc8yet, so we just might find the answer there.
What’s that? “Jet fuel can’t melt steel beams”? - Gibberish. But to be sure, let’s do it again.

“Harambe was an inside job”? - Different gibberish. I wonder what will happen if we keep doing it over and over again.

“Lizard people are running the White House”!? - Suddenly… [insert x-files theme music]

The plot thickens… - That’s not the flag though. We need to go deeper.

Voila! - And finally, we have our flag, which is
flag{write_in_bernie!}.
And that’s it for now folks. I hope you enjoyed this CTF write up despite it being a month late. I surely did enjoy writing it. Anyway, if you need the binary and the decompiled source code, I have attached them onto the section below.