본문 바로가기
Study/Software Security

[소프트웨어보안] 스택 Overflow에 대한 대응, 안전한 프로그램 개발

by 8희 2022. 11. 30.

스택 Overflow에 대한 대응

일반적 방어 방법

방어 기술은 fix를 대체하기 어려움

– 계층적인 방어(Layered Defense) 기법

• 악성코드 실행, 취약한 코드의 악용

– 코드의 변경이 가능한지에 대한 고려

 

Overflow defense

Overflow에 대한 대응 방법은 지속적으로 개발되어 옴

공격에 대한 성공 확률 낮춤

– Tamper detection

– 운영체제와 하드웨어에서의 Memory protection

– Diversification methods

 

Canaries on the stack

• 각 스택 프레임이 갖고 있는 취약한 포인터 값들에 대한 보호

• Idea:

– 프레임을 보호계층으로 감싸기 “canary”

– Canary는 return address 아래 위치

– 공격자가 리턴 주소를 위변조 하고자 할 때

– Canary를 갱신하게 됨

– 프로그램 실행 중 Canary의 갱신 여부를 확인

• 초기 버전: StackGuard compiler.

 

경쟁 조건(race condition)

경쟁: 공격자는 canary 메커니즘을 분석하여 이의 취약점 을 발견하고 공격을 수행

– 상수형 canary 를 찾아냄

• 만일 canary가 0x0af237ab6이면 리턴 주소 근처에 해당 값을 넣어서 우회함

– 난수형 Canary

• 난수 값의 변화를 확인 하거나 SEED 값을 찾아냄

– 암호기술 기반의 난수생성

• 값이 저장된 위치 찾기

• 이를 복사하기 위한 코드 작성

 

효과

지역변수는 보호하지 않음

– 지역변수의 재배치를 방어기법으로 사용

• 파라미터에 대한 overwriting 공격

– 연속적으로 쓰기가 발생한 경우의 변경을 확인

– 리턴 주소에 쓰기를 해도 리턴 하지 않음

• Heap 보호 기능 개발

– glibc와 Windows XP SP2 부터 heap canaries를 갖고 있음

• 리턴을 기반으로 하는 프로그래밍

– state-of-the-art: 존재하는 실행 코드의 활용

– Canaries 우회, NX 까지 우회

 

Operating system  분리

• 고립(Isolation)

– 다른 프로세스들이 다른 자원을 사용하도록 (address spaces, file systems, . . . )

• 공유(Sharing) - 프로세스간 자원이 공유되어야 함, 일부 고립 허 용, 공유 대상:

– All or nothing – 접근통제를 통한 중재(mediated with access controls)

– 사용량 제한을 통한 중재(mediated with usage controls (capabilities))

• Concern: 보호의 단위 (granularity of protection.)

• 운영체제는 다중 사용자 환경을 기반으로 분리 메커니즘을 중요하 게 생각함.

 

NX(실행불가-Non-executable) Memonry

 CPU가 메모리 페이지에 대해 R, RW, X 보호 기능을 갖게 함

– x86 series CPU들은 페이지 레벨 XD/NX을 갖게 함.

• non-executable regions의 정의를 통해

– code와 데이터가 나누어져 있는 상황을 고려

– 쉘 코드의 실행이 데이터영역에서 이루어지지 않도록 할 수 있음

 

Address Space Layout Randomization (ASLR)

 개념

– 같은 프로그램의 여러 버전을 만들어서 다양화 함.

– 고정된 구조를 가질 것이라고 가장한 공격의 발생을 막을 수 있음

• Randomization을 통해

– 데이터 혹은 코드의 위치를 찾기 어렵게 함.

• 효과

– 좋지만, 주된 취약점을 제거하지는 못함.

– 오히려 ASLR구현 내용이 악용 대상이 되기도 함.

– 적은 주소 공간을 가지고 random 화 할 경우 (e.g. 256 addresses), 공격자가 brute force 기법으로 취약한 위치를 찾을 수 있음

 


안전한 프로그램 개발

방어적 프로그래밍 - 경계 점검

오버 플로우에 대한 방어적 프로그래밍 방법은 경계의 검사임.

– 쓰기 전 데이터 길이 검사 (Check data lengths before writing)

– 입력의 길이를 제한(Constrain size of inputs)