7 분 소요

📦 DDoS 완전정복 6부작 — DDoS가 무엇이고 공격이 어떻게 분류되는지 큰 그림을 그리고(1편), 대역폭을 말려버리는 볼류메트릭·반사증폭 공격(2편), 연결 테이블을 터뜨리는 프로토콜·상태 고갈 공격(3편), 정상 요청처럼 굴며 서버를 태우는 애플리케이션 계층(L7) 공격(4편), 이 모든 걸 탐지하고 막아내는 방어·완화(5편), 그리고 세운 방어가 실제로 버티는지 내 사이트에서 합법적으로 검증하는 내성 테스트(6편)까지 이어집니다. 전체 6편.
  1. DDoS 완전정복 — 개념과 공격 지형도
  2. 볼류메트릭·반사증폭 공격 — 대역폭을 말려버리는 방법지금 글
  3. 프로토콜·상태 고갈 공격 — 연결 테이블을 터뜨리기
  4. 애플리케이션 계층(L7) 공격 — 정상 요청처럼 굴며 서버를 태우기
  5. DDoS 방어와 완화 — 탐지부터 스크러빙까지
  6. 내 사이트 DDoS 내성 테스트 — 합법적으로, 제대로

Summary

1편에서 DDoS의 큰 지형도를 훑었다면, 이번 글은 그중에서도 가장 원초적이면서 여전히 제일 흔한 유형인 볼류메트릭(volumetric) 공격을 다룹니다. 이름 그대로 “부피”로 승부하는 공격이에요. 서버의 로직이나 세션 테이블을 노리는 게 아니라, 회선 자체를 물로 가득 채워 정상 트래픽이 들어올 자리를 없애버립니다. 특히 출발지 IP를 위조해 남의 서버로 트래픽을 튕기는 반사·증폭 기법은 작은 요청으로 거대한 응답을 만들어내기 때문에, 공격자 입장에서는 가성비가 아주 좋은 무기랍니다. 방어자 관점에서 원리를 하나씩 뜯어볼게요.

💡 이 글에서 다루는 것

  • 볼류메트릭 공격의 본질: bps와 pps로 회선을 포화시키기
  • UDP 플러드와 ICMP 플러드가 자원을 갉아먹는 방식
  • 출발지 IP 스푸핑을 이용한 반사(reflection)의 구조
  • 증폭 계수(amplification factor)와 대표 증폭 벡터 정리
  • memcached·Mirai 사례가 남긴 교훈과 카펫 폭격·워터토처



1. 볼류메트릭 공격이란 — 파이프를 물로 채우기

볼류메트릭 공격의 목표는 단순명료합니다. 피해자에게 연결된 네트워크 회선의 대역폭을 트래픽으로 가득 채워서 포화시키는 거예요. 물이 흐르는 파이프를 상상하면 이해가 빠릅니다. 파이프 굵기가 정해져 있는데 누군가 밖에서 물을 계속 밀어넣으면, 정작 안에서 흘러야 할 정상적인 물이 지나갈 자리가 사라져 버립니다.

이 공격을 평가할 때는 두 가지 지표를 봅니다. 하나는 초당 비트 수를 뜻하는 bps(bits per second)로, 회선의 굵기 자체를 얼마나 채웠는지를 나타내요. 다른 하나는 초당 패킷 수인 pps(packets per second)로, 라우터나 방화벽이 처리해야 할 패킷 개수가 얼마나 폭주하는지를 보여줍니다.

큰 덩어리 패킷으로 bps를 밀어붙이는 공격도 있고, 아주 작은 패킷을 어마어마하게 많이 뿌려서 pps로 장비의 CPU를 태우는 공격도 있어요. 어느 쪽이든 결과는 같습니다. 정상 사용자의 요청이 회선이나 장비 앞에서 막혀버리고, 서비스는 응답 불능 상태에 빠지게 됩니다.



2. UDP 플러드

UDP 플러드는 볼류메트릭 공격의 가장 고전적인 형태예요. 왜 하필 UDP를 쓰는지부터 짚어볼게요. UDP는 무상태(stateless) 프로토콜이라 연결을 맺는 과정이 없습니다. TCP처럼 3-way 핸드셰이크로 “너 진짜 있니?”를 확인하는 절차가 없으니, 공격자는 그냥 패킷을 던지기만 하면 됩니다. 확인 절차가 없다는 건 위조하기도 쉽다는 뜻이에요.

공격자는 피해 서버의 여러 포트, 특히 아무 서비스도 열려 있지 않은 랜덤한 포트로 UDP 패킷을 대량으로 쏟아붓습니다. 그러면 서버는 매 패킷마다 “이 포트에는 아무 애플리케이션도 없는데?”라고 판단하고, 규약에 따라 출발지로 ICMP Destination Unreachable(port unreachable) 응답을 돌려주려 애씁니다.

아래는 이 흐름을 개념적으로만 표현한 의사 다이어그램이에요.

공격자 ──(UDP, 랜덤 목적지 포트)──▶ 피해 서버
피해 서버: 해당 포트에 서비스 없음 확인
피해 서버 ──(ICMP port-unreachable 생성 시도)──▶ (위조된 출발지)
      └ 매 패킷마다 이 과정을 반복 → CPU·대역폭 소모

패킷 하나하나는 별것 아니지만, 초당 수십만·수백만 개가 밀려들면 서버는 없는 포트를 확인하고 에러 응답을 만드느라 자원을 계속 태우게 됩니다. 게다가 출발지 IP가 위조되어 있으면 그 ICMP 응답은 엉뚱한 곳으로 날아가고, 공격자는 흔적도 남기지 않아요.



3. ICMP(Ping) 플러드

ICMP 플러드는 우리가 흔히 “핑”이라 부르는 ICMP Echo Request 패킷을 폭주시키는 공격입니다. 원래 핑은 상대가 살아 있는지 확인하려고 던지는 아주 가벼운 진단 도구예요. 정상적으로는 한 번 보내고 한 번 응답받으면 끝나는 소소한 대화입니다.

문제는 이 진단 패킷을 초당 어마어마한 양으로 밀어넣을 때 생깁니다. 피해 서버는 들어오는 Echo Request마다 Echo Reply를 만들어 돌려주려 하고, 이 과정에서 들어오는 대역폭과 나가는 대역폭이 동시에 소모돼요. 요청을 받아들이는 회선과 응답을 내보내는 회선이 양쪽에서 함께 막히는 셈이죠.

여기에 출발지 IP를 위조하는 기법이 얹히면 응답이 엉뚱한 방향으로 튀면서 추적이 어려워집니다. ICMP 플러드는 원리가 워낙 단순해서 요즘은 라우터나 방화벽 단에서 ICMP 속도 제한(rate limit)으로 상당 부분 걸러내지만, 대량의 봇넷이 동원되면 여전히 회선을 압박할 수 있는 위협으로 남아 있어요.



4. 반사(reflection)의 원리

여기서부터가 이 글의 핵심입니다. 앞서 계속 등장한 “출발지 IP 위조(스푸핑)”가 반사 공격의 뼈대예요. UDP는 연결 확인 절차가 없기 때문에, 공격자가 패킷을 보낼 때 출발지 IP 칸에 자기 주소 대신 피해자의 주소를 적어넣을 수 있습니다. 받는 서버는 그 주소가 진짜인지 검증할 방법이 마땅치 않아요.

공격자는 이 위조 패킷을 인터넷에 공개된 제3의 서버, 즉 반사서버(reflector)로 보냅니다. 반사서버는 지극히 정상적으로 동작할 뿐이에요. 요청이 들어왔으니 응답을 돌려줄 뿐인데, 그 응답의 목적지가 위조된 출발지, 곧 피해자가 되는 겁니다.

아래 다이어그램으로 흐름을 정리했어요.

[공격자]
   │  출발지 IP = 피해자로 위조한 요청
   ▼
[반사서버(정상 서버)]  ← DNS/NTP/memcached 등 공개 UDP 서비스
   │  "요청이 왔으니 응답을 보낸다"
   ▼
[피해자]  ← 자기가 요청한 적 없는 응답 폭탄을 받음

이 구조의 무서운 점은 두 가지입니다. 첫째, 피해자 입장에서 트래픽의 출처는 공격자가 아니라 수많은 정상 서버들이라 원흉을 특정하기 어려워요. 둘째, 공격자는 반사서버 뒤에 완전히 숨어버립니다. 피해자가 보는 IP 목록에는 공격자 주소가 단 하나도 없거든요.



5. 증폭(amplification) — 작은 질문, 거대한 응답

반사만으로도 성가시지만, 여기에 증폭이 결합되면 위력이 폭발적으로 커집니다. 증폭의 핵심 개념은 요청 대비 응답의 크기 비율이에요. 이걸 증폭 계수(amplification factor)라고 부릅니다.

공격자가 아주 작은 요청 패킷을 반사서버에 보냈는데, 반사서버가 그 요청에 대해 훨씬 큰 응답을 만들어 피해자에게 돌려준다면, 공격자는 적은 대역폭을 투자해 훨씬 많은 트래픽을 피해자에게 쏟아부을 수 있게 됩니다. 60바이트짜리 질문에 4,000바이트짜리 대답이 돌아온다면 증폭 계수는 대략 60배가 넘는 셈이에요.

왜 하필 UDP 기반 서비스가 표적이 될까요. 이유는 앞서 계속 나온 그대로입니다. UDP는 연결 확인이 없어 출발지를 위조하기 쉽고, 그중에서도 “작게 묻고 크게 답하는” 성질을 가진 서비스들이 존재하기 때문이에요. 이런 서비스들이 인터넷에 무방비로 열려 있으면 곧바로 증폭 발판이 됩니다.

⚠️ 증폭 공격의 근본 대책은 두 갈래예요. 하나는 네트워크 사업자가 출발지 위조 패킷을 걸러내는 것(BCP 38 기반 출발지 검증)이고, 다른 하나는 공개될 필요가 없는 UDP 서비스를 인터넷에 노출하지 않는 것입니다.



6. 대표 증폭 벡터

대표적으로 악용돼 온 증폭 프로토콜을 정리했어요. 증폭 계수는 서비스 설정과 데이터에 따라 크게 달라지므로 대략적인 범위로 봐주세요.

프로토콜 포트 대략 증폭계수
DNS 53 28~54x
NTP(monlist) 123 최대 ~556x
memcached 11211 10,000~51,000x
CLDAP 389 56~70x
SSDP 1900 ~30x
chargen 19 ~358x
SNMP 161 ~6x

표를 보면 memcached의 계수가 압도적으로 튄다는 걸 알 수 있어요. memcached는 원래 웹 애플리케이션의 데이터를 임시로 저장해두는 내부용 캐시 서버입니다. 인터넷에 노출될 이유가 전혀 없는데도 과거에 기본 설정으로 UDP 11211 포트가 열린 채 방치된 서버가 많았어요. 여기에 작은 요청을 던지면 캐시에 저장된 대용량 데이터가 그대로 응답으로 튀어나오면서, 만 배 단위의 극단적인 증폭이 일어났습니다.

NTP의 monlist 역시 유명한 사례예요. monlist는 해당 NTP 서버에 최근 접속한 클라이언트 목록을 돌려주는 오래된 진단 명령인데, 목록이 길면 짧은 요청 하나에 수백 배 크기의 응답이 돌아왔습니다. DNS는 증폭 계수 자체는 상대적으로 낮지만 공개 리졸버가 워낙 많아 여전히 흔하게 악용되고, CLDAP·SSDP·chargen 같은 오래된 프로토콜도 방치된 장비를 발판 삼아 꾸준히 등장하고 있어요.



7. 실제 사례가 남긴 교훈

숫자가 얼마나 커질 수 있는지는 실제 사례가 잘 보여줍니다. 아래 수치는 모두 공개 보고서 기준의 대략적인 규모예요.

2018년에는 memcached 증폭을 이용한 공격이 세상에 충격을 줬습니다. 공개 보고서 기준으로 대략 1.3~1.7Tbps 규모의 트래픽이 관측됐는데, 이는 당시로서는 기록적인 수준이었어요. 만 배가 넘는 증폭 계수를 가진 서비스가 인터넷에 열려 있으면 어떤 일이 벌어지는지를 극적으로 보여준 사건이었죠. 이 사건 이후 “캐시 서버 같은 내부용 UDP 서비스는 절대 인터넷에 열지 말라”는 원칙이 상식으로 자리 잡았습니다.

2016년의 Dyn 사건은 결이 조금 다릅니다. 이건 증폭보다는 Mirai 봇넷이 동원된 대규모 트래픽 공격이었어요. Mirai는 기본 비밀번호가 그대로 남은 IP 카메라나 공유기 같은 IoT 기기를 대량으로 감염시켜 만든 봇넷이었습니다. 주요 DNS 서비스 업체를 겨냥하자, 그 DNS에 의존하던 수많은 유명 서비스가 한꺼번에 접속 불능에 빠졌어요. 방향은 달라도 교훈은 통합니다. 관리되지 않고 방치된 장치와 서비스가 결국 공격의 연료가 된다는 점이에요.

정리하면 memcached를 인터넷에 여는 순간 그 서버는 내 자원이 아니라 남을 때리는 무기가 됩니다. 내가 피해자가 아니어도, 내 관리 소홀이 누군가의 공격 발판이 될 수 있다는 감각이 중요해요.



8. 카펫 폭격과 워터토처(랜덤 서브도메인)

최근 볼류메트릭 공격은 탐지를 피하려고 좀 더 교묘해졌습니다. 두 가지 변형을 소개할게요.

첫 번째는 카펫 폭격(carpet bombing)이에요. 예전 공격은 하나의 목표 IP에 트래픽을 집중시켰기 때문에, 그 IP 하나만 유심히 보면 임계치를 금방 넘어서 탐지가 됐습니다. 카펫 폭격은 반대로 움직여요. 한 조직이 보유한 /24 대역, 즉 254개 주소 전체에 트래픽을 얇게 골고루 흩뿌립니다. 개별 IP만 보면 각각은 임계치를 넘지 않아 조용해 보이지만, 대역 전체를 합산하면 회선이 이미 포화 상태인 거예요. 그래서 IP 단위가 아니라 네트워크 대역 전체를 묶어서 보는 탐지가 필요해집니다.

두 번째는 DNS 워터토처(water torture)로, 랜덤 서브도메인 공격이라고도 불러요. 공격자는 랜덤문자열.피해도메인.com 처럼 존재하지 않는 무작위 서브도메인을 끝없이 질의합니다. 이 질의를 받은 리졸버는 캐시에 답이 없으니 매번 피해 도메인의 권한 있는 네임서버(authoritative server)까지 물어보러 가요. 결국 피해자의 DNS 서버가 존재하지도 않는 이름을 조회하느라 자원을 소진하고 응답 능력을 잃게 됩니다. 물방울이 한 방울씩 떨어져 결국 사람을 지치게 한다는 고문에서 이름을 따온 만큼, 개별 질의는 작아도 누적되면 치명적이에요.



마치며

볼류메트릭 공격은 기술적으로 가장 단순한 축에 속하지만, 그래서 오히려 가장 끈질기게 살아남은 유형이기도 해요. 핵심은 대역폭이라는 유한한 자원을 어떻게 고갈시키느냐에 있고, 반사와 증폭이라는 두 개념이 그 위력을 몇 배로 끌어올린다는 점이었습니다. 방어자 입장에서 기억할 건 명확해요. 출발지 위조를 걸러내는 네트워크 위생과, 열려 있으면 안 될 UDP 서비스를 닫아두는 관리가 절반 이상을 해결합니다.

일단 오늘은 여기까지…..
다음 글에서는 대역폭이 아니라 연결 테이블을 터뜨리는 프로토콜·상태 고갈 공격으로 넘어갈게요.



← 이전 글: (1/6) DDoS 완전정복 — 개념과 공격 지형도다음 글 →: (3/6) 프로토콜·상태 고갈 공격 — 연결 테이블을 터뜨리기


참고: Cloudflare Learning — Memcached DDoS attack · CISA Alert TA14-017A — UDP-Based Amplification Attacks · Cloudflare — DNS amplification attack