취약점 분석/CWE

CWE-121/122: 버퍼 오버플로우(Buffer Overflow) 완전 정리 - 개념부터 실무 탐지까지

y0.0ns 2026. 7. 7. 18:06

1. 이 글에서 다루는 것

보안 뉴스나 CVE 분석 글을 읽다 보면 "버퍼 오버플로우(Buffer Overflow)" 라는 단어가 자주 등장한다. 실제로 CVSS 9.0 이상의 치명적 취약점 중 상당수가 이 유형에 해당한다. 이 글에서는 버퍼 오버플로우가 무엇인지, 왜 위험한지, 그리고 실무에서 어떻게 탐지할 수 있는지를 정리한다.


2. 버퍼 오버플로우란?

버퍼(Buffer)가 뭔지부터

버퍼란 프로그램이 데이터를 임시로 저장해두는 메모리 공간이다. 프로그램은 데이터를 처리하기 전에 일단 버퍼에 담아두고, 처리가 끝나면 비운다.

예시: DNS 응답을 받을 때
외부에서 DNS 응답 도착
        ↓
버퍼에 임시 저장 (크기: 512바이트로 미리 지정)
        ↓
프로그램이 버퍼에서 데이터를 꺼내 처리

 

오버플로우(Overflow)가 뭔지

오버플로우는 버퍼에 담을 수 있는 크기를 초과하는 데이터가 들어올 때 발생한다. 컵에 물이 넘치는 것과 같다.

버퍼 크기: 512바이트
들어온 데이터: 1024바이트

→ 512바이트를 초과한 512바이트가 버퍼 밖으로 넘쳐흐름
→ 버퍼 바로 옆에 있는 메모리 공간을 덮어씀

 

왜 위험하냐

버퍼 옆에는 프로그램이 "다음에 뭘 실행할지" 기억해두는 주소값(Return Address)이 저장되어 있다. 오버플로우로 이 주소를 덮어쓰면, 프로그램이 공격자가 원하는 코드를 실행하게 된다.

[정상 상태]
┌─────────────────────┐
│  데이터 저장 공간    │  ← 버퍼 (512바이트)
├─────────────────────┤
│  다음 실행 주소      │  ← 0x00401234 (정상 코드 주소)
│  (Return Address)   │
└─────────────────────┘

[오버플로우 발생 후]
┌─────────────────────┐
│  AAAAAAAAAAAAAAAA   │
│  AAAAAAAAAAAAAAAA   │  ← 버퍼를 초과한 데이터가 넘쳐흐름
│  AAAAAAAAAAAAAAAA   │
├─────────────────────┤
│  0xDEADBEEF         │  ← 정상 주소가 공격자 코드 주소로 덮어씌워짐
└─────────────────────┘
           ↓
프로그램이 다음 코드 실행을 위해 주소를 읽는 순간
공격자 코드로 점프

 


3. CWE 분류

버퍼 오버플로우는 발생하는 메모리 영역에 따라 두 가지로 나뉜다.

분류 CWE 번호 발생 위치 특징
스택 오버플로우 CWE-121 스택 메모리 함수 호출 시 생성되는 임시 메모리 영역에서 발생
힙 오버플로우 CWE-122 힙 메모리 프로그램 실행 중 동적으로 할당되는 메모리 영역에서 발생

스택 vs 힙 쉽게 구분하기

스택: 함수가 실행되는 동안만 쓰이는 임시 메모리. 함수가 끝나면 자동으로 사라짐

  • 힙: 프로그램이 필요할 때 직접 할당하고 해제하는 메모리. 더 유연하지만 관리가 복잡함

4. 취약점의 근본 원인

버퍼 오버플로우의 근본 원인은 입력 데이터의 크기를 검증하지 않는 것이다.

 
c
// 취약한 코드 (크기 검증 없음)
memcpy(buffer, input_data, input_size);
// input_size가 buffer 크기를 초과해도 그냥 복사

// 안전한 코드 (크기 검증 있음)
if (input_size <= buffer_size) {
    memcpy(buffer, input_data, input_size);
} else {
    // 오류 처리하고 버림
}

단 한 줄의 크기 검증이 없어서 시스템 전체가 장악될 수 있는 취약점이 만들어진다.


5. 왜 백신으로 탐지가 어려운가 (파일리스 공격)

버퍼 오버플로우 기반 공격이 특히 위험한 이유 중 하나는 파일리스(Fileless) 공격이 가능하다는 점이다.

 
일반 악성코드 공격:
공격자 코드가 .exe 파일로 디스크에 저장됨
→ 백신이 파일 스캔 → 탐지 가능

버퍼 오버플로우 공격:
공격자 코드가 네트워크 패킷 안에 담겨
메모리에 직접 올라가서 실행됨
→ 디스크에 파일이 전혀 안 남음
→ 파일 기반 백신으로는 탐지 불가

따라서 버퍼 오버플로우 기반 공격을 방어하려면 파일 기반 백신 외에도 EDR(메모리 스캔), 네트워크 이상 탐지, SIEM 기반 행위 탐지를 병행해야 한다.


6. 실제 공격 흐름 예시

버퍼 오버플로우를 이용한 공격은 보통 아래 흐름으로 진행된다.

 
1. 공격자가 취약한 프로그램에 과도하게 큰 입력값 전송
   (네트워크 패킷, 파일, 사용자 입력 등)

2. 프로그램이 크기 검증 없이 버퍼에 저장 시도
   → 버퍼 오버플로우 발생

3. 인접 메모리(Return Address)가 공격자 코드 주소로 덮어씌워짐

4. 프로그램이 다음 실행 주소를 읽는 순간
   → 공격자 코드(셸코드)로 점프

5. 공격자 코드 실행
   → 백도어 설치, 권한 상승, 내부망 이동 등

7. SOC 실무에서의 탐지 접근

버퍼 오버플로우 공격은 메모리에서 발생하기 때문에 직접 탐지가 어렵다. 대신 공격 전후 행위 패턴을 SIEM에서 탐지하는 방식이 현실적이다.

탐지 포인트 1: 비정상적으로 큰 입력값

 
spl
index=network_logs
| eval input_size_kb=round(bytes/1024, 2)
| where input_size_kb > 100
| stats count as large_input_count by src_ip, dest_ip, dest_port
| where large_input_count > 5
| sort -large_input_count

정상적인 요청에서는 수백 KB를 넘는 입력값이 반복적으로 발생하지 않는다. 짧은 시간 안에 비정상적으로 큰 데이터가 반복 전송되면 퍼징(Fuzzing) 또는 오버플로우 시도로 볼 수 있다.

 

탐지 포인트 2: 오버플로우 이후 의심 프로세스 생성

버퍼 오버플로우 성공 후 공격자는 보통 cmd, powershell 같은 프로세스를 실행해 추가 명령을 내린다.

 
spl
index=wineventlog OR index=sysmon
| where EventCode IN (4688, 1)
| eval suspicious=if(match(process_name, "(cmd\.exe|powershell|wscript|mshta)"), 1, 0)
| where suspicious=1
| stats count as suspicious_count by src_ip, process_name, parent_process_name
| where suspicious_count > 3
| sort -suspicious_count

⚠️ 인덱스명 안내: wineventlog, sysmon 은 예시로 작성한 것이다. 실제 환경의 인덱스명으로 변경 후 사용할 것.

 

탐지 포인트 3: 비정상적인 아웃바운드 연결

오버플로우 성공 후 백도어가 설치되면 C2(Command & Control) 서버로 아웃바운드 연결을 시도한다.

 
spl
index=firewall_logs
| where direction="outbound"
| where dest_port IN (4444, 8080, 9001, 1080, 31337)
| stats count as connection_count by src_ip, dest_ip, dest_port
| where connection_count > 3
| sort -connection_count

왜 저 포트들을 특정했는가:

공격자 도구들이 기본값으로 자주 사용하는 포트이기 때문이다.

포트 주로 쓰이는 도구 이유
4444 Metasploit 리버스쉘 해킹 프레임워크 Metasploit의 기본 리스닝 포트
8080 웹 프록시, 백도어 정상 HTTP(80)와 비슷해서 탐지 우회 목적으로 자주 사용
9001 Tor, Chisel 터널링 익명 통신 도구 기본 포트
1080 SOCKS 프록시 터널링 및 내부망 피버팅에 사용
31337 고전 백도어 해커 은어 "elite"를 의미하는 leet speak에서 유래

이 방식의 한계:

  • 공격자가 포트를 443(HTTPS), 80(HTTP) 같은 정상 포트로 바꾸면 탐지 불가
  • 8080은 개발 서버, 테스트 환경에서도 자주 사용되어 오탐 발생 가능

더 정확한 탐지 방법 (개선형):

특정 포트를 지정하는 것보다 "허가된 포트 외 모든 아웃바운드" 를 탐지하는 방식이 더 효과적이다. 공격자가 포트를 바꿔도 잡을 수 있기 때문이다.

 
spl
index=firewall_logs
| where direction="outbound"
| where NOT dest_port IN (80, 443, 53, 25, 465, 587)
| stats count as connection_count by src_ip, dest_ip, dest_port
| where connection_count > 3
| sort -connection_count

⚠️ 개선형 쿼리는 허용 포트 외 모든 아웃바운드를 탐지하므로 오탐이 많아질 수 있다. 자사 방화벽 정책 기준으로 허용 포트 목록을 정교하게 관리하는 것이 전제조건이다.


8. 오탐지 줄이는 팁

  • 큰 입력값 탐지: 파일 업로드 기능이 있는 서비스는 정상적으로 큰 데이터를 전송할 수 있음 → 업로드 엔드포인트는 제외하거나 임계값을 높게 설정
  • 의심 프로세스 탐지: 개발자 환경에서는 powershell, cmd가 빈번하게 실행됨 → 개발 서버 IP는 별도 처리
  • 아웃바운드 포트: 환경마다 허용된 포트가 다를 수 있음 → 자사 방화벽 정책 기준으로 비허용 포트 목록을 직접 정의

9. 대응 방법

방법 설명
패치 적용 취약점이 발견된 소프트웨어의 보안 업데이트 즉시 적용
입력값 검증 개발 단계에서 모든 입력 데이터 크기 검증 로직 추가
ASLR 메모리 주소를 랜덤하게 배치해 공격자가 Return Address를 예측하기 어렵게 만듦
DEP/NX 데이터 영역에서 코드 실행을 차단하는 하드웨어/OS 기능
스택 카나리 버퍼와 Return Address 사이에 감시값을 넣어 오버플로우 감지
EDR 도입 메모리 레벨에서 비정상 행위를 탐지하는 엔드포인트 보안 솔루션

10. 마무리

버퍼 오버플로우는 1988년 모리스 웜(Morris Worm)에서 최초로 공개적 악용이 확인된 이후 수십 년이 지난 지금도 치명적인 취약점으로 꾸준히 등장하고 있다. 근본 원인은 단순하지만(크기 검증 누락), 파일리스 공격이 가능하다는 특성 때문에 탐지와 대응이 쉽지 않다.

SOC 실무에서는 메모리 레벨의 직접 탐지보다 공격 전후의 네트워크/프로세스 행위 패턴을 SIEM으로 모니터링하는 접근이 현실적이다.

더 나은 탐지 방법이나 실제 운영 환경에서의 개선점이 있다면 댓글로 공유해주세요.


이 블로그의 관련 CVE 분석 글:


참고 자료: