1. 버퍼 오버플로우 공격
1-1. 개요
- 프로세스 메모리 구조
- Text: 프로그램 코드와 상수 (read-only)
- Data: 전역 변수와 정적 변수
- Heap: 동적 메모리 호출에 의해 할당
- Stack: 지역 변수, 매개 변수, 함수 반환 주소
- 스택 프레임
- 스택 영역에 저장되는 함수 호출 정보
- 공격 원리
- 시스템 제어를 위한 특별한 코드 (셸 코드) 삽입
- 정해진 크기의 버퍼를 벗어나 메모리 위치에 데이터를 겹쳐 씀으로써 공격
1-2. 스택 버퍼 오버플로우
- SetUID가 설정된 루트 권한의 프로그램을 공격 대상으로 함
- 셸 코드: 셸의 제어를 넘기고 공격 당한 프로그램의 권한을 사용할 수 있도록 하는 코드
- 공격 절차
- 셸 코드를 버퍼에 저장
- 스택 반환주소를 셸 코드가 있는 버퍼의 주소로 변경
- 특정 함수 호출이 완료되면 셸 코드 주소가 반환되어 루트 권환 획득
1-3. 힙 버퍼 오버플로우
- 힙은 메모리 위 방향으로 커지며 연결리스트와 같은 동적 데이터 구조를 위해 사용됨
- 할당된 공간이 함수에 대한 포인터를 포함하고 있을 때, 해당 주소를 셸코드의 주소로 변경
1-4. 대응책
- 컴파일 시간 방어
- 고급 프로그래밍 언어 사용
- C, C++는 자유도가 높아 메모리 접근 가능
- Java, ADA, Python 등은 버퍼 오버플로우를 허용하지 않음
- 시큐어 코딩
- 사용 자제: strcat, strcpy, gets, scanf, sscanf, vscanf, vsscanf, sprintf, vsprintf, gethostbyname, realpath
- 사용 권장: strncat, strncpy, fgets, fscanf, vfscanf, snprintf, vsnprintf
- 안전한 라이브러리
- Stack Guard
- 스택 프레임을 검사하고, 손상이 있다면 프로그램을 종료시킴
- 함수 호출 시 ret 앞에 canary 값을 주입해 해당 값이 변조되었는지를 탐지
- Stack Shield
- ret을 Global RET이라는 특수 스택에 저장해두고, 함수 종료 후 비교하여 변조되었으면 실행 중단
- 고급 프로그래밍 언어 사용
- 실행 시간 방어
- ASLR (Address Space Layout Randomization)
- 프로세스 스택 위치를 임의로 변경
- NOP sled: NOP을 타고 다음 명령어로 넘어가면서 정확한 주소를 몰라도 셸코드를 실행 가능
- Non-Executable Stack
- 스택과 힙을 실행불능 상태로 만듦
- /etc/system에서 해당 설정 가능
- RTL (Return to Libc): ret 주소를 libc 영역의 주소로 변경해 원하는 함수를 수행함으로써 우회
- ASLR (Address Space Layout Randomization)
2. 포맷 스트링 공격
사용자 입력을 통해 포맷 스트링이 결정될 때 생기는 취약점
취약한 프로세스를 공격하거나 메모리 내용을 읽을 수 있음
- 원리
- 데이터 형태에 대한 불명확한 정의를 악용
- %x를 통해 메모리 내용을 참조하고 %n을 통해 RET를 악성코드가 위치한 주소로 변조 가능
- 위협 요소
- 프로그램 파괴, 프로세스 메모리 참조, 메모리 덮어쓰기 등이 가능함
- 보안 대책
- 사용자 입력값을 직접 포맷 문자열로 사용하지 않음
- %n, %hn은 메모리 특정 값을 변경할 수 있으므로 사용하지 않음
3. 레이스 컨디션 공격
공유자원에 프로세스가 동시에 접근할 때 비정상적인 결과가 발생하는 것을 악용
- 파일 링크
- 하드 링크: 복사된 파일이 생성되어, 변경 사항이 동기화됨
- 심볼릭 링크: 원본 파일을 가리키는 링크 정보만 가짐
- 레이스 컨디션 공격
- 소유자가 root이며, 임시 파일을 생성하는 SetUID 파일을 대상으로 함
- lsof와 같은 명령어를 통해 임시 파일의 이름을 알아냄
- 프로그램이 실행되기 전, 임시 파일의 이름으로 심볼릭 링크 파일 생성 (원하는 타겟을 가리킴)
- 대응책
- 임시 파일 접근 전에 검사 과정 추가 (심볼릭 링크 설정 및 권한 검사)
- 임시 파일을 생성하지 않거나 sticky bit를 설정해 삭제되지 않게 함
- umask를 높게 유지
4. 백도어 (트랩도어)
보안이 제거된 비밀통로로, 설계자가 업무 편의성을 위해 고의적으로 만듦
악의적인 목적으로 만들어진 통로는 사용자의 정보를 유출시킴
- 리눅스와 유닉스에서는 http 데몬이 root 권한으로 운영되면 매우 취약함
- 탐지 및 대응
- 동작 중인 프로세스 확인
- 윈도우와 유닉스 시스템의 정상 프로세스를 알고 있는 게 좋음
- 악성 프로그램이 애용하는 프로세스: Csrss(콘솔 관장), Lsass(인증 프로세스), Svchost(DLL에 의해 실행), Mstask(백업, 업데이트 등)
- H-IDS 사용
- 호스트 기반 IDS를 사용해 의심스러운 포트의 활동을 탐지
- 의심스러운 실행 파일에 대한 checksum 수행 가능
- 동작 중인 프로세스 확인
5. 시스템 자원 고갈 공격 (DoS)
가용 디스크 자원 고갈 공격 | 파일을 계속 생성해서 디스크 자원 고갈 |
가용 메모리 자원 고갈 공격 | malloc 함수로 메모리 할당 계속 수행 디스크 자원 고갈 공격보다 더 많은 자원을 차지함 |
가용 프로세스 자원 고갈 | fork 함수를 무한대로 사용 |
프로세스 죽이기 | 루트 권한을 획득하고 스크립트로 모든 프로세스를 죽임 |
6. 리버스 엔지니어링
장치나 시스템 구조를 역추론해 원리를 발견하는 것
- 리버스 엔지니어링 공격
- 공격 대상 시스템이나 프로그램 분석을 수행한 후, 취약점을 공격할 수 있는 코드 생성
- 공격자는 가독성을 낮춰 분석을 어렵게 하고, 장비의 탐지를 우회하기 위해 코드 난독화를 함
- 대응책
- 소스코드 난독화: 소스코드를 알아보기 힘들게 함
- 바이너리 난독화: 컴파일 후 생성된 바이너리를 역공학으로 변조
7. 기타 시스템 보안 위협
- 루트킷 (Rootkit)
- 관리자 권한으로 접근하는 비밀통로를 유지하는 프로그램 집합
- 자신의 존재를 숨기기 위해 바이너리 파일을 변조시키는 경우가 많음
- 루트킷을 찾기 위해 시스템 프로그램의 파일 크기, 변경 시간 등을 확인해야 함
- 논리폭탄 (Logic Bomb)
- 특정 사건이 발생할 때 활성화되는 트리거를 보유