공시 한 판

정보보호론 개념서 · 응용 프로그램 취약점

버퍼 오버플로 대응 기법: 스택 가드

설명 영상 버퍼 오버플로 대응 기법: 스택 가드 · 2:32

핵심 정리

버퍼 오버플로는 고정 길이 버퍼에 그 길이를 넘는 데이터를 써서 인접한 메모리를 덮어쓰는 결함이다. 스택에 할당된 버퍼가 넘치면 함수가 돌아갈 주소인 복귀 주소까지 덮어써질 수 있어 실행 흐름을 공격자가 바꿀 수 있다. 그래서 스택 영역의 오버플로는 힙보다 프로그램 실행에 주는 영향이 크다. 대응 수단은 입력 단계에서 길이를 막는 방법과, 오버플로가 일어난 뒤 이를 탐지하거나 공격의 효과를 없애는 방법으로 나뉜다. 버퍼 오버플로 대응 방법에는 스택 가드, 스택 쉴드, ASLR 등이 있다.

스택 가드는 리턴 주소 앞에 카나리 값을 두어 변조를 감지하는 기법이다. 함수가 끝나기 전에 카나리 값이 바뀌었는지 검사하면 스택 오버플로를 찾아낼 수 있다. 검사에 걸리면 프로그램은 세그멘테이션 오류를 일으키며 중단되고, 공격자가 제어를 넘겨받는 것을 막는다. 스택 가드의 효과는 오버플로를 아예 막는 것이 아니라 복귀 전에 탐지해 실행을 멈추는 데 있다.

주소 공간 배치 난수화(ASLR)는 실행할 때마다 스택, 힙, 공유 라이브러리의 주소를 무작위로 배치하는 방어 기법이다. 배치가 매번 달라지므로 메모리 손상 공격에서 함수 위치를 예측하기 어렵다. 스택 영역에서의 코드 실행을 막는 Non-Executable 스택도 버퍼 오버플로에 대응하는 기법이다.

스택 쉴드는 반환 주소를 별도 영역에 보관하고 함수 복귀 시 비교하는 방어 기법이다. 이 기법들은 탐지, 주소 흩뜨리기, 실행 금지, 복귀 주소 대조처럼 원리가 서로 달라 어느 하나로 모든 공격을 막을 수 없다. 스택 보호가 완벽한 해결책이 아닌 것은 귀환 주소가 아닌 민감한 데이터가 여전히 덮어씌어질 가능성이 있기 때문이다.

근본적인 대응은 공격이 일어나기 전에 입력의 길이를 검사하는 것이다. 개발 단계에서 저장할 수 있는 최대 길이를 지정하는 안전한 함수를 쓰면 오버플로가 생기는 원인 자체를 없앨 수 있다. 이 점에서 입력 단계의 대응은 다른 기법보다 앞서는 기본 수단이다.

자세히

카나리 값 검사 (스택 가드)

스택 가드의 핵심은 검사 시점이다. 카나리 값은 복귀 주소 바로 앞에 놓이므로, 스택 버퍼 오버플로가 일어나면 복귀 주소보다 먼저 이 값이 덮어써진다. 따라서 함수가 값을 돌려주기 직전에 카나리 값만 확인해도 오버플로가 있었는지 알 수 있다.

카나리 값이 늘 같은 값이면 공격자가 그 값을 그대로 덮어쓰고 검사를 통과할 수 있다. 그래서 카나리 값을 무작위 값으로 두어 공격자가 미리 알아내지 못하게 한다. 값이 노출되면 우회가 쉬워지므로 무작위성은 이 기법이 성립하기 위한 요건이라고 볼 수 있다.

검사에 실패했을 때의 처리는 실행 중단이다. 변경이 발견되면 프로그램은 복귀를 진행하지 않고 끝나므로, 위조된 복귀 주소로 흐름이 넘어가지 않는다. 다만 이 방식은 복귀 주소 쪽의 변조를 겨냥한 것이어서, 복귀 주소가 아닌 민감한 데이터는 여전히 덮어씌어질 수 있다는 한계가 있다.

주소 무작위 배치의 효과 (ASLR)

ASLR이 노리는 것은 공격자가 필요한 주소를 미리 알지 못하게 하는 것이다. 복귀 주소를 위조하는 공격에서 공격자는 자신이 원하는 메모리 주소를 지정해야 하는데, 배치가 매번 바뀌면 그 지정이 어려워진다. 스택 영역을 임의의 메모리 주소에 할당하면 스택 영역의 주소를 추측하기 어려워진다.

ASLR은 위치를 없애는 것이 아니라 위치를 모르게 하는 기법이다. 따라서 주소가 노출되는 정보 누출이 있으면 그 효과는 줄어든다. 또한 ASLR은 오버플로 자체를 찾아내는 장치가 아니라 오버플로 이후에 쓰일 주소를 흩뜨리는 장치이므로, 오버플로 발생 여부를 검사하는 스택 가드와는 역할이 다르다.

이어지는 내용

로그인하면 하루 5페이지까지 무료로 전체를 읽을 수 있습니다.

앱에서 이 절 읽기