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]