BOF에 대한 내용을 정리하기에 앞서, 취약점(Vulnerability)과 관련된 용어에 대해 알아보자
Vulnerability
소프트웨어에서 로그인 없이 액세스를 활성화하거나 허가되지 않은 코드를 실행하거나 컴퓨터를 손상시키는 등 공격 시 예기치 않은 컴퓨터 동작을 발생시키는 Bug 이다.
Exploit
프로그램에 존재하는 Bug를 악용하는 input이다.
- Exploitable: Bug를 이용해서 소프트웨어를 성공적으로 장악할 수 있다. (공격하는 데 사용할 수 없다면 'exploitable 하지 않다'고 한다.)
Threat
컴퓨터 보안에서 Threat은 취약성을 악용하여 보안을 위반함으로써 피해를 입힐 가능성이 있는 위험이다.
취약점 공격의 종류는 그 구분 방법에 따라 여러 가지로 나눌 수 있으며, 그 중 하나가 BOF 취약점 공격 이다.
그렇다면, BOF 취약점 공격은 무엇인가?
Buffer
데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리의 영역을 의미한다.
Overflow
사전적으로 '용량을 초과하여 넘쳐 흐른다'는 뜻의 용어로, 한정된 메모리 용량을 넘어가는 값이 들어갈 때 발생하는 오류를 의미한다.
Buffer Overflow (BOF)
Buffer가 흘러넘쳐 발생하는 것으로, 데이터를 메모리에 저장할 때 프로그래머가 지정한 메모리 바깥쪽에 저장하는 것이다.
벗어난 데이터는 가까운 메모리를 덮어쓰게 되는데, 해당 메모리에 다른 데이터가 포함되어있을 가능성이 있다.
C 및 C++은 변수의 범위를 검사하지 않아 특히 Buffer Overflow에 취약하다. (값이 Buffer를 초과하더라도 신경쓰지 않고 저장한다.)
🚫 단순히 데이터가 바뀌는 것에 그치지 않고 해킹에 사용된다면?
악의적인 공격자는 위와 같은 취약점을 알고 데이터의 길이와 내용을 적절히 조정하여
의도적으로 Buffer Overflow를 일으켜서 특정 코드를 실행시키도록 한다.
BOF 종류
Stack에 존재하는 Buffer에 대한 공격이냐 Heap에 존재하는 Buffer에 대한 공격이냐에 따라 Stack BOF와 Heap BOF로 구분된다.
- Stack BOF
Stack (함수 처리를 위해 지역 및 매개변수가 위치하는 메모리 영역) 구조 상, 할당된 Buffer가 정의된 Buffer 한계치를 넘는 경우 복귀 주소를 변경하여 공격자가 임의 코드를 수행
- Heap BOF
Heap (malloc()등의 메모리 할당 함수로 사용자가 동적으로 할당하는 메모리 영역) 구조 상, 최초 정의된 Heap의 메모리 사이즈를 초과하는 문자열들이 Heap의 Buffer에 할당될 시, 공격자가 데이터 변경 및 함수 주소 변경으로 임의 코드를 수행
메모리 구조
- Stack
- 프로그램이 자동으로 사용하는 임시 메모리 영역으로, 지역변수, 매개변수, 리턴 값 등이 잠시 사용되었다가 사라지는 임시적인 데이터를 저장하는 영역
- 함수 호출 시 생성되고 함수가 끝나면 반환
- Stack의 사이즈는 각 프로세스마다 할당되지만, 프로세스가 메모리에 로드될때 Stack 사이즈가 고정되어 있어 런타임시 사이즈 변경 불가능
- 메모리의 높은 주소에서 낮은 주소의 방향으로 저장
- Heap
- 필요에 의해 메모리를 동적 할당하고자 할 때 사용하는 메모리 영역으로, 동적 데이터 영역
- 메모리 주소값에 의해서만 참조되고 사용
- 이 영역에 데이터를 저장하기 위해 C에서 malloc()함수를 사용
- 메모리의 낮은 주소에서 높은 주소의 방향으로 할당
Stack BOF
- 공격자는 SFP 영역까지 값을 넘치게 덮어 쓴 후, RET 영역까지 도달, RET 영역의 주소를 악성 코드의 주소로 변경하여 실행되도록 유도하는 형태로 Stack BOF를 수행
- 악성 코드 내 setuid를 설정하여 root 권한으로의 권한 상승 등 다양한 공격에 이용 가능
Heap BOF
- Heap 영역의 낮은 주소에 있는 버퍼가 넘쳐서 다른 버퍼를 침범하여 발생
- 동적 메모리 할당 연결(malloc 상위 수준 데이터)을 덮어 씀으로써 프로그램의 함수 포인터를 조작
C 언어 BOF 주요 함수
- strcpy(char dst, const char src)
- src 문자열을 dst 버퍼에 저장
- src 문자열 길이를 체크하지 않아, dst 버퍼를 초과하는 BOF 가능
- strncpy(char dst, const char src, size_t len)
- src 문자열의 len 만큼을 dst 버퍼에 저장
- src 문자열 길이를 제한하여 BOF 방지 가능
- size_t strlen(const char *str)
- 문자열(str)의 null 문자를 제외한 바이트 수를 반환
- sizeof(피연산자)
- 피연산자의 크기를 반환
Buffer Overflow 방지법
- BOF를 일으킬 여지가 있는 표준 라이브러리 함수를 사용하지 않는다.
- 입력 값 검사를 한다. 모든 입력을 받아들이고 특정 입력을 차단하는 방식에서 특정 입력만 받아들이고, 나머지를 차단하는 방식을 고려해야 한다.
- 프로그래밍 시 버퍼 경계 검사를 한다.
- BOF에 안전한 라이브러리를 사용한다.
- 각종 BOF 대응 기술을 사용한다.
- BOF 정적 분석 도구를 사용한다. 많은 분석도구가 BOF 결함을 탐지해낼 수 있다.
- BOF를 방지할 수 없다는 주장도 있다.
BOF 대응 기술
- Stack Guard (Canary Word Method)
메모리 상 프로그램 복귀 주소와 변수 사이에 특정 값(Canary Word)를 저장, 그 값이 변경되었을 경우 BOF로 간주하고 프로그램 중단 - Stack Shield
복귀 주소를 Global RET라는 특수 Stack에 저장 후, 함수 종료 시에 저장된 값과 RET 값을 비교하여 다를 시, BOF로 간주하고 프로그램 중단 - ASLR (Address Space Layout Randomization)
프로그램 실행 시 마다 메모리 주소 공간을 난수화 하여 특정주소 호출 방지
해커가 BOF에 사용할 여러 메모리 주소들을 찾기 어렵게 만드는 것
위 기술들은 현재 OS에 기본으로 반영되어있다.
실제사례
- Heartbleed
- Ariane 5 로켓 폭팔 사고
- 윈도우 XP
9999년 12월 31일 오후 11시 59분 59초에서 1초후인 10000년이 되면, CPU의 점유율이 급상승하는 오류
Reference
- https://www.youtube.com/watch?v=SOoJcrR4Ijo
- https://nitr0.tistory.com/175
- https://www.youtube.com/watch?v=quLIdcHgi1k
- https://eehoeskrap.tistory.com/9
- https://isc9511.tistory.com/119_
- https://dong-co.tistory.com/11
- https://dieuhouse.tistory.com/entry/%EA%B3%B5%EA%B2%A9%EA%B8%B0%EB%B2%95-Buffer-Overflow%EB%B2%84%ED%8D%BC-%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0
- https://bpsecblog.wordpress.com/2016/10/06/heap_vuln/
- https://itwiki.kr/w/%EB%B2%84%ED%8D%BC_%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0