2021. 7. 10. 00:01ㆍDreamhack Wargame
#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;
}
이 코드는 basic_exploitation_001.c 파일에 들어있는 소스코드입니다.
main문부터 보면 0x80 크기의 배열 buf가 있습니다.
그리고 initialize라는 함수를 호출하고선 buf를 입력을 받습니다.
initialize라는 함수를 자세히 보도록 하겠습니다.
initialize 함수의 첫 번째 줄에 있는 setvbuf() 함수는 버퍼의 크기를 설정하는 함수입니다.
signal() 함수와 alarm() 함수는 어떠한 신호를 alarm_handler() 함수에 보내고 실행을 시켜주는 함수입니다.
즉, 저 두 줄을 해석하면 30초가 지나면 alarm_handler() 함수에 신호를 보내서 실행시키는 함수입니다.
alarm_handler() 함수는 그냥 TIME OUT을 출력하고 프로세스를 종료시키는 함수입니다.
그런데 여기서 read_flag라는 굉장히 수상해 보이는 함수가 하나 있습니다.
내용을 보니 flag를 출력해주는 함수인 듯 한데, 여기서 문제는 저 함수를 어떻게 실행시키느냐가 되겠습니다.
main 함수에서 buf 입력을 받을 때 gets를 쓰는 걸 보니 오버플로우 문제인 것 같습니다.
buf와 sfp는 그냥 아무 값으로 채우고 뒤에 있는 ret(return address)에 read_flag() 함수 주소 값을 채우면 될 것 같습니다.
info function 명령어로 read_flag() 함수의 주소도 알아냈으니 이제 파이썬으로 익스코드를 짜 보겠습니다.
payload 변수에 a가 132개 이어져있는 문자열을 넣어서 오버플로우를 유도했습니다.
여기서 132는 buf의 크기 0x80(10진수로 128) + sfp의 크기 4를 더한 값입니다.
이 코드를 컴파일하고 실행해보겠습니다.
그러면 이렇게 의도한 대로 FLAG가 나오게 됩니다.
버퍼 오버플로우의 기초적인 문제였습니다.
버퍼의 개념과 오버플로우 익스코드 구현을 복습하기에 좋았습니다.
'Dreamhack Wargame' 카테고리의 다른 글
welcome 풀이 (0) | 2021.07.22 |
---|---|
basic_exploitation_000 풀이 (0) | 2021.07.11 |
broken-png 풀이 (0) | 2021.06.03 |
pathtraversal 풀이 (0) | 2021.05.29 |
file-download-1 풀이 (0) | 2021.05.09 |