Home (CTF) b01lers CTF 2022
Post
Cancel

(CTF) b01lers CTF 2022

difficulty: 🩸 rank: 70 writeup: rev(1)

TM ( 🩸 247 pt, 45 solve )

TL;DR : simple function poiner vm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  int ReturnValue; // [rsp+4h] [rbp-1Ch]
  int i; // [rsp+8h] [rbp-18h]
  __int32 *Heap; // [rsp+10h] [rbp-10h]
  __int32 *NextFunc; // [rsp+18h] [rbp-8h]

  setup();
  ptr = malloc(0x100uLL);
  ptrPointer = ptr;
  memset(ptr, 0, 0x100uLL);
  buf = malloc(0x100uLL);
  bufPointer = buf;
  *(bufPointer + read(0, buf, 0x100uLL)) = 0;
  Heap = *HeapArray;
  ReturnValue = 1;
  while ( ReturnValue )
  {
    NextFunc = HeapArray[Heap[*ptrPointer + 0x200]];
    ReturnValue = (*&Heap[2 * *ptrPointer])();
    Heap = NextFunc;
  }
  for ( i = 0; i <= 99; ++i )
    free(HeapArray[i]);
  free(ptr);
  free(buf);
  free(HeapArray);
  return 0LL;
}

Just dropping the tm file to ida, see the pseudo-code

setup()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HeapArray = (__int64 *)malloc((size_t)&MEMORY[0x4B000]);
  memset(HeapArray, 0, (size_t)&MEMORY[0x4B000]);
  v56 = malloc(0xC00uLL);
  for ( i = 0; i <= 255; ++i )
    v56[i] = ret_1;
  for ( j = 0; j <= 255; ++j )
    *((_DWORD *)v56 + j + 512) = 1;
  *HeapArray = (__int64)v56;
  v57 = malloc(0xC00uLL);
  for ( k = 0; k <= 255; ++k )
    v57[k] = buf_to_ptr;
  for ( m = 0; m <= 255; ++m )
    *((_DWORD *)v57 + m + 512) = 2;
  HeapArray[1] = (__int64)v57;

It setup the HeapArray ( function pointer and some nums )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# HeapArray 0 
# +0     (void*) return 1 func * 0x100
# +0x200 (int) 1 * 0x100

# HeapArray 1
# +0     (void*) *ptrPointer = *buf; buf = buf+1; func * 0x100
# +0x200 (int) 2 * 0x100

# HeapArray 2 
# +0     (void*) return 1 func * 0x80 (odd index) / (void*) *ptrPointer+=10 * 0x80 (even index)
# +0x200 (int) 4 *1
# +0x204 (int) 3 * 0x100-1

# HeapArray 3 
# +0     (void*) *ptrPointer^=0x45, ptrPointer+=1 *0x100
# +0x200 (int) 1 * 0x100

# HeapArray 4 
# +0     (void*) ptrPointer-=2 * 0x100
# +0x200 (int) 7 * 0x100

# HeapArray 5 
# +0     (void*) print rejected * 0x100

# HeapArray 6
# +0     (void*) print accepted * 0x100

# HeapArray 7 ~ 27
# +0     (void*) --ptrPointer * 0x100
# +0x200 ~ 0x300 = 5
# +0x2XX = 0x8 ~ 0x1b

HeapArray like this.

1
2
3
4
5
6
7
8
Heap = (__int32 *)*HeapArray;
ReturnValue = 1;
while ( ReturnValue )
  {
    v7 = (__int32 *)HeapArray[Heap[*(char *)ptrPointer + 0x200]];
    ReturnValue = (*(__int64 (**)(void))&Heap[2 * *(char *)ptrPointer])();
    Heap = v7;
  }

and execution routine is like this.

  1. get number in HeapArray[Heap[0x200+*ptrPointer]]
  2. call the function in Heap[2 * *ptrPointer]
  3. update Heap to next

the number array is the idx of the next HeapArray

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0. goto 1
1. get my one input byte to ptr, goto 2
2. *ptr is odd -> *ptr-=10
           even -> return 1, goto 3
    if *ptr == 0, goto 4

3. xor *ptr with 0x45, ptr++, goto 1
4. ptrPointer-=2, goto 7
5. print rejected
6. print accepted <-- goal
7. if *ptr == XX,ptr-=1,goto 7+1 or 5
8. if *ptr == XX,ptr-=1,goto 8+1 or 5
...
27. if *Ptr == XX, ptr-=1, goto 6 <-- all correct flag

Untitled

To find the correct XX, I used IDApython.

parse all index ( 0x276, 0x23D .. ), repeat xor and minus 10 if even number.

solve.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
start=0x555555555704

f=ida_funcs.get_func(start)
c=7
flag=''
for ea in Heads(f.start_ea,f.end_ea):
    if get_operand_value(ea,1)==0x555555555342:
        to=get_operand_value(ea+0x32,1)
        idx=get_operand_value(ea+0x4a,0)
        value=get_operand_value(ea+0x4a,1)
        print(f"{c}: default : {to}, {(idx//4)-0x200}={value}")
        c+=1
        if ((idx//4-0x200)^0x45) & 1 == 0:
            flag+=chr(((idx//4-0x200)^0x45)-10)
        else:
            flag+=chr(((idx//4-0x200)^0x45))
print(flag[::-1])

If you find the routine well. It was an easy problem

This post is licensed under CC BY 4.0 by the author.
Trending Tags