
Windows DNS 트래픽을 pktmon을 통해 모니터링하여 포이즈닝, 스푸핑, 악성 리졸버 응답, 게이트웨이 MAC 변경을 탐지하고 경고를 기록하는 PowerShell 스크립트입니다.
Windows 머신 자체의 네트워크 트래픽에서 DNS 포이즈닝 / 스푸핑의 징후를 감시하는 단일 파일 PowerShell 스크립트로, Windows 10 (1809+), Windows 11, Windows Server 2019+에 내장된 패킷 캡처 도구인 pktmon을 사용합니다. 서드파티 캡처 도구(Wireshark, Npcap, tcpdump)는 필요하지 않습니다.
OS 네트워킹 스택에서 DNS 트래픽(UDP/TCP 포트 53)을 캡처하여 일반적인 머신의 LAN 및 WAN 트래픽을 모두 포괄한 다음, 원시 패킷 자체를 파싱합니다 — pcapng 바이너리 형식, Ethernet/IP/UDP/TCP 헤더, 그리고 이름 압축 포인터를 포함한 DNS 메시지 형식을 전부 네이티브 PowerShell로 처리합니다.
macOS와 Linux를 지원하는 동반 bash/tcpdump 버전도 있습니다.
| 신호 | 중요한 이유 |
|---|---|
| 동일한 DNS 쿼리에 대한 상충되는 응답 | 포이즈닝 시도의 교과서적 특징: 공격자가 위조 응답을 실제 응답과 경쟁시켜, 위조 응답이 먼저 도착해 캐시되기를 노립니다. |
| 설정한 적 없는 DNS 서버로부터의 응답 | Get-DnsClientServerAddress와 비교합니다. 인식되지 않는 서버로부터의 응답은 경로 외부(off-path) 공격자가 응답을 주입하고 있음을 나타낼 수 있습니다. |
| 대응하는 미해결 쿼리가 없는 응답 | 모니터가 질의된 것을 본 적 없는 질문에 대한 응답 — 주입/스푸핑된 트래픽의 가능한 징후입니다(오탐을 피하기 위한 시작 유예 기간 포함). |
| 세션 중 기본 게이트웨이 MAC 주소 변경 | 각 캡처 주기마다 Get-NetNeighbor를 통해 폴링합니다. ARP 스푸핑은 공격자가 LAN 내 DNS 변조를 위해 위치를 잡는 일반적인 첫 단계입니다. |
모든 경고는 두 부분을 출력합니다:
[TECHNICAL] — 추가 조사를 원하는 사람을 위한 원시 패킷 세부 정보[WHAT THIS MEANS] — 이것이 왜 중요한지에 대한 평이한 설명모든 출력은 타임스탬프가 붙은 로그 파일에도 기록됩니다.
pktmon.exe를 사용할 수 있어야 함(이들 모두에 기본 내장)pktmon pcapng는 초기 1809 릴리스 이후에 추가되었으므로, 없다면 Windows를 업데이트하세요git clone https://github.com/microlaser/dns-watchdog.git
cd dns-watchdog\windows
설치할 모듈이나 외부 종속성은 없습니다 — 스크립트 자체만 있으면 됩니다.
관리자 권한으로 상승된(elevated) PowerShell에서:
.\dns_watchdog.ps1
기본적으로 스크립트는 기본 게이트웨이와 설정된 DNS 서버를 자동 감지하고 모든 네트워크 어댑터에서 캡처합니다(pktmon은 OS 네트워킹 스택에서 동작하므로 특정 어댑터를 선택하지 않고도 자연스럽게 LAN과 WAN 트래픽을 모두 포괄합니다). Ctrl+C로 모니터링을 중지하며, 종료 시 세션 요약이 출력됩니다.
.\dns_watchdog.ps1 [-LogFile <path>] [-CaptureIntervalSeconds <n>] [-GraceResponses <n>] [-KeepCaptures]
| 매개변수 | 설명 |
|---|---|
-LogFile | 세션 로그 경로(기본값: .\dns_watchdog_<timestamp>.log) |
-CaptureIntervalSeconds | 변환 및 분석 전 각 캡처 창의 길이. 낮을수록 = 탐지 지연 감소, 오버헤드 증가. 기본값: 5 |
-GraceResponses | 시작 시 노이즈를 피하기 위해 "대응하는 쿼리 없음" 경고가 활성화되기 전에 관찰할 응답 수. 기본값: 10 |
-KeepCaptures | 분석 후 삭제하는 대신 각 창의 .etl/.pcapng 파일을 디스크에 유지 |
=========================================================================
DNS Watchdog (Windows) - DNS poisoning / spoofing monitor
=========================================================================
Capturing on: all network adapters (pktmon captures at the OS networking stack,
which covers this host's LAN and WAN traffic together)
Default gateway: 192.168.1.1 (MAC baseline: 60-95-F8-2B-5E-78)
Configured DNS: 192.168.0.1, 192.168.1.1
Log file: .\dns_watchdog_20260918_204725.log
...
[20:47:44.872] [ALERT] Conflicting DNS responses for the same query
[TECHNICAL] txn=64878 query=example.com (type 28) first_response=[AAAA:2607:f8b0:...] conflicting_response(src=10.0.0.9)=[AAAA:dead:beef::1]
[WHAT THIS MEANS] This machine's DNS question got two DIFFERENT answers back. Legitimate DNS servers don't normally do this. This is the textbook signature of a DNS poisoning attempt, where an attacker races a forged answer against the real one, hoping the forged one arrives first and gets cached.
Windows에는 tcpdump를 텍스트 파서로 파이프하는 것과 직접적으로 대응하는 기능이 없습니다 — pktmon의 실시간 콘솔 출력은 디코딩된 줄이 아니라 원시 바이트입니다. 그래서 이 스크립트는 대신 다음을 수행합니다:
pktmon을 짧은 순환 창(기본 5초)으로 실행하여 .etl로 캡처.pcapng로 변환(pktmon pcapng)알아둘 만한 특이점: Windows는 일부 스택 체크포인트에서 이더넷 헤더가 추가되기 전에 로컬에서 생성된(아웃바운드) 패킷을 자주 캡처하므로, 아웃바운드 DNS 쿼리는 링크 계층 프레이밍이 전혀 없는 순수 IP 패킷으로 도착할 수 있는 반면, 인바운드 응답은 회선에서 완전한 이더넷 프레이밍으로 도착합니다. 파서는 두 경우 모두를 감지하고 처리합니다. pktmon은 또한 동일한 물리적 패킷을 여러 번 보고하는 경향이 있습니다(네트워크 스택의 여러 지점에서 캡처됨). 스크립트는 각 캡처 창 내에서 바이트 단위로 동일한 반복을 중복 제거하여 하나의 실제 패킷에 대해 여러 번 경고하지 않도록 합니다 — 진정으로 상충되거나 포이즈닝된 응답은 내용이 다르므로 이 중복 제거의 영향을 받지 않습니다.
pktmon pcapng 변환에는 어느 정도 최신 Windows 빌드가 필요합니다. 매우 오래된 1809 시절 시스템은 대신 pktmon etl2txt로 폴백해야 할 수 있습니다(여기서는 구현되지 않음).MIT (또는 원하는 대로 업데이트하세요).