Step 84. Wireshark 2 — 프로토콜 파헤치기와 이상 탐지

Step 84. Wireshark 2 — 프로토콜 파헤치기와 이상 탐지

Level 1 — 프로그래밍과 컴퓨터 내부 | 난이도 ★★★☆☆ | 예상 소요 시간 3시간

전제: Step 83을 마쳤다. Wireshark(또는 tshark)로 캡처하고 필터를 걸 수 있다. Step 81의 nmap 스캔을 할 수 있다.

  • 준비물: Wireshark와 내 랩. tshark가 있으면 명령줄로도 전부 재현됩니다.
  • 주의: ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. 스캔 실험의 대상도 127.0.0.1뿐입니다. 이 챕터의 모든 패킷 출력은 2026-09-09에 WSL 리눅스(TShark 4.2.2)에서 실측했고, GUI 화면 설명은 "화면 예시"입니다.

의사가 병을 알아보려면 먼저 건강한 몸을 알아야 합니다. 네트워크도 같습니다. "이상한 패킷"을 찾으려면 "정상적인 패킷"이 어떻게 생겼는지부터 알아야 합니다. 오늘은 TCP, DNS, HTTP의 정상적인 모습을 현미경으로 하나씩 파헤치고, 마지막에는 Step 81의 nmap 스캔을 일부러 일으켜 그것이 패킷 목록에서 어떤 얼굴로 보이는지 확인합니다. 공격의 발자국을 자기 손으로 찍고 자기 눈으로 보는 실험입니다.


1. 학습 목표

이 챕터를 끝내면 다음을 할 수 있습니다:

  • TCP 3-way 핸드셰이크를 실제 캡처에서 세 패킷으로 찾아낸다
  • DNS 질문-대답 한 쌍의 정상 모양을 설명한다
  • HTTP 요청-응답의 필드를 패킷 상세에서 읽는다
  • 스캔 트래픽의 "서명"을 패킷 목록에서 식별한다
  • 이상의 세 얼굴 — 짝 없는 대답, 비정상적 빈도, 상식 밖 내용 — 을 적용한다

2. 배경 지식 — 오늘의 도구와 개념

오늘의 도구 한눈에 보기

구분 내용
언어·환경 Wireshark(GUI) 또는 tshark(명령줄), 리눅스 터미널
오늘의 도구 디스플레이 필터 조합(and/or), 패킷 상세 창, tshark -Y/-T fields, 트래픽 발생용 curl·파이썬·nmap
필요한 개념 TCP 플래그(SYN/ACK/RST), DNS 질의응답, HTTP 요청/응답, Step 80의 패킷 계층
오늘의 산출물 "프로토콜 정상 파일" — 세 규약의 정상 모습과 이상 징후를 정리한 노트

2-1. TCP — 악수로 시작하는 대화

모든 TCP 대화는 3-way 핸드셰이크(세 악수)로 시작합니다. SYN(시작합시다) → SYN-ACK(좋습니다, 시작하죠) → ACK(확인했습니다). Step 80에서 손으로 만들던 그 의식입니다. 정상의 모양: 세 패킷이 번개처럼 연속하고, 그 뒤에 데이터가 오갑니다.

2-2. DNS — 전화번호부 검색

DNS(Domain Name System)example.com 같은 이름을 숫자 주소로 바꿔 줍니다. 정상의 모양은 깔끔한 한 쌍입니다 — Query(질문) 하나, Response(대답) 하나. 이상 징후의 예: 질문도 안 했는데 대답이 오거나(DNS 포이즈닝의 그림자), 같은 이름을 미친 듯이 반복해서 묻는 트래픽입니다.

2-3. HTTP — 요청과 응답의 쌍

요청(GET /)과 응답(200 OK)의 쌍입니다. 평문이라면 헤더와 본문까지 전부 읽힙니다. 오늘은 이 대화를 캡처에서 짝 맞춰 봅니다.

2-4. 이상 탐지의 사고법

세 규약에 공통되는 감별 원리는 하나입니다. 질문과 대답의 짝이 맞는가. 정상 통신은 항상 짝이 있습니다. 질문 없는 대답, 대답 없는 질문의 폭주, 내용이 상식 밖인 대답 — 이 셋이 이상의 대표 얼굴입니다. 이 원리 하나로 오늘의 모든 실험을 읽을 수 있습니다.


3. 따라 하기

3-1. 세 악수 찾기 — 책 속 그림의 실물 확인

내 컴퓨터 안에 연습 서버(python3 -m http.server 8000)를 열고, 캡처하면서 접속해 봅니다.

입력

tshark -i lo -f "tcp port 8000" -c 6 -w handshake.pcap
# 다른 터미널에서:
curl -s http://127.0.0.1:8000/ > /dev/null

출력 (2026-09-09 실측):

    1 0.000000000    127.0.0.1 → 127.0.0.1    TCP 74 52398 → 8000 [SYN] Seq=0 Win=65495 Len=0
    2 0.000022753    127.0.0.1 → 127.0.0.1    TCP 74 8000 → 52398 [SYN, ACK] Seq=0 Ack=1
    3 0.000031640    127.0.0.1 → 127.0.0.1    TCP 66 52398 → 8000 [ACK] Seq=1 Ack=1
    4 0.000140725    127.0.0.1 → 127.0.0.1    HTTP 143 GET / HTTP/1.1
    5 0.000144004    127.0.0.1 → 127.0.0.1    TCP 66 8000 → 52398 [ACK] Seq=1 Ack=78
    6 0.001643067    127.0.0.1 → 127.0.0.1    TCP 251 HTTP/1.0 200 OK  [TCP segment of a reassembled PDU]

읽는 법: 1~3번이 세 악수입니다. 임시 포트(52398)에서 8000번으로 [SYN], 서버가 [SYN, ACK], 다시 [ACK]. 시각(Time) 열을 보세요 — 세 악수 전체가 0.03밀리초 만에 끝납니다. 그리고 4번에서야 비로소 GET이라는 "말"이 나옵니다. 악수하고 나서야 대화가 시작되는 의식의 순서가 실물로 확인됐습니다.

: "접속한다"는 한 번의 행위 아래에서 벌어지는 일의 순서를 목격하는 단계입니다. 이 그림이 눈에 익으면, 악수만 수백 번 하고 말은 없는 이상한 트래픽(3-4의 스캔)이 확 튀어 보입니다.

3-2. DNS 한 쌍 잡기

입력

tshark -i any -f "udp port 53" -a duration:8 -w dns.pcap
# 다른 터미널에서:
python3 -c "import socket; print(socket.gethostbyname('www.khan.co.kr'))"

출력 (2026-09-09 실측):

    1 0.000000000 10.255.255.254 → 10.255.255.254 DNS 76 Standard query 0x68b3 A www.khan.co.kr
    2 0.007112111 10.255.255.254 → 10.255.255.254 DNS 184 Standard query response 0x68b3 A www.khan.co.kr CNAME ... A 23.216.159.194 A 23.216.159.203

읽는 법: 질문 한 줄, 대답 한 줄입니다. Standard query 0x68b3 A www.khan.co.kr은 "이름의 A 레코드(IPv4 주소)를 알려 주세요"이고, 대답에는 주소 두 개가 들어왔습니다. 질문과 대답의 번호(0x68b3)가 같은 것 — 이 번호가 짝을 맞추는 표입니다. 주소가 10.255.255.254끼리인 것은 WSL의 내부 DNS 창구를 거치기 때문으로, 일반 리눅스에서는 내IP → 공유기 모양으로 보입니다.

: 인터넷의 모든 여정이 이 작은 질의응답으로 시작됩니다. 그리고 DNS는 평문입니다 — 누가 어떤 이름을 물었는지가 길목에서 다 보인다는 사실도 함께 기억하세요.

막히면: 운영체제가 DNS 결과를 저장해 두는(캐시) 경우 질문 자체가 안 나갑니다. 처음 묻는 이름으로 시도하세요.

3-3. HTTP 필드 대조 실험

입력 (캡처 파일에서)

tshark -r raw.pcap -Y http -T fields -e frame.number -e http.request.method -e http.host -e http.request.uri -e http.response.code

출력 (2026-09-09 실측):

4	GET	127.0.0.1:8000	/	
8				200
16	POST	127.0.0.1:8000	/login	
20				501

읽는 법: 4번(GET /)과 8번(200)이 한 쌍, 16번(POST /login)과 20번(501)이 한 쌍입니다. GUI에서라면 4번 패킷을 클릭하고 상세 창의 Hypertext Transfer Protocol 층을 펼치세요 — Host, User-Agent 줄이 있고 그 아래 TCP, IP 층이 차례로 있습니다 (화면 예시). curl로 보던 봉투가 패킷 안에 문자 그대로 실려 있습니다.

: 추상(프로토콜 명세)과 실측(캡처)이 하나로 맞물리는 확인입니다. 요청에는 항상 응답이 따라오는 짝의 규칙도 다시 보입니다.

3-4. 예측해 보기 — 스캔 트래픽은 어떻게 생겼을까

예측입니다. 이 컴퓨터에서 127.0.0.1을 향해 nmap SYN 스캔(-sS, 포트 1~30)을 돌리면, 패킷 목록에는 어떤 그림이 나타날까요? 색, 간격, 패턴을 상상해 적어 두세요.

직접 확인

tshark -i lo -a duration:10 -w scan.pcap
# 다른 터미널에서:
sudo nmap -sS -p 1-30 127.0.0.1

출력 (2026-09-09 실측, 앞부분):

    1 0.000000000    127.0.0.1 → 127.0.0.1    TCP 58 48622 → 21 [SYN] Seq=0 Win=1024 Len=0
    2 0.000017080    127.0.0.1 → 127.0.0.1    TCP 54 21 → 48622 [RST, ACK] Seq=1 Ack=1
    3 0.000025431    127.0.0.1 → 127.0.0.1    TCP 58 48622 → 25 [SYN] Seq=0 Win=1024 Len=0
    4 0.000026888    127.0.0.1 → 127.0.0.1    TCP 54 25 → 48622 [RST, ACK] Seq=1 Ack=1
    5 0.000030221    127.0.0.1 → 127.0.0.1    TCP 58 48622 → 22 [SYN] Seq=0 Win=1024 Len=0
    6 0.000031494    127.0.0.1 → 127.0.0.1    TCP 54 22 → 48622 [RST, ACK] Seq=1 Ack=1
    ...

읽는 법: 하나의 출발지 포트(48622)가 목적지 포트를 21, 25, 22, 23, … 으로 바꿔 가며 [SYN]만 연발하고, 대답은 전부 [RST, ACK](닫힘)입니다. 세 악수가 완성되는 대화가 하나도 없습니다. 이것이 스캔의 얼굴입니다 — 정상 대화는 절대 이렇게 생기지 않습니다.

: 여러분이 직접 찍은 발자국입니다. 공격 도구의 트래픽이 방어자의 화면에서 어떻게 보이는지를 알면, "이상 탐지"가 추상이 아니라 패턴 인식이 됩니다. 예측과 비교해 보세요.

3-5. 필터 조합 — 첫인사만 세기

스캔의 서명을 필터 문장으로 옮겨 봅니다.

입력

tshark -r scan.pcap -Y "tcp.flags.syn == 1 and tcp.flags.ack == 0" | wc -l
tshark -r raw.pcap  -Y "tcp.flags.syn == 1 and tcp.flags.ack == 0" | wc -l
tshark -r scan.pcap -Y "tcp.flags.reset == 1" | wc -l

출력 (2026-09-09 실측):

30    # scan.pcap의 SYN-only(첫인사) 개수
2     # raw.pcap(정상 curl 두 번)의 SYN-only 개수
30    # scan.pcap의 RST(닫힘 응답) 개수

읽는 법: and로 조합한 필터가 "SYN이고 ACK가 아닌 패킷" — 대화의 첫인사만 골라냅니다. 30포트 스캔 파일에는 첫인사가 30개, 정상 접속 두 번짜리 파일에는 2개. 그리고 그 첫인사 30개 전부가 RST로 거절당했습니다. 같은 목적지에 첫인사만 쏟아지는 패턴, 그것이 스캔입니다.

: 필터 문법은 검색어 이상입니다. "어떤 패턴이 이상인가"를 문장으로 옮기는 기술이며, 이것이 그대로 침입 탐지 규칙 작성의 기초가 됩니다.

3-6. 이상의 세 얼굴 정리

오늘 실험들을 감별 원리로 묶어 봅니다.

  • 짝 없는 대답: 질문도 없는 DNS 응답, "공유기는 나야"라는 ARP 응답의 폭주(ARP 스푸핑의 얼굴 — 이 책의 Level 2에서 랩 재현으로 해부합니다).
  • 비정상적 빈도: 3-4의 SYN 연발처럼, 정상에서는 절대 안 나오는 밀도.
  • 상식 밖 내용: 묻지도 않은 이름의 주소, 있을 수 없는 크기의 응답.

해보기: 오늘 만든 캡처 파일들(handshake.pcap, dns.pcap, scan.pcap)을 Wireshark GUI로도 열어 보세요. 같은 파일이 GUI에서는 색으로 물든 목록이 되고, 패킷을 클릭하면 계층이 펼쳐집니다 (화면 예시). 도구가 달라도 패턴은 같습니다.


4. 미션과 연습문제

미션 — 프로토콜 정상 파일 작성

  1. TCP, DNS, HTTP 각각에 대해 "정상의 한 쌍"을 캡처에서 찾아, 패킷 번호와 핵심 필드를 베껴 적습니다.
  2. 각 규약의 이상 징후를 한 줄씩 정의합니다 (짝 없는 대답 / 폭주 / 상식 밖 내용 중 해당하는 것).
  3. nmap 스캔을 일으켜 그 패턴을 캡처하고, "스캔의 서명"을 세 가지 특징으로 요약합니다.
  4. 조합 필터를 하나 직접 만들고, 무엇을 골라내는 필터인지 주석을 답니다.
  5. 마지막 문단: "정상을 아는 것이 왜 이상을 보는 눈의 전부인가"를 오늘 실험을 근거로 씁니다.

연습문제

문제 1. TCP 대화에서 [SYN] 세 개가 연속하고 [SYN, ACK]가 하나도 없다면 어떤 상황일까요?

문제 2. DNS 질문과 대답이 한 쌍인지 확인하려면 패킷의 어떤 값을 비교해야 하나요?

문제 3. 스캔의 서명 세 가지(출발지, 목적지 포트, 대화 완성 여부)를 문장으로 말해 보세요.

문제 4. 디스플레이 필터 tcp.flags.syn == 1 and tcp.flags.ack == 0가 골라내는 것은 무엇이며, 이 필터가 "스캔 탐지의 씨앗"인 이유는 무엇인가요?


5. 모범 답안과 완료 기준

미션 모범 답안

정상 한 쌍의 기록 예 (2026-09-09 실측 값):

[TCP] handshake.pcap 1~3번: [SYN] → [SYN, ACK] → [ACK], 총 0.03밀리초. 그 뒤 4번 GET.
[DNS] dns.pcap 1~2번: query 0x68b3 A www.khan.co.kr → response 0x68b3 (같은 번호가 짝의 증거).
[HTTP] raw.pcap 4번+8번: GET / ↔ 200 OK. 16번+20번: POST /login ↔ 501.

스캔의 서명 세 가지 (2026-09-09 실측에서 도출): ① 하나의 출발지 포트가 목적지 포트만 바꿔 가며 SYN을 연발한다. ② 세 악수가 완성되는 대화가 없다 — 대답이 전부 RST-ACK(닫힘)이다. ③ 단위 시간당 첫인사 밀도가 정상의 수십 배다 (스캔 파일 SYN-only 30개 vs 정상 파일 2개).

조합 필터 예: tcp.flags.syn == 1 and tcp.flags.ack == 0 and ip.src == 10.0.0.5 — "10.0.0.5가 뿌린 첫인사만" 골라내는 필터.

검증하는 법: ① 세 규약의 "정상 한 쌍"이 패킷 번호와 함께 기록됐는가. ② 스캔 서명이 세 가지로 요약됐는가. ③ 직접 만든 조합 필터에 주석이 달렸는가.

연습문제 해답

문제 1 해답. 대상이 응답하지 않는 상황입니다 — 꺼져 있거나, 방화벽이 패킷을 조용히 버리거나(filtered), 해당 포트가 없습니다. nmap으로 치면 "응답 없음" 상태이며, 같은 SYN을 몇 번 재전송하는 것도 TCP의 정상 동작입니다.

문제 2 해답. 트랜잭션 ID(질의 번호)입니다. 실측에서 질문과 대답 모두 0x68b3로 찍혀 있었습니다. 이 번호가 같아야 같은 대화의 짝입니다 — 질문도 안 한 번호의 대답이 오면 그것이 곧 이상입니다.

문제 3 해답. 한 출발지에서 목적지 포트를 바꿔 가며 SYN(첫인사)만 연발하고, 세 악수가 완성되는 대화는 하나도 없으며, 응답은 대부분 RST-ACK(닫힘)입니다. 정상 대화는 몇 안 되는 포트에 깊게 이어지지만, 스캔은 많은 포트에 얕게 스칩니다.

문제 4 해답. "SYN이고 ACK가 아닌" 패킷 — 즉 대화의 첫인사(SYN-ACK에는 ACK도 서 있으므로 제외됨)만 골라냅니다. 스캔과 정상 접속 모두 첫인사로 시작하므로, 이 필터 위에서 출발지별·시간당 개수를 세면 밀도 이상이 바로 드러납니다 (실측: 스캔 파일 30개 vs 정상 파일 2개). 그래서 이 한 줄이 탐지 규칙의 씨앗입니다.

완료 기준 체크리스트

  • [ ] 캡처에서 세 악수 세 패킷을 찾아낼 수 있다
  • [ ] DNS 질문과 대답의 짝을 트랜잭션 ID로 확인할 수 있다
  • [ ] HTTP 요청-응답의 짝을 필드 추출로 맞출 수 있다
  • [ ] 스캔 트래픽의 서명을 세 가지로 요약할 수 있다
  • [ ] and/or 조합 필터를 직접 만들 수 있다
  • [ ] 미션: 프로토콜 정상 파일을 완성했다

6. 흔한 실수와 해결

벽 1. DNS가 안 잡혀요

증상: 이름 해석을 했는데 dns 필터에 안 나옵니다.

원인: 운영체제가 DNS 결과를 저장해 두는(캐시) 경우 질문 자체가 안 나갑니다. 또는 암호화된 DNS(DoH)를 쓰는 환경일 수 있습니다. 실측 환경(WSL)에서도 첫 시도는 캐시와 내부 창구 때문에 eth0에서 안 잡혀, 캐시를 비우고 -i any로 잡아야 했습니다 (2026-09-09).
해결: 처음 묻는 이름으로 시도하고, 인터페이스를 넓혀 보세요(-i any). DoH 환경이라면 "암호화된 DNS는 목록에 안 보인다"는 것 자체가 관찰 결과입니다.

벽 2. 캡처가 끝나질 않아요

증상 (2026-09-09 실측): tshark -i lo -c 30 -w raw.pcap을 걸었는데 30개가 안 차서 tshark가 계속 기다립니다. 루프백은 조용해서 패킷이 잘 안 생깁니다.

원인: -c 개수 조건은 그 개수가 채워져야 끝납니다.
해결: 시간 조건을 쓰세요 — -a duration:6(6초 후 자동 종료). 또는 트래픽 발생(curl)과 캡처의 순서를 맞추세요.

벽 3. 패킷이 전부 까만색이에요

증상: GUI 목록에 검정 줄이 가득합니다 (화면 예시).

원인: 검정은 보통 재전송(TCP Retransmission) 등의 주의 표시입니다. 가상 네트워크 환경에서는 환경 특성으로 생기기도 합니다.
해결: 공황 상태일 필요는 없습니다. 다만 "왜 재전송이 많은가"를 묻는 것이 분석의 시작이라는 것만 기억하세요. View → Coloring Rules에서 색의 뜻을 확인할 수 있습니다.

벽 4. 스캔 패턴인지 정상인지 구분이 안 돼요

증상: SYN이 많은 건 스캔인데, 브라우저도 연결을 많이 여는 것 같습니다.

원인: 정상 프로그램도 연결을 여러 개 엽니다. 구분의 핵심은 "같은 목적지에 포트를 바꿔 가며"인가입니다.
해결: 목적지 포트 기준으로 정렬해 보세요. 스캔은 포트가 순차적으로 변하고(21, 22, 23…), 정상은 몇 개 안 되는 포트에 대화가 깊습니다. 3-5의 첫인사 세기 필터가 정량적 판별을 도와줍니다.

벽 5. 세 악수가 두 줄밖에 없어요

증상: [SYN] 뒤에 바로 데이터가 옵니다.

원인: 캡처가 대화 중간에 시작돼 악수를 놓쳤거나, 필터가 일부를 가렸습니다.
해결: 캡처를 먼저 시작하고 접속하세요. 필터를 잠시 지우고 그 연결의 전체를 보세요 — 악수가 파일에 있는지부터 확인합니다.


7. 정리

오늘의 개념

개념 한 줄 설명
3-way 핸드셰이크 SYN → SYN-ACK → ACK. 말은 악수 다음에 나온다
트랜잭션 ID DNS 질문-대답의 짝표 — 번호가 같아야 한 쌍
이상의 세 얼굴 짝 없는 대답 / 비정상적 빈도 / 상식 밖 내용
스캔의 서명 한 출발지 + 포트 바꾸는 SYN 연발 + RST 응답 + 미완성 대화
시그니처 알려진 공격 패턴의 목록 — 오늘의 "서명 세 가지"가 수제 시그니처

오늘의 명령어·필터

명령·필터 하는 일
tshark -i lo -f "tcp port 8000" 8000번 대화만 캡처
tshark -r 파일 -Y dns DNS 패킷만 보기
tshark -r 파일 -T fields -e ... 원하는 필드만 표로 추출
tcp.flags.syn == 1 and tcp.flags.ack == 0 대화의 첫인사만 골라내기
tcp.flags.reset == 1 닫힘 응답만 골라내기
`필터 wc -l`

명령어보다 중요한 감각

오늘 배운 "질문과 대답의 짝" 원리는 고가의 보안 장비들도 쓰는 기본 논리입니다. 침입 탐지 시스템의 규칙 상당수가 결국 "짝 없는 대답", "비정상적 빈도", "상식 밖 내용"을 찾아냅니다 — 여러분은 오늘 그 규칙들의 마음을 손으로 익혔고, 자기 손으로 찍은 스캔 발자국으로 검증까지 했습니다.

HTTPS가 기본인 시대에는 내용을 읽는 탐지가 어려워지고, 대신 "내용 없이 보이는 것들" — 상대방 주소, 통신의 크기와 리듬, 빈도 — 으로 이상을 찾는 행위 분석이 커지고 있습니다. 오늘의 패턴 읽기는 그 시대에도 그대로 쓰이는 기초 체력입니다. 그리고 이 모든 관찰이 내 랩의 트래픽에서만 이뤄졌다는 사실 — 그 경계선이 이 기술의 사용 면허임을 다시 새겨 둡니다.


전부 체크되면 Step 84 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.