시스템 보안위협 정리 (방법 vs 방어)
대상: 버퍼 오버플로우, 포맷 스트링, 레이스 컨디션(TOCTOU), 시스템 자원 고갈
| 위협 | 방법(공격 시나리오/악용 포인트) | 방어(개발 · 빌드 · 운영) |
|---|---|---|
| 버퍼 오버플로우 (Buffer Overflow) | - 입력 길이 검증 부재로 스택/힙 메모리 덮어쓰기- 리턴 주소, 함수 포인터, vtable 조작 → 임의 코드 실행- 고전 C API 오용: gets, strcpy, sprintf 등 |
- 안전 API: snprintf, strlcpy, memcpy_s 등 사용, 경계 체크 철저- 컴파일 보호: -fstack-protector, Stack Canary, PIE, RELRO- 플랫폼 보호: DEP/NX, ASLR, W^X- 정적/동적 분석: SAST/DAST, 퍼저(fuzzer)로 입력 경계 검증 |
| 포맷 스트링 (Format String) | - printf(user)처럼 사용자 입력을 포맷 문자열로 사용- %x/%p로 메모리 노출, %n로 메모리 쓰기 → 정보유출/권한상승 |
- 항상 리터럴 포맷 지정: printf("%s", user)- 컴파일 경고/정적분석 활성화(-Wformat -Wformat-security)- 런타임 완화: ASLR/DEP, 민감 포인터/주소 노출 최소화 |
| 레이스 컨디션 (Race Condition, TOCTOU) | - 검사-사용 간 시차(TOCTOU): 권한/상태 확인 후 실제 사용 사이에 변경 유도- 예) 임시파일 링크 교체, 권한 파일 열기 순서 경쟁, PID/소켓 바꿔치기 | - 원자적 처리: `open(..., O_CREAT |
| 시스템 자원 고갈 (Resource Exhaustion/DoS) | - 메모리/FD/스레드/프로세스 무한 생성(예: fork bomb), 소켓/포트 고갈- 무한 요청/대용량 업로드, ReDoS(정규식 폭발), 로그/디스크 가득 채우기 | - 쿼터/리밋: ulimit, cgroups, 컨테이너 리소스 제한(CPU/메모리/FD)- 요청 제어: 레이트리밋, 동시접속/큐 길이 제한, 타임아웃/서킷브레이커- 입력 방어: 정규식 NFA 폭발 회피(고정폭·어설션 최소화), 최대 크기/시간 제한- 모니터링/자동복구: 메트릭·알람(메모리/FD/디스크), 로테이션·백프레셔 |
핵심 암기 포인트
-
버퍼 오버플로우: 입력 길이 + 안전 API + 컴파일/플랫폼 보호(ASLR/DEP/Canary)
-
포맷 스트링: 포맷은 항상 리터럴.
%n악용 주의,-Wformat-security -
레이스(TOCTOU): 원자적 시스템콜·락·권한 최소화, 임시파일/심볼릭 링크 주의
-
자원 고갈: 리소스 한도(ulimit/cgroups) + 레이트리밋/타임아웃 + 모니터링
실무 체크리스트 (바로 적용)
-
코드: 안전 래퍼 도입, 입력 최대길이 상수화, 위험 API 금지 규칙(PR 게이트)
-
빌드:
-O2 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Werror -
런타임: 컨테이너/OS 리밋, 파일/로그 로테이션, 비정상 패턴에 자동 백오프
-
테스트: 퍼징(AFL/LibFuzzer), TOCTOU 시나리오 재현, ReDoS 입력 케이스 포함
미니 퀴즈
-
printf(user_input);형태로 메모리 쓰기까지 가능한 취약점은? -
검사 후 사용 사이에 파일이 교체되는 문제 유형은?
-
컨테이너에서 프로세스·메모리 폭주를 제어하는 대표적 수단 2가지는?
-
A1. 포맷 스트링 취약점(특히
%n) -
A2. 레이스 컨디션(TOCTOU)
-
A3. cgroups 리소스 제한, ulimit(프로세스/FD/메모리 한도)