外观
网络嗅探与Wireshark协议分析
约 2000 字大约 7 分钟
网络安全技术网络嗅探Wireshark协议分析
2026-05-17
本课核心
网络嗅探(Packet Sniffing,指捕获并分析网络数据包)不是“看网页内容”的魔法,而是把 TCP 握手、HTTP 请求、DNS 查询这些网络层面的证据保存下来,再用 Wireshark 或命令行工具逐包复盘。本课只分析本机和课堂靶机流量。
课堂红线
所有抓包操作仅限本机、Kali WSL 与课堂靶机。禁止抓取他人网络、公共 WiFi、校园网或生产环境流量。
故事引入:为什么抓包能看到请求
当浏览器或 curl 访问一个 HTTP 服务时,系统会先建立 TCP 连接,再发送 HTTP 请求行和 Header,服务器随后返回响应。未加密 HTTP 的请求行、Header 和响应头都能在 pcap 证据中看到;HTTPS 的应用层内容会被 TLS 加密,抓包只能看到握手和加密后的载荷。
💻 客户端
🕵️ 抓包节点
🖥️ 服务端
理论基础:嗅探不是“全部都能看到”
| 场景 | 能否被动看到他人流量 | 原因 |
|---|---|---|
| Hub 共享式网络 | 能 | Hub 会把帧广播到所有端口 |
| Switch 交换式网络 | 默认不能 | 交换机按 MAC 表转发,只送到目标端口 |
| ARP 欺骗后 | 可能能 | 攻击者把流量路径诱导到自己身上 |
| SPAN 端口镜像 | 能 | 管理员授权复制流量给监控端口 |
混杂模式(Promiscuous Mode,网卡接收非本机目标帧的工作模式)只解决“网卡愿不愿意收”的问题;如果交换机根本没有把帧转发到你的端口,混杂模式也看不到。
工具准备
本机 Kali WSL 已带有 tcpdump、curl、dig 和 nmap。如果课堂要求使用命令行版 Wireshark,再补装 tshark;本课真实输出使用已存在的 tcpdump 完成复现。
command -v tcpdump
command -v curl
command -v dig
command -v nmap
command -v tshark || echo "tshark not found, install only when needed"
# 仅当上面提示 tshark 不存在且课堂必须使用 tshark 时执行
sudo apt install -y tshark真实输出:
/usr/bin/tcpdump
/usr/bin/curl
/usr/bin/dig
/usr/bin/nmap
tshark not found, install only when needed输出解释: tcpdump 负责抓包和读取 pcap;curl 负责产生 HTTP 流量;dig 负责产生 DNS 查询;nmap 负责产生端口扫描流量。tshark 当前环境未安装,因此文档不再把它作为必跑命令。
实战一:抓取一次 HTTP 请求
先启动一个只绑定本机的 HTTP 服务。WSL 环境里存在本机代理变量,所以访问本机靶机时要给 curl 加 --noproxy "*",避免请求绕到代理端口。
rm -rf /tmp/lesson11-www
mkdir -p /tmp/lesson11-www
printf "lesson11 packet capture target\n" > /tmp/lesson11-www/index.html
cd /tmp/lesson11-www
python3 -m http.server 9999 --bind 127.0.0.1 >/tmp/lesson11-http.log 2>&1 &
echo $! > /tmp/lesson11-http.pid
curl --noproxy "*" -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9999真实输出:
200输出解释: 200 表示 Python HTTP 服务可访问。--bind 127.0.0.1 让服务只监听本机,避免课堂靶机暴露到其他网络。
启动抓包并产生 HTTP 请求:
sudo tcpdump -i any -w /tmp/http-capture.pcap -c 11 port 9999 &
echo $! > /tmp/lesson11-tcpdump.pid
curl --noproxy "*" -v -H "X-Test: HelloSniffer" http://127.0.0.1:9999/ 2>&1 | sed -n "1,28p"
wait "$(cat /tmp/lesson11-tcpdump.pid)"真实输出(curl 节选):
* Trying 127.0.0.1:9999...
* Established connection to 127.0.0.1 (127.0.0.1 port 9999) from 127.0.0.1 port 47530
* using HTTP/1.x
> GET / HTTP/1.1
> Host: 127.0.0.1:9999
> User-Agent: curl/8.19.0
> Accept: */*
> X-Test: HelloSniffer
>
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.13.12
< Date: Mon, 18 May 2026 03:05:36 GMT
< Content-type: text/html
< Content-Length: 31
lesson11 packet capture target输出解释: > 开头的是客户端发出的 HTTP 请求,< 开头的是服务器响应。自定义 Header X-Test: HelloSniffer 能在抓包里被看到,说明未加密 HTTP 的请求头是明文。
读取 pcap 文件:
tcpdump -nn -r /tmp/http-capture.pcap | sed -n "1,12p"
tcpdump -A -nn -r /tmp/http-capture.pcap \
| grep -E "GET /|Host:|User-Agent:|X-Test:|HTTP/1\.0 200"真实输出(包摘要):
11:05:52.136732 loopback0 Out IP 127.0.0.1.48022 > 127.0.0.1.9999: Flags [S], seq 2608812194, length 0
11:05:52.137047 loopback0 Out IP 127.0.0.1.9999 > 127.0.0.1.48022: Flags [S.], seq 2732145618, ack 2608812195, length 0
11:05:52.137359 loopback0 Out IP 127.0.0.1.48022 > 127.0.0.1.9999: Flags [.], ack 1, length 0
11:05:52.137412 loopback0 Out IP 127.0.0.1.48022 > 127.0.0.1.9999: Flags [P.], seq 1:101, ack 1, length 100
11:05:52.138246 loopback0 Out IP 127.0.0.1.9999 > 127.0.0.1.48022: Flags [P.], seq 1:187, ack 101, length 186真实输出(明文载荷):
GET / HTTP/1.1
Host: 127.0.0.1:9999
User-Agent: curl/8.19.0
X-Test: HelloSniffer
HTTP/1.0 200 OK输出解释: [S]、[S.]、[.] 对应 TCP 三次握手;[P.] 是携带应用层数据的包。tcpdump -A 会以 ASCII 方式打印载荷,因此能看到 HTTP 请求头。
🌐 网络接口
💾 硬盘 (PCAP文件)
💻 Wireshark 屏幕
捕获过滤器过滤规则: 拒绝 SSH
显示过滤器过滤规则: 不看 SSH
HTTP 流量
SSH 流量
DNS 流量
实战二:追踪 DNS 查询
WSL 的默认 DNS 隧道不一定能被普通接口稳定捕获,所以这里显式向阿里公共 DNS 223.5.5.5 查询,保证 pcap 中能看到 UDP 53。
sudo tcpdump -i any -w /tmp/dns-capture.pcap -c 2 udp port 53 &
echo $! > /tmp/lesson11-dns.pid
dig @223.5.5.5 www.baidu.com +short +time=2 +tries=1
wait "$(cat /tmp/lesson11-dns.pid)"
tcpdump -nn -r /tmp/dns-capture.pcap真实输出:
www.a.shifen.com.
111.45.11.5
183.240.99.224
11:07:16.930517 eth2 Out IP 192.168.30.6.45326 > 223.5.5.5.53: 7659+ A? www.baidu.com. (54)
11:07:16.946163 eth2 In IP 223.5.5.5.53 > 192.168.30.6.45326: 7659 3/0/1 CNAME www.a.shifen.com., A 111.45.11.5, A 183.240.99.224 (104)输出解释: 第一行包是查询,A? www.baidu.com. 表示询问 IPv4 地址;第二行包是响应,返回了一个 CNAME 和两个 A 记录。DNS 查询默认是明文 UDP,因此域名会直接出现在抓包里。
当前进度: 0 / 5 - 准备就绪
💻 客户端
🖥️ 服务端
📦 数据包详细解析 (Hex / ASCII)
请点击“下一步”开始发送数据包...
实战三:分析端口扫描流量
为了避免依赖额外 Docker 镜像,靶机用本机 Python HTTP 服务模拟 3 个开放端口,再用 nmap 扫描 8078-8085。
for port in 8081 8082 8083; do
mkdir -p "/tmp/lesson11-www-$port"
printf "lesson11 service on %s\n" "$port" > "/tmp/lesson11-www-$port/index.html"
(cd "/tmp/lesson11-www-$port" && python3 -m http.server "$port" --bind 127.0.0.1 >/tmp/lesson11-$port.log 2>&1 & echo $! > "/tmp/lesson11-$port.pid")
done
ss -tlnp | grep -E ":808[123]"
sudo nmap -sT -Pn -p 8078-8085 127.0.0.1真实输出(监听端口):
LISTEN 0 5 127.0.0.1:8081 0.0.0.0:* users:(("python3",pid=1757,fd=3))
LISTEN 0 5 127.0.0.1:8082 0.0.0.0:* users:(("python3",pid=1762,fd=3))
LISTEN 0 5 127.0.0.1:8083 0.0.0.0:* users:(("python3",pid=1765,fd=3))真实输出(nmap):
Starting Nmap 7.99 ( https://nmap.org ) at 2026-05-18 11:10 +0800
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00057s latency).
PORT STATE SERVICE
8078/tcp closed unknown
8079/tcp closed unknown
8080/tcp open http-proxy
8081/tcp open blackice-icecap
8082/tcp open blackice-alerts
8083/tcp open us-srv
8084/tcp closed websnp
8085/tcp closed unknown输出解释: open 表示端口完成了 TCP 连接;closed 表示主机可达但端口没有服务。8080 是当前环境里已有的本机映射端口,8081-8083 是本课临时启动的服务。
抓取扫描过程并统计 SYN 包:
sudo tcpdump -i any -w /tmp/scan-capture.pcap -c 16 "tcp and portrange 8078-8085" &
echo $! > /tmp/lesson11-scan.pid
nmap -sT -Pn -p 8078-8085 127.0.0.1 >/tmp/lesson11-nmap-capture.txt
wait "$(cat /tmp/lesson11-scan.pid)"
tcpdump -nn -r /tmp/scan-capture.pcap "tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0" | sed -n "1,12p"真实输出:
11:10:14.277462 loopback0 Out IP 127.0.0.1.45702 > 127.0.0.1.8080: Flags [S], length 0
11:10:14.277476 loopback0 Out IP 127.0.0.1.47616 > 127.0.0.1.8081: Flags [S], length 0
11:10:14.277485 loopback0 Out IP 127.0.0.1.46896 > 127.0.0.1.8082: Flags [S], length 0
11:10:14.277493 loopback0 Out IP 127.0.0.1.45254 > 127.0.0.1.8085: Flags [S], length 0
11:10:14.277499 loopback0 Out IP 127.0.0.1.48224 > 127.0.0.1.8078: Flags [S], length 0
11:10:14.277506 loopback0 Out IP 127.0.0.1.47746 > 127.0.0.1.8079: Flags [S], length 0
11:10:14.277512 loopback0 Out IP 127.0.0.1.45140 > 127.0.0.1.8083: Flags [S], length 0
11:10:14.277518 loopback0 Out IP 127.0.0.1.45210 > 127.0.0.1.8084: Flags [S], length 0输出解释: 短时间内连续向多个目标端口发送 SYN,是端口扫描最明显的流量特征。真实 IDS 通常会把“同一源地址在短时间内探测多个端口”作为扫描告警条件。
课后任务
- 用 Wireshark 打开
/tmp/http-capture.pcap,标出 TCP 三次握手、HTTP 请求、HTTP 响应三个阶段。 - 改用 HTTPS 网站抓包,对比为什么看不到明文 Header 和响应内容。
- 扫描 1-1000 端口并统计 SYN 包数量、开放端口数量、关闭端口数量。
- 编写一个
pcap-summary.sh,输入 pcap 文件后输出总包数、Top 5 目标端口和出现过的协议。
实验环境快速恢复
kill "$(cat /tmp/lesson11-http.pid)" 2>/dev/null
for port in 8081 8082 8083; do
kill "$(cat "/tmp/lesson11-$port.pid")" 2>/dev/null
done
rm -rf /tmp/lesson11-www /tmp/lesson11-www-*
rm -f /tmp/http-capture.pcap /tmp/dns-capture.pcap /tmp/scan-capture.pcap
rm -f /tmp/lesson11-*.pid /tmp/lesson11-*.log /tmp/lesson11-nmap-capture.txt