Tags: vm reversing

Rating:

# compUDer

Check out our brand new computer!

nc challenges.ctfd.io 30525

Attachments:
* [vm.out](./vm.out)

## Solution
Opened the binary in Ghidra, after some clearup (Rename and Retype variable), we got

### Main Function
c
void main(void)
{
// Some Initialisation
fib_mem((long)arr_flag,0x20);
fwrite("VM $",1,5,stderr); vm_loop = false; while (!vm_loop) { __isoc99_scanf("%ld",&ins;; if (7 < ins) return; __isoc99_scanf("%ld",&x); is_reg_valid((uint)x); __isoc99_scanf("%ld",&a); is_reg_valid((uint)a); __isoc99_scanf("%ld",&b); is_reg_valid((uint)b); switch(ins) { case 0: stack[x] = stack[b] + stack[a]; break; case 1: stack[x] = stack[a] - stack[b]; break; case 2: stack[x] = stack[b] * stack[a]; break; case 3: stack[x] = stack[b] & stack[a]; break; case 4: stack[x] = stack[b] | stack[a]; break; case 5: if (0x43 < x) return; stack[x] = arr_flag[stack[a]]; break; case 6: if (0x43 < x) return; arr_flag[stack[x]] = stack[a]; break; case 7: vm_loop = true; break; default: return; } } flag_chk = 0; do { if (32 < flag_chk) { local_150 = fopen("flag.txt","r"); if (local_150 != (FILE *)0x0) { while( true ) { iVar2 = getc(local_150); if ((char)iVar2 == -1) break; putchar((int)(char)iVar2); } fclose(local_150); } return; } if (arr_flag[flag_chk] != arr_flag[flag_chk + 33]) { puts("Incorrect."); return; } flag_chk = flag_chk + 1; } while( true ); }  So we are given a VM binary. The constraint of the equations are: - Instruction value < 8 - Operands value < 6 The VM:  OPC Out a b -------------- 0 x a b ; stack[x] = stack[a] + stack[b] 1 x a b ; stack[x] = stack[a] - stack[b] 2 x a b ; stack[x] = stack[a] * stack[b] 3 x a b ; stack[x] = stack[a] & stack[b] 4 x a b ; stack[x] = stack[a] | stack[b] 5 x a b ; stack[x] = arr_flag[stack[a]] 6 x a b ; arr_flag[stack[x]] = stack[a] 7 x a b ; exit VM  I used gdb dynamic debugging to leak the initial stack  0x00000000 | 0 0x00000000 | 1 0x00000000 | 2 0x00000000 | 3 0x00000000 | 4 0x00000001 | 5  1st 33 values of arr_flag is initialized with fibonacci values. We need to make the next 33 values as same as the 1st ones to get the flag, like this: py for i in range(33): arr_flag[33+i] = arr_flag[i]  So my solution was: - Init a value to 33(say i) - Loop 33 times in the following way,(say loop var x) - Copy arr_flag[x] to stack - set arr_flag[x+i] from the stack - Increase value of (x+i) - Increase i Script [here](./solve.py) sh$ python solve.py
[+] Opening connection to challenges.ctfd.io on port 30525: Done
[*] Init [i]
[*] Set arr_flag[i]
FLAG!!! UDCTF{r3v3rs!nG_cUst0m_VMs_1s_3Z}


## Flag
> UDCTF{r3v3rs!nG_cUst0m_VMs_1s_3Z}

Original writeup (https://github.com/1GN1tE/CTF_Writeups/tree/main/Writeups/UDCTF(BlueHens)_2021/compUDer).