메모리 공격과 방어 기법의 역사
**버퍼 오버플로우(Buffer Overflow)**는 프로그램이 데이터를 저장하기 위해 사용하는 메모리 공간(버퍼)의 크기를 초과하여 데이터를 기록할 때 발생하는 보안 취약점
**모리스 웜(Morris Worm)**은 1988년 11월 2일, 코넬 대학교 대학원생 로버트 터팬 모리스(Robert Tappan Morris)가 작성한 최초의 인터넷 웜입니다. 이 웜은 인터넷을 통해 스스로 복제하며 확산되어, 당시 인터넷에 연결된 약 10%의 컴퓨터(약 6만 대)를 감염
메모리 공격 기법
(1) 버퍼 오버플로우 (Buffer Overflow)
- 역사: 1988년 모리스 웜(Morris Worm)이 최초로 버퍼 오버플로우를 악용하며 대규모 네트워크 감염을 일으켰습니다7.
- 작동 원리: 입력 데이터가 버퍼 크기를 초과하면서 메모리의 인접 영역(예: 반환 주소)을 덮어쓰고, 이를 통해 악성 코드를 실행합니다.
- 발전: 1996년 엘리아스 레비(Aleph One)가 "스택 기반 버퍼 오버플로우"를 체계적으로 설명하며 공격 기법이 널리 알려졌습니다7.
(2) 힙 오버플로우 (Heap Overflow)
- 역사: 동적 메모리 할당 영역(힙)을 대상으로 한 공격으로, 2000년대 초반부터 주목받기 시작했습니다.
- 작동 원리: 힙 영역의 데이터 구조를 변조해 프로그램의 제어 흐름을 탈취하거나 악성 코드를 실행합니다.
(3) 인메모리 공격 (Fileless Malware)
- 역사: 2008년, 스티븐 퓨어(Stephen Fewer)가 Reflective DLL Injection을 발표하며 "파일리스(Fileless)" 공격 개념이 등장했습니다4.
- 작동 원리: 파일 시스템에 흔적을 남기지 않고 메모리에 직접 악성 코드를 주입하여 탐지를 회피합니다.
- 예시: PowerShell 스크립트를 활용한 악성 코드 실행9.
(4) Return-Oriented Programming (ROP)
- 역사: 2000년대 중반 등장한 고급 기술로, 기존 코드 조각(Gadget)을 조합하여 악성 행위를 수행합니다.
- 작동 원리: 실행 가능한 메모리 내의 코드 조각을 재배열해 새로운 기능을 구현합니다.
2. 방어 기법
(1) 스택 가드(Stack Guard)
- 역사: 1990년대 후반 도입된 기술로, 컴파일러가 스택에 "카나리 값(Canary Value)"를 삽입하여 스택 오버플로우를 탐지합니다.
- 작동 원리: 함수 종료 시 카나리 값이 변조되었는지 확인하여 공격 여부를 판단합니다.
(2) 주소 공간 배치 난수화 (ASLR)
- 역사: 2001년 리눅스에서 처음 도입된 기술로, 이후 주요 운영체제에 채택되었습니다.
- 작동 원리: 실행 파일과 라이브러리, 힙, 스택의 메모리 주소를 무작위화하여 공격자가 정확한 주소를 예측하기 어렵게 만듭니다.
(3) 데이터 실행 방지 (DEP)
- 역사: 2004년 윈도우 XP SP2에서 처음 도입되었습니다.
- 작동 원리: 특정 메모리 영역(예: 스택, 힙)의 실행 권한을 제한하여 악성 코드 실행을 차단합니다.
(4) Control Flow Integrity (CFI)
- 역사: 2010년대 이후 연구 및 구현이 활발히 진행되었습니다.
- 작동 원리: 프로그램의 제어 흐름이 사전에 정의된 경로를 벗어나지 않도록 보장합니다.
(5) EDR 및 XDR 솔루션
- 역사: 2010년대 중반부터 엔드포인트 탐지 및 대응(EDR), 확장 탐지 및 대응(XDR)이 널리 사용되기 시작했습니다.
- 작동 원리: 실시간으로 메모리 활동을 모니터링하고 비정상적인 행동을 탐지하여 차단합니다
c, c++ 취약점
대상 : 웹 브라우저, 도커 하이퍼바이저엔진, 운영체제 등 많은 것들이 C와 C++로 사용되고 있다.
1. 주요 취약점 유형
(1) 버퍼 오버플로우 (Buffer Overflow)
- 설명: 고정된 크기의 메모리 버퍼보다 더 많은 데이터를 쓰거나 읽으려 할 때 발생.
- 영향: 프로그램 비정상 종료, 악성 코드 실행, 민감 데이터 유출.
- 예시: 사용자 입력 길이를 확인하지 않고 strcpy 같은 함수 사용.
(2) 사용 후 해제 (Use-After-Free, UAF)
- 설명: 해제된 메모리를 참조하는 경우 발생.
- 영향: 메모리 변조, 악성 코드 실행.
- 원인: 동적 메모리 해제 후 포인터를 초기화하지 않음.
(3) 메모리 누수 (Memory Leak)
- 설명: 동적으로 할당된 메모리를 해제하지 않아 자원이 고갈됨.
- 영향: 시스템 성능 저하, 장기 실행 프로그램의 불안정성.
- 원인: new와 delete 또는 malloc과 free의 부적절한 사용.
(4) 타입 안전성 부족
- 설명: 잘못된 타입 캐스팅이나 포인터 연산으로 인해 발생.
- 영향: 예기치 않은 동작, 데이터 손상.
- 원인: C++의 포인터와 강타입 언어 특성이 충돌할 때 발생.
(5) 포인터 연산 오류
- 설명: 잘못된 주소 계산으로 인한 메모리 접근 문제.
- 영향: 민감 데이터 노출, 프로그램 충돌.
- 예시: 잘못된 오프셋 계산으로 배열 경계를 넘어서는 접근.
2. 취약점의 근본 원인
- 직접적인 메모리 관리 요구:
- C/C++는 프로그래머가 메모리를 직접 할당 및 해제해야 하므로 실수 가능성이 높음.
- 낮은 수준의 제어:
- 메모리에 직접 접근할 수 있는 포인터와 같은 기능이 강력하지만 위험함.
- 표준 라이브러리의 제한적 보호 기능:
- 기존 표준 라이브러리는 메모리 안전성을 보장하지 않음
3. 대응 방안
(1) 안전한 코딩 관행
- 사용자 입력 길이 검증 및 경계 검사 수행.
- 포인터 초기화 및 사용 후 NULL로 설정.
(2) 정적 분석 도구 활용
- Clang Static Analyzer, Coverity 등 도구를 사용해 코드 내 취약점을 사전에 탐지.
(3) 최신 기술 적용
- 강화된 라이브러리 사용:
- 구글은 '강화된 libc++'를 도입해 공간 메모리 안전성을 개선하고 취약점 40%를 차단했다고 발표.
- 메모리 안전 언어로 전환:
- Rust와 같은 메모리 안전 언어로 전환을 고려.
(4) 런타임 보호 기법
- 주소 공간 배치 난수화(ASLR): 메모리 주소를 무작위화하여 공격 난이도 증가.
- 데이터 실행 방지(DEP): 실행 권한이 없는 영역에서 코드 실행 차단.
(5) 교육 및 코드 리뷰 강화
- 개발자들이 C/C++의 메모리 관리 문제를 이해하고 이를 방지하기 위한 교육 실시.
'kmooc > 메모리 익스플로잇-해킹과 방어' 카테고리의 다른 글
해킹이란 무엇일까? (0) | 2025.02.24 |
---|