메모리 보호 기법 SSP(Stack Smashing Protector)

출처: 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함수를 호출)