PromleeBlog
sitemap
aboutMe

posting thumbnail
정보보안기사 - 2.2 IP 헤더 구조와 단편화(Fragmentation)
IP Header Structure and Fragmentation - InfoSec Engineer 2.2

📅

들어가기 전에 🔗

지난 2.1편에서는 네트워크 통신의 뼈대인 7계층 구조와 데이터가 포장되는 캡슐화 과정을 알아보았습니다.
이번 시간에는 3계층(네트워크 계층)에서 데이터를 포장할 때 사용하는 택배 송장, 즉
IP
(Internet Protocol) 헤더를 뜯어보겠습니다.

택배 송장에 보내는 사람, 받는 사람, 물건의 무게가 적혀 있는 것처럼,
IP
헤더에도 네트워크 통신에 필요한 필수 정보들이 빼곡하게 담겨 있습니다.
또한, 너무 큰 택배 상자는 여러 개로 나누어 보내야 하는 것처럼 네트워크에서도 큰 데이터를 잘게 쪼개는
단편화
(Fragmentation) 과정이 발생합니다.
오늘은 이 헤더의 구조와 단편화 원리, 그리고 이를 악용한 해킹 기법까지 상세하게 파헤쳐 보겠습니다.

IPv4 헤더 구조 분석 🔗

IPv4
헤더는 기본적으로 20바이트의 크기를 가지며, 여러 개의 구역(필드)으로 나뉘어 있습니다.
보안 분석가는 패킷을 가로챘을 때 이 필드들의 의미를 정확히 해석할 수 있어야 합니다.

TTL (Time To Live)의 동작 원리 🔗

TTL
(Time To Live)은 네트워크 패킷이 영원히 인터넷을 떠도는 것을 막기 위한 수명 장치입니다.
라우팅 설정이 잘못되어 패킷이 목적지를 찾지 못하고 라우터 사이를 무한히 맴도는 루핑(Looping) 현상을 방지합니다.

TTL 감소 메커니즘 🔗

  1. 패킷을 처음 생성하는 운영체제가 기본
    TTL
    값을 부여합니다. (일반적으로 윈도우는 128, 리눅스는 64를 사용합니다.)
  2. 패킷이 라우터(장비)를 하나 거칠 때마다 라우터는
    TTL
    값을 1씩 감소시킵니다.
  3. 만약 목적지에 도착하기 전에
    TTL
    이 0이 되면, 해당 라우터는 패킷을 즉시 폐기(
    Drop
    )합니다.
  4. 폐기 후, 출발지에게 "시간이 초과되어 패킷을 버렸다"라는 의미의
    ICMP Time Exceeded
    메시지를 반환합니다.

IP 단편화 (Fragmentation) 원리 🔗

네트워크 장비들은 한 번에 전송할 수 있는 최대 데이터 크기가 정해져 있습니다.
이 제한 크기를
MTU
(Maximum Transmission Unit)라고 부르며, 일반적인 이더넷 환경에서는 1500바이트입니다.
원본 데이터가 1500바이트보다 크다면, 시스템은 이를 여러 개의 작은 조각으로 잘라서 보내야 하는데 이를 단편화라고 합니다.

단편화 관련 3가지 핵심 필드 🔗

단편화 진행 예시 🔗

원래 크기가 4000바이트인 데이터를
MTU
1500바이트인 네트워크로 보낼 때의 변화를 텍스트 코드로 살펴보겠습니다.
(
IP
헤더 20바이트를 제외하면, 한 번에 보낼 수 있는 순수 데이터는 1480바이트입니다.)
[원본 패킷]
Total Length: 4000, ID: 100, MF: 0, Offset: 0

[첫 번째 조각 (Fragment 1)]
1480바이트의 데이터를 담아 전송합니다. 뒤에 조각이 더 남았으므로 MF를 1로 설정합니다.
헤더 포함 전체 길이는 1500바이트입니다.
Total Length: 1500, ID: 100, MF: 1, Offset: 0

[두 번째 조각 (Fragment 2)]
다음 1480바이트의 데이터를 보냅니다. 여전히 남은 조각이 있으므로 MF는 1입니다.
앞서 1480바이트를 보냈으므로 오프셋은 1480(실제로는 8로 나눈 185)이 됩니다.
Total Length: 1500, ID: 100, MF: 1, Offset: 185

[세 번째 조각 (마지막 조각)]
남은 1040바이트의 데이터를 보냅니다. 마지막 조각이므로 MF는 0이 됩니다.
앞서 총 2960바이트를 보냈으므로 오프셋은 2960(실제로는 8로 나눈 370)이 됩니다.
Total Length: 1060, ID: 100, MF: 0, Offset: 370
단편화 진행 구조도
단편화 진행 구조도

Ping of Death 공격과 취약점 🔗

IP
단편화 기능은 거대한 데이터를 원활하게 보내기 위해 설계되었지만, 공격자들은 이 구조를 악용하여 시스템을 파괴하는 공격 기법을 만들어냈습니다.
그 대표적인 공격이 바로
Ping of Death
입니다.

공격 원리 🔗

앞서
IP
패킷의 전체 길이를 나타내는
Total Length
필드의 최대 크기가 65,535바이트라고 설명했습니다.
과거의 윈도우나 리눅스 시스템은 "세상에 65,535바이트보다 큰 패킷은 존재할 수 없다"라고 가정하고 메모리를 할당했습니다.

공격자는 이 맹점을 노립니다.
  1. 공격자는
    ping
    명령어를 이용해 정상적인 최대 크기(65,535바이트)보다 훨씬 큰 거대한
    ICMP
    패킷을 만듭니다.
  2. 이 거대한 패킷은 단편화 원리에 의해 여러 개의 작은 조각으로 나뉘어 정상적으로 네트워크를 통과합니다.
  3. 서버(피해자)는 도착한 조각들을 모아 재조립(Reassembly)을 시도합니다.
  4. 조각을 다 합치고 나니 크기가 65,535바이트를 훌쩍 넘어버립니다.
  5. 결국 시스템이 준비해 둔 메모리 버퍼가 넘쳐흐르는
    버퍼 오버플로우
    (Buffer Overflow)가 발생하고, 서버는 다운되거나 재부팅됩니다.

개념적 파이썬 공격 스크립트 🔗

원리를 이해하기 위해 공격 패킷이 어떻게 구성되는지 파이썬 슈도(Pseudo) 코드로 확인해 보겠습니다.
ping_of_death_concept.py
 # [주의] 이 코드는 이해를 돕기 위한 가상 코드입니다.
import network_library as net
 
target_ip = "192.168.0.100"
 
 # 1. 65535바이트를 초과하는 악의적인 거대 데이터를 생성합니다.
malicious_payload = "A" * 70000 
 
 # 2. 이 데이터를 작은 조각(Fragment)으로 나눕니다.
fragments = net.fragment_data(malicious_payload, mtu=1500)
 
 # 3. 조각들을 타겟에게 연속적으로 전송합니다.
for frag in fragments:
    # 타겟 시스템은 조각을 받을 때마다 메모리에 누적하다가,
    # 결국 버퍼를 초과하여 시스템이 멈추게 됩니다.
    net.send_packet(target_ip, frag)

방어 대책 🔗

현대의 운영체제는 재조립 과정에서 패킷의 전체 크기가 65,535바이트를 넘는지 미리 검사하도록 패치되어 있어 이 공격에 안전합니다.
또한, 네트워크 앞단의 방화벽이나 침입탐지시스템(
IDS
)에서 단편화된
ICMP
패킷이 비정상적으로 많이 들어올 경우 이를 즉시 차단(
Drop
)하도록 설정하여 방어합니다.

결론 🔗

이번 시간에는 네트워크 통신의 기본 송장인
IP
헤더와 데이터 분할 정책에 대해 알아보았습니다.
데이터가 안전하게 잘게 쪼개어 전달되는 과정을 확인했으니, 다음 시간에는 이 데이터를 주고받는 양 끝단의 컴퓨터가 어떻게 서로 인사를 나누고 연결을 맺는지 알아보겠습니다.
2.3 TCP 3-Way Handshake와 Flag 분석
편에서 뵙겠습니다.

참고 🔗