출처: http://bbolmin.tistory.com/65
Stack Smashing Protector은 gcc 4.1버전 부터 있는 stack overflow를 방지하기 위한 컴파일러 옵션이다.
gcc 4.6.1버전에서 컴파일 후 overflow가 발생하는 프로그램을 실행시켜 보니 다음과 같이 stack smashing detected가 뜨는 것을 확인 할 수 있다.
SSP 끄기 : -fno-stack-protector
SSP를 모든 함수에 설치 : -fstack-protector-all (원래는 일정 크기의 char배열이 있는 함수에만 적용됨)
SSP의 기능을 살펴보자
1. 로컬 변수 재배치
2. 로컬 변수전에 포인터 배치
3. canary 삽입
1. 로컬 변수 재배치
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void main(int argc, char *argv[])
{
int check=0;
char buf[10];
strcpy(buf, argv[1]);
if(check==0)
exit(0);
printf(“check : %d\n”, check);
}
buf를 오버플로우시켜서 check값을 바꿀 수 있을 것이다. 하지만 SSP는 스택에서 char배열을 제일 높은 곳으로 올려 다른 변수 값이 변조되는 것을 막는다.
2. 로컬 변수전에 포인터 배치
void test(char *arg)
{
char buf[10];
strcpy(buf, arg);
}
위와 같이 포인터가 있을 때 buf를 오버플로우 시켜서 test함수의 파라미터로 전달된 포인터 arg값을 바꿀 수 있을 것이다. 하지만 SSP는 arg포인터를 buf아래 쪽에 두어서 변조되는 것을 막는다.
3. canary 삽입
————
| ret |
————
| ebp |
————
| canary |
————
| buf |
————
stack guard처럼 canary를 두어 ret변조를 탐지한다. 이 때 canary는 ebp와 buf 사이에 넣는다. canary 값은 1) random, 2) terminator, 3) null 을 사용하여 우회하는 것을 방지한다. canary 변조를 탐지 했을 때 맨위 그림와 같이 stack-smashing-detected 메시지를 띄어준다. (변조 탐지시 __stack_chk_fail함수를 호출)