취약점 분석과 방어 기법이란?
소프트웨어 취약점은 공격자가 시스템을 침해하는 주요 경로입니다. 정보보안기사에서는 메모리 취약점의 원리, 익스플로잇 기법, 그리고 운영체제·컴파일러 레벨의 방어 메커니즘을 깊이 이해해야 합니다.
메모리 취약점 유형
버퍼 오버플로우
- Stack-based BOF: 스택의 로컬 변수 영역을 침범해 리턴 주소 덮어쓰기. strcpy·gets·sprintf 등 안전하지 않은 함수 사용 시 발생
- Heap-based BOF: 동적 할당 메모리 영역 침범. 청크 헤더 메타데이터 조작으로 임의 주소 쓰기 가능
- Off-by-one: 경계 검사 오류로 1바이트 초과 쓰기. 스택 카나리 부분 덮어쓰기에 활용 가능
기타 메모리 취약점
- Use-After-Free(UAF): 해제된 메모리를 재참조. 댕글링 포인터(Dangling Pointer) 문제
- Double Free: 같은 메모리를 두 번 해제. 힙 메타데이터 손상
- Format String: printf(“%s”, user_input) 대신 printf(user_input) 형태. %x·%n으로 임의 주소 읽기·쓰기
- Integer Overflow: 정수형 범위 초과로 할당 크기 조작 가능
운영체제 방어 메커니즘
ASLR (Address Space Layout Randomization)
- 개념: 스택·힙·라이브러리의 메모리 주소를 실행 시마다 무작위화
- 엔트로피: 64비트 시스템에서 높은 무작위성. 32비트는 엔트로피 낮아 브루트포스 가능
- 우회 기법: 정보 유출(Info Leak)로 베이스 주소 획득. Heap Spray로 주소 예측
- Linux 설정: /proc/sys/kernel/randomize_va_space (0=비활성, 1=부분, 2=전체)
DEP/NX (Data Execution Prevention/No-eXecute)
- 개념: 데이터 영역(스택·힙)에서 코드 실행 방지. 하드웨어 NX 비트 활용
- 우회 기법: ROP(Return-Oriented Programming). 기존 코드의 가젯(Gadget) 조합
- ROP 체인: ret 명령으로 연결되는 코드 조각들. mprotect·VirtualProtect로 실행 권한 변경
스택 카나리(Stack Canary)
- 개념: 리턴 주소 앞에 랜덤 값 배치. 함수 반환 전 카나리 값 변조 여부 확인
- GCC 옵션: -fstack-protector(-all/-strong). SSP(Stack Smashing Protector)
- 우회 기법: 카나리 값 유출(Format String 등). 비연속 메모리 덮어쓰기
CFI (Control Flow Integrity)
- 개념: 간접 호출(함수 포인터, 가상 함수)의 대상을 미리 정의된 집합으로 제한
- Shadow Stack(CET): Intel CET. 리턴 주소를 별도 쉐도우 스택에 저장해 검증
안전한 코딩 기법
- 경계 검사 함수: strncpy·snprintf·strlcpy 사용. 입력 길이 항상 검증
- 스마트 포인터: C++ unique_ptr·shared_ptr으로 UAF·Double Free 방지
- 메모리 안전 언어: Rust의 소유권 시스템으로 컴파일 타임에 메모리 오류 방지
- Fuzzing: AFL++·libFuzzer·OSS-Fuzz. 무작위 입력으로 크래시 발견
시험 핵심 포인트
- ASLR 우회: 정보 유출(Info Leak) + ROP 체인 조합
- DEP 우회: ROP(Return-Oriented Programming) — 실행 가능 코드 가젯 재활용
- 스택 카나리: __stack_chk_fail 호출로 프로그램 종료
- Format String: %n으로 임의 주소에 쓰기 가능
마무리
취약점 방어 기법은 공격 기법과 항상 쌍으로 이해해야 합니다. 각 방어 기법이 어떤 공격을 막고, 어떻게 우회될 수 있는지 파악하는 것이 핵심입니다.