대부분의 소프트웨어는 완벽하지 않다. 소프트웨어에 존재하는 결함은 버그 (bug)라고 부른다. 보안 문제를 일으키는 버그를 취약점 (vulnerability)이라고 부른다. 공격자가 취약점을 이용하여 수행하는 보안 공격을 익스플로잇 (exploit)이라고 한다. 즉, 취약점은 익스플로잇을 할 수 있는 버그이다.
제로데이 공격 (0-day attack)
소프트웨어의 취약점이 발견되고 패치되기 까지는 어느정도 시간이 필요하다. 아직 패치가 나오지 않은 취약점을 제로데이 취약점 (0-day vulnerability)이라고 부른다. 패치가 나오지 않은 시점에 이루어지는 보안 공격을 제로데이 공격 (0-day attack) 이라고 한다.
버퍼오버플로우 (buffer overflow)
int main() {
int buffer[10];
buffer[12] = 55;
}
다음의 코드를 실행하면 어떤 일이 벌어질까?
- 임시메모리공간에buffer[10](10개의공간)을할당
- buffer[12] 위치의 메모리에 55이 할당된다.
입력 받는 데이터의 크기가 버퍼의 크기를 벗어나는지 제대로 체크하지 않을 경우 공격자는 버퍼를 벗어난 메모리 의 공간의 데이터를 수정할 수 있다.(혹은 자신이 원하는 값 을 쓸 수 있다.)
- C언어에서 사용자 입력을 받는 gets() 함수는 버퍼의 크기를 체크할 수 없어 버퍼 오버플로에 취약하다.
- Morris worm이 gets() 함수의 취약점을 이용했다.
char buf[100]; // 100바이트짜리 버퍼
gets(buf); // 입력 데이터가 100바이트를 넘기는지 확인하지 않는다.
buffer overflow의 대응책
[첫 번째]
스택 카나리아(stack canary)
- 카나리아라는 명칭은 탄광의 유독 가스 를 알아차리기 위해 카나리아라는 새를 이용한 데에서 유래
- Stack canary라는 임의의 난수 값을 스택 메모리의 리턴 주소 전에 저장해 둔다.
- 공격자가 스택 메모리 공간을 덮어써서 리턴 주소를 조작할 경우, 중간에 위치한 stack canary가 손상된다는 점을 이용해 함수 리턴 전에 stack canary를 확인하는 방법
- 컴파일러에서 제공하는 보안 기능이다.
[두 번째]
데이터 실행 방지(DEP, data execution prevention)
OS에서 제공하는 보안 기능으로, 실행 금지(NX)라고도 부름.
- 메모리 할당 시에 읽기/쓰기/실행 속성을 지정할 수 있는데, 데이터 영역 메모리는 실행 금지(NX)로 함
- 해커가 임의의 코드를 데이터 영역에 실어서 실행하는 것을 차단
- 두가지방식이있다.
- CPU 차원에서의 하드웨어 지원
- 소프트웨어 에뮬레이션: 스레드 태스크 스위칭 시 코드 주소를 확인 하여 실행 속성이 없는 메모리일 경우 실행을 중단
[세 번째]
데이터 실행 방지(DEP, data execution prevention) - Windows 10의 Windows 보안 설정
반환 지향형 프로그래밍 (ROP : Return-Oriented Programming)
- DEP를 우회하기 위해 고안된 코드 취약점
- 메모리 상에 존재하는 라이브러리 함수 코드 일부를 가져와서 리턴 주소 체인을 만들어 실행시키는 방식
정상적으로 존재하는 코드 메모리의 일부를 이용했으므로 DEP에 의해 차단되지 않는다.
ROP 의 대응책
ASLR(Address Space Layout Randomization)
- 해커가ROP에쓰이는코드조각의메모리주소를알수없도 록 메모리 공간의 배치를 랜덤화한다.
- OS에서 제공하는 보안 기능이다.
- Windows 10의 Windows 보안 설정 ( 밑에 그림 참고)
FSB (Format String Bug)
서식 문자열 버그(FSB, Format String Bug)
- C언어에서 콘솔 출력을 수행하는 printf 함수는 서식 문자열과 출력할 데이터를 인자로 전달받는다.
- 문자열데이터str을출력할때printf(“%s”,str)대신 printf(str) 형태로 출력할 경우 서식 문자열 버그에 취약하다.
- Printf 함수에 의해서 해석되는 “str”은 출력하고자 하는 문자열이 아 니라 printf 함수에서 사용할 각종 형식 지시자(%d, %s 등)를 포함한 format string으로 인식한다.
- 따라서출력하려는문자열내에지시자(directive)가들어있으면, printf 함수에 전달된 인자의 개수와는 상관없이 이러한 형식 지시자 의 개수 만큼의 인자들이 스택으로부터 추출된다.
- 공격자는 입력되는 str 문자열에 % 기호를 포함시켜 서식 문자열을 구성 할 수 있다. 서식 문자열 중 %n은 공격자는 이것을 이용하여 메모리 값을 조작할 수 있다.
- %n 형식은 format string 내에서 %n 지시자 전에 지정된 출력되어야 하는 모든 공간의 개수를 해당 변수로 저장한다.
- 예) int val;
printf(“aaaa%n”, &val); // val에 문자의 개수인 4가 대입된다.
- 예) int val;
- printf 함수가 %n 지시자를 만나면 이 지시자의 순서에 해당하는 내용을 스택에서 pop하고 pop된 내용을 주소로 하여 해당 주소에 지금까지 출력 된 문자의 개수를 저장하게 된다. 이때 만약 이 주소가 어떤 함수의 리턴 주소가 저장되어 있는 곳이라면 프로그램의 흐름이 변경될 수 있다.
FSB (Format String Bug) 의 대응책
- 시스템 차원에서는 대응할 수 없고 컴파일러 차원에서 대응하고 있다.
- FSB를 예방하기 위해 많은 C/C++ 컴파일러에서 printf(str)와 같은 문장을 경고로 처리한다.
- 또, 많은 C/C++ 컴파일러에서 표준이 아닌 서식 문자 인 %n의 지원을 없애 FSB를 이용한 메모리 조작의 가능 성을 없앴다.
- 그러나 FSB를 이용하여 민감한 정보를 읽어보는 것은 여 전히 가능하기에 printf(str)와 같은 문장은 피해야 한다.
'서버 > 암호' 카테고리의 다른 글
루트킷 (rootkit) (0) | 2021.07.29 |
---|---|
이진 분류기(binary classifier)의 결과 분류 (0) | 2021.07.29 |
멀웨어(malware) (0) | 2021.07.27 |
TLS 내부 (0) | 2021.03.25 |
TLS record 생성 (0) | 2021.03.24 |