콘텐츠로 건너뛰기

Small Counter

Description

플래그를 생성하는 함수 flag_gen()을 호출하고 플래그를 출력하세요.

플래그 형식은 DH{…} 입니다.


int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 src[10]; // [rsp+0h] [rbp-F0h] BYREF
  char dest[72]; // [rsp+A0h] [rbp-50h] BYREF
  unsigned int i; // [rsp+ECh] [rbp-4h]

  puts("---Counter---");
  for ( i = 10; (int)i > 0; --i )
  {
    printf("%d\n", i);
    if ( i == 3 )
    {
      strcpy((char *)src, "IM{508889j32j87j9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}");
      memcpy(dest, src, 0x45uLL);
    }
  }
  puts("---END---");
  return 0;
}

IDA로 열어보면 암호화된 FLAG가 보이는데, 문제는 flag_gen 함수가 보이지 않는다.

찾아보면 분명 flag_gen가 main을 역참조하는것을 확인할 수 있는데, 어셈블리로 확인해볼 필요가 있었다.


flag_gen은 어디서 호출?

flag_gen이 호출되지 않는 원인을 찾았다.

루프문을 빠져나가면 반복 카운트를 담당하는 i인 [rbp+var_4] 값이 0이 되고
cmp [rbp+var_4], 5 어셈블리 코드를 수행하면 zero flag가 1이 되므로
loc_15FE 분기문으로 점프될 수 밖에 없다.

따라서 Pseudo Code를 다시 구현하면 아래와 같을 것이다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 src[10]; // [rsp+0h] [rbp-F0h] BYREF
  char dest[72]; // [rsp+A0h] [rbp-50h] BYREF
  unsigned int i; // [rsp+ECh] [rbp-4h]

  puts("---Counter---");
  for ( i = 10; (int)i > 0; --i )
  {
    printf("%d\n", i);
    if ( i == 3 )
    {
      strcpy((char *)src, "IM{508889j32j87j9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}");
      memcpy(dest, src, 0x45uLL);
    }
  }
  if(i == 5) {
    puts("Nice!");
    flag_gen(dest, (__int64)i, 10);
  } else {
    puts("---END---");
  }
  return 0;
}

GDB 디버깅해서 flag_gen 호출하기

0x00000000000015aa <+278>:	cmp    DWORD PTR [rbp-0x4],0x5

카운트 변수를 담당하는 i 변수가 5인지 확인하는 어셈블리 코드에 브레이크 포인트를 걸고 실행한다.

ubuntu@wh1te4ever-main:~/Desktop$ gdb ./chall
...
Reading symbols from ./chall...
(No debugging symbols found in ./chall)
gdb-peda$ b *main+0x116
Breakpoint 1 at 0x15aa
gdb-peda$ r
Starting program: /home/ubuntu/Desktop/chall 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
---Counter---
10
9
8
7
6
5
4
3
2
1
[----------------------------------registers-----------------------------------]
RAX: 0x2 
RBX: 0x0 
RCX: 0x1 
RDX: 0x0 
RSI: 0x5555555592a0 ("1\n\nCounter---\n")
RDI: 0x7fffffffdd50 --> 0x7ffff7de10d0 (<__funlockfile>:	endbr64)
RBP: 0x7fffffffe3a0 --> 0x1 
RSP: 0x7fffffffe2b0 ("IM{508889j32j87j9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}")
RIP: 0x5555555555aa (<main+278>:	cmp    DWORD PTR [rbp-0x4],0x5)
R8 : 0x0 
R9 : 0x7fffffffe187 --> 0xe2083ecf3a130031 
R10: 0x0 
R11: 0x246 
R12: 0x7fffffffe4b8 --> 0x7fffffffe718 ("/home/ubuntu/Desktop/chall")
R13: 0x555555555494 (<main>:	endbr64)
R14: 0x555555557da0 --> 0x555555555180 (<__do_global_dtors_aux>:	endbr64)
R15: 0x7ffff7ffd040 --> 0x7ffff7ffe2e0 --> 0x555555554000 --> 0x10102464c457f
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x55555555559c <main+264>:	sub    DWORD PTR [rbp-0x4],0x1
   0x5555555555a0 <main+268>:	cmp    DWORD PTR [rbp-0x4],0x0
   0x5555555555a4 <main+272>:	jg     0x5555555554c5 <main+49>
=> 0x5555555555aa <main+278>:	cmp    DWORD PTR [rbp-0x4],0x5
   0x5555555555ae <main+282>:	jne    0x5555555555fe <main+362>
   0x5555555555b0 <main+284>:	lea    rax,[rip+0xa5f]        # 0x555555556016
   0x5555555555b7 <main+291>:	mov    rdi,rax
   0x5555555555ba <main+294>:	call   0x555555555090 <puts@plt>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe2b0 ("IM{508889j32j87j9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}")
0008| 0x7fffffffe2b8 ("9j32j87j9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}")
0016| 0x7fffffffe2c0 ("9jg54650840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}")
0024| 0x7fffffffe2c8 ("840428hjhi2ii08h74ihj538h543j7g6k5jk8jih22f}")
0032| 0x7fffffffe2d0 ("hi2ii08h74ihj538h543j7g6k5jk8jih22f}")
0040| 0x7fffffffe2d8 ("74ihj538h543j7g6k5jk8jih22f}")
0048| 0x7fffffffe2e0 ("h543j7g6k5jk8jih22f}")
0056| 0x7fffffffe2e8 ("k5jk8jih22f}")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x00005555555555aa in main ()
gdb-peda$

그리고 rbp-0x4에 저장된 포인터 주소에 5라는 값을 할당시키면,
flag_gen 함수가 호출된다.

gdb-peda$ set *(int*)($rbp-0x4) = 5
gdb-peda$ c
Continuing.
Nice!

DH{389998e56e90e8eb34238948469cecd6dd89c04dce359c345e0b2f3ef9edc66a}
[Inferior 1 (process 26192) exited normally]
태그:

답글 남기기