Tags: movfuscated reverse re 


# future_fun

Let's take a look at the binary we are given:

$ file future_fun
future_fun: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, not stripped
$ ./future_fun
Give the key, if you think you are worthy.


### Movfuscation

So we are dealing with a 32 bit crackme here. When we take a look at the assembly code, something becomes very apparent:

.text:080491BB mov dl, byte ptr alu_s+3
.text:080491C1 mov al, alu_true[edx+eax]
.text:080491C8 mov al, byte ptr alu_false[eax]
.text:080491CE mov byte ptr dword_81FD210, al
.text:080491D3 mov edx, offset alu_cmp_of
.text:080491D8 mov al, byte ptr alu_x+3
.text:080491DD mov eax, alu_b7[eax*4]
.text:080491E4 mov edx, [edx+eax*4]
.text:080491E7 mov al, byte ptr alu_y+3
.text:080491EC mov eax, alu_b7[eax*4]
.text:080491F3 mov edx, [edx+eax*4]
.text:080491F6 mov al, byte ptr alu_s+3
.text:080491FB mov eax, alu_b7[eax*4]
.text:08049202 mov edx, [edx+eax*4]
.text:08049205 mov edx, [edx]
.text:08049207 mov byte ptr dword_81FD218, dl
.text:0804920D mov eax, dword_81FD210
.text:08049212 mov eax, alu_false[eax*4]
.text:08049219 mov b0, eax
.text:0804921E mov eax, b0
.text:08049223 mov edx, on
.text:08049229 mov eax, and[eax*4]
.text:08049230 mov eax, [eax+edx*4]
.text:08049233 mov b0, eax
.text:08049238 mov eax, b0
.text:0804923D mov eax, sel_target[eax*4]
.text:08049244 mov edx, branch_temp
.text:0804924A mov [eax], edx
.text:0804924C mov ecx, b0
.text:08049252 mov data_p, offset jmp_r0
.text:0804925C mov eax, sel_data[ecx*4]
.text:08049263 mov edx, R0

This code has been obfuscated using movfuscator (https://github.com/xoreaxeaxeax/movfuscator ). Movfuscator is a compiler that basically only uses the `mov` instruction. As such reversing this become really fun.

Starting off I used demovfuscator on it (you can find it here https://github.com/kirschju/demovfuscator). It can do a couple of things. The first is it can create a graph roughly showing the code flow of the binary. The second is it can generate an elf that replaces some of the `mov` instructions with other instructions that are typically used, which makes it a bit easier to reverse.

To use it (after you compile it):
$ ./demov -g graph.dot -o patched future_fun

Now since the file `graph.dot` is essentially a text file containing information on a graph, we will have to use `dot` to actually draw it for us:

$ cat graph.dot | dot -Tpng > graph.png

In this case I didn't find the graph to be too helpful. However the patched binary it gave us helped me out alot. Mainly because it patched certain `call` instructions back in which helped finding out where it branched.

Now looking over the list of functions this binary has, `check_input` sounds like the most important function. Using the patched binary, we can just search for the call function to `check_input` and see that it is at `0x08051986`:

gef➤ b *0x8051986
Breakpoint 1 at 0x8051986
gef➤ r
Starting program: /home/guyinatuxedo/demovfuscator/patched
Give the key, if you think you are worthy.


. . .

────────────────────────────────────────────────────────────────────────────── stack ────
0x085fd220│+0x0000: 0x00000071 ("q"?) ← $esp
0x085fd224│+0x0004: 0x00000066 ("f"?)
0x085fd228│+0x0008: <stack+2097032> sbb eax, 0x66000000
0x085fd22c│+0x000c: "flag{15935728}"
0x085fd230│+0x0010: "{15935728}"
0x085fd234│+0x0014: "35728}"
0x085fd238│+0x0018: 0x000a7d38 ("8}"?)
0x085fd23c│+0x001c: <stack+2097052> add BYTE PTR [eax], al
──────────────────────────────────────────────────────────────────────── code:x86:32 ────
0x8051978 <main+5646> mov eax, DWORD PTR [eax*4+0x83fd270]
0x805197f <main+5653> mov esp, DWORD PTR ds:0x83fd250
0x8051985 <main+5659> pop eax
→ 0x8051986 <main+5660> call 0x804896e <check_element+474>
↳ 0x804896e <check_element+474> mov eax, ds:0x83fd254
0x8048973 <check_element+479> mov ds:0x81fd230, eax
0x8048978 <check_element+484> mov eax, 0x83fd250
0x804897d <check_element+489> mov edx, 0x1
0x8048982 <check_element+494> nop
0x8048983 <check_element+495> mov ds:0x83fd294, eax
──────────────────────────────────────────────────────────────── arguments (guessed) ────
check_element+474 (
──────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "patched", stopped, reason: BREAKPOINT
────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x8051986 → main()

So we can see that it takes the two characters as an argument `q` and `f`, which one of them we gave as part of input. Turns out the first couple of characters are `flag{` (since it follows the standard flag format). We see that it is checking the characters of our input one by one, and if a character isn't correct then the program exits and stops checking characters. In addition to that we can see with the first couple of characters that we got, the string that our input is being compared to (after it is ran through some algorithm) is `qshr�r77kj{o8yr<jq7}j�;8{pyr�` (29 characters long).

Now instead of going through and statically reversing this, we can just use a side channel attack using Perf.

### Perf

Perf is a performance analyzer for linux, that can tell you a lot of information on processes that run. We will use it (specifically perf stat) to do instruction counting. Essentially we will count the number of instructions that the binary has ran to help determine if we gave it a correct character. If we gave it a correct character, then it should run through the `chec_element` function again and thus have a higher instruction count than all other characters we tried. However there are some things happening in the background that can affect this count, so it's not always 100% accurate. However what we can do is check the sequence of characters that it gives us via seeing how many checks it passes with gdb, and add the correct characters to the input. If it starts spitting out wrong characters then we will just restart the script which brute forces it.

Let's take a look at how perf runs:

$ perf stat -x : -e instructions:u ./future_fun
Give the key, if you think you are worthy.


Here we can see that it executed `5201320` instructions. Let's break down the command:

perf stat Specify that we are using perf stat
-x Specify that we want out output in CSV format
-e Specify that we are going to be monitoring events
instructions:u Specify that we are going to be monitoring userland instruction events
./future_fun Process that we will be anaylyzing

Now we can just throw together a little script to do the brute forcing. This script I got from one of my other writeups that is based off of https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html:
#Import the libraries
from subprocess import *
import string
import sys

#Establish the command to count the number of instructions
command = "perf stat -x : -e instructions:u " + sys.argv[1] + " 1>/dev/null"
flag = 'flag{'
while True:
ins_count = 0
count_chr = ''
for i in (string.lowercase + string.digits):
target = Popen(command, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=True)
target_output, _ = target.communicate(input='%s\n'%(flag + i))
instructions = int(target_output.split(':')[4])
#print hex(instructions)
if instructions > ins_count:
count_chr = i
ins_count = instructions
flag += count_chr
print flag

when we run it:
$ python rev.py ./future_fun

In this case, it gave us the valid letters `g00d` before selecting an incorrect character. However we can just append those characters to our input and start over. After a little bit, we get the full flag `flag{g00d_th1ng5_f0r_w41ting}`.

$ ./future_fun
Give the key, if you think you are worthy.

Good job!

Original writeup (https://github.com/guyinatuxedo/ctf/tree/master/swampctf19/rev/future).