【学习笔记】tcpdump+Wireshark抓包(2)
1. TLS我们学过 HTTP 明文这个TLS 可以当成同一件事只是内容被锁进保险箱里了。之前 curlhttp://www.example.com时连的是 80 端口Wireshark 里能直接看到GET / HTTP/1.1、200 OK如果改成https://连的是 443 端口数据先 加密再放进 TCPWireshark 看不到 GET 和网页只能看到 TLS 和 Application DataHTTP 明信片谁都能读HTTPS 封信封里面写了什么抓包看不到TLS 就是那只信封和锁1.1 抓包 查看平台说明下文-i any用于 Linux可同时监听所有接口。macOS 请先执行tcpdump -D查看接口再把any替换为实际接口普通网络流量通常选择en0本机回环实验选择lo0具体以本机列表和目标流量为准。终端 1开始抓 443sudo tcpdump -i any -nn -s 0 -w ~/Desktop/https-beginner.pcap port 443只抓 443比抓全部包干净很多。终端 2关掉代理访问 HTTPSunset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY curl -v https://www.example.comcurl 之后会出现一个ip大概在如下位置用Wireshark打开刚刚的这个.pcap包然后在顶部过滤刚刚你查出来的这个IP。可以看到如下三个点Protocol 多是 TLS 或 TLSv1.2 / TLSv1.3Source/Destination 是你的电脑和 example 服务器来回端口 一边是自己另一边是 443总过程为4段No.8–10 TCP 三次握手先接通 443No.11–20 TLS 握手商量加密、交换证书、切换密文No.21–34 加密传数据Application Data里面是 HTTPNo.35–39 TCP 四次挥手断开连接1.2 找 TLS 握手包号过程11Client Hello你开始 TLS 握手声明访问www.example.comSNI14TCP ACK服务器确认收到 Client Hello15Server Hello Change Cipher Spec服务器选定加密方式并通知后续改用密钥加密16–17服务器继续发握手内容证书、握手结束等TLS 1.3 中常已加密或打包18–19你发 TCP ACK确认收到服务器握手数据20Change Cipher Spec你这边也切换为加密通信TLS 握手基本完成这一阶段 在 TCP 之上建立 HTTPS 安全通道还没传或刚开始传业务网页数据。过滤条件再加一个 tls.handshake 。版本说明下面是便于入门理解的通用握手名称。TLS 1.2 与 TLS 1.3 的具体消息和可见性不同本次抓包以 Wireshark 实际显示为准不要求在 TLS 1.3 中逐项看到 Server Hello Done 或 Client Key Exchange。直接看 Info 字段Info谁发给谁白话解释Client Hello你 → 服务器我想用 HTTPS 连你我支持这些加密方式Server Hello服务器 → 你好我们用这一种加密Certificate服务器 → 你这是我的证书证明我是正规网站Server Hello Done服务器 → 你我这边说完了Client Key Exchange 等你 → 服务器交换密钥细节可先不管Change Cipher Spec双方后面开始加密Encrypted Handshake Message双方加密的握手收尾Client Hello 包SNI 里通常是访问的域名。含义虽然 HTTP 还没开始传但客户端会先告诉服务器「我要访问www.example.com」。这是 HTTPS 抓包里少数还能直接看到域名的字段之一。此时还没有传 HTTP GET只是在商量怎么加密。Change Cipher Spec切换加密含义 通知对方从下一刻起后面数据都用刚商量好的密钥加密就像双方说好密码后说好从现在开始用这套密码说话。界面上可能写 Version: TLS 1.2 (0x0303)这是兼容写法你这次整体仍是 TLS 1.3不用纠结这个显示。1.3 加密业务数据包号过程21、22、23、25、27–30、33、34Application Data加密的 HTTP 请求、响应和网页内容24、26、31、32TCP ACK确认上面数据已收到这一阶段 真正的 HTTPS 访问发生在这里。里面是 GET、200 OK、HTML但被 TLS 加密Wireshark 只能显示 Application Data。1.4 和 HTTP 明文对照之前学过的 HTTP80 端口TCP 三次握手 ↓ 明文 HTTP GETWireshark 直接看到 ↓ 明文 HTTP 200 OK HTMLWireshark 直接看到 ↓ TCP 四次挥手现在的 HTTPS443 端口TCP 三次握手和 HTTP 一样还是 TCP ↓ TLS Client Hello / Server Hello / Certificate...多出来的 TLS 握手 ↓ TLS Application Data加密的 GET看不见 ↓ TLS Application Data加密的 200 OK HTML看不见 ↓ TCP 四次挥手多出来的就是 TLS 握手 全程加密。2. tcpdump常见命令1. 基础结构sudo tcpdump [选项] [过滤表达式]抓包一般要sudo。不写过滤表达式 抓所有流量噪音大初学建议加过滤。2. 最常用选项选项含义示例-i any指定网卡any为所有网卡tcpdump -i en0-w 文件.pcap保存到文件给 Wireshark-w ~/Desktop/out.pcap-r 文件.pcap读已有 pcap不抓新包tcpdump -r out.pcap-c 数字抓满 N 个包就停-c 100-n不把 IP 转成主机名输出更快、更干净-nn不把 IP、端口转成名字推荐常用打开已存在的 .pcap 包进行查看如 ping-gateway.pcap 。步骤 1终端中 只看 ICMPtcpdump -r ~/Desktop/ping-gateway.pcap -nn icmp你应该看到类似10.2.73.219 10.2.72.1: ICMP echo request 10.2.72.1 10.2.73.219: ICMP echo reply顺便看一下加 -nn 和不加 -nn 的区别。中间可能夹杂unreachable报错正常。步骤 2终端中 只看和网关有关的tcpdump -r ~/Desktop/ping-gateway.pcap -nn host 10.2.72.1只保留和10.2.72.1有关的包噪音少很多。# 出现类似如下结果 reading from PCAP-NG file /Users/liyijun/Desktop/ping-gateway.pcap 13:53:35.444034 IP 10.2.73.219 10.2.72.1: ICMP echo request, id 4782, seq 0, length 64 13:53:35.453132 IP 10.2.72.1 10.2.73.219: ICMP echo reply, id 4782, seq 0, length 64 13:53:36.449209 IP 10.2.73.219 10.2.72.1: ICMP echo request, id 4782, seq 1, length 64 13:53:36.454207 IP 10.2.72.1 10.2.73.219: ICMP echo reply, id 4782, seq 1, length 64 13:53:37.454194 IP 10.2.73.219 10.2.72.1: ICMP echo request, id 4782, seq 2, length 64 13:53:37.477599 IP 10.2.72.1 10.2.73.219: ICMP echo reply, id 4782, seq 2, length 64 13:53:38.456592 IP 10.2.73.219 10.2.72.1: ICMP echo request, id 4782, seq 3, length 64 13:53:38.468613 IP 10.2.72.1 10.2.73.219: ICMP echo reply, id 4782, seq 3, length 64在Wireshark中其实就是如下的过滤条件之前演示过很好理解icmp ip.addr 10.2.72.1 icmp ip.addr 10.2.72.1如果要捕捉指定端口在tcpdump里直接使用port 端口号就行。比如打开之前捕捉百度dns解析过程的文件进行演示tcpdump -r ~/Desktop/dns-test.pcap -nn port 53# 结果如下 reading from PCAP-NG file /Users/liyijun/Desktop/dns-test.pcap 15:34:16.634264 IP 10.2.73.219.57470 10.2.255.2.53: 8489 A? www.baidu.com. (31) 15:34:16.648031 IP 10.2.255.2.53 10.2.73.219.57470: 8489* 3/0/0 CNAME www.a.shifen.com., A 110.242.69.21, A 110.242.70.57 (138)但是在Wireshark里不能直接用port字段需要指定是tcp还是udpdns是udp所以要输入的过滤条件是udp.port 53若tcp也要那就在顶部同时过滤udp.port 53 || tcp.port 53-v/-vv/-vvv更详细输出终端直接看时用-A以 ASCII 显示包内容看明文 HTTP 等-X十六进制 ASCII比-A更全-s 0抓完整包默认可能截断生产环境建议加上-s 0是 tcpdump 的抓包长度选项意思是每个包都完整抓取不截断。-ssnaplen单个包最多抓多少字节0不限制抓整包常见用法sudo tcpdump -i any -nn -s 0 -w ~/Desktop/capture.pcap抓包存文件时习惯加上-s 0保证 pcap 里是完整包。读已有文件用-r时一般不需要再加-s 0。3. 常见抓包组合可直接复制抓所有包存文件sudo tcpdump -i any -w ~/Desktop/all.pcap只抓某种协议的包如 ICMPpingsudo tcpdump -i any icmp -w ~/Desktop/ping.pcap只抓 50 个包 -c 选项后面加数字sudo tcpdump -i any -c 50 -w ~/Desktop/test.pcap终端直接看不存文件如 ping sudo tcpdump -i any -nn icmp抓完整包 不解析名字sudo tcpdump -i any -nn -s 0 -w ~/Desktop/full.pcap4. 过滤表达式重点按主机和某 IP 有关的所有包源或目的sudo tcpdump -i any host 10.2.72.1只抓源是该 IPsudo tcpdump -i any src host 10.2.73.219只抓目的是该 IPsudo tcpdump -i any dst host 172.66.147.243按网段整个网段sudo tcpdump -i any net 10.2.73.0/24按端口端口 80HTTPsudo tcpdump -i any port 80端口 443HTTPSsudo tcpdump -i any port 443源端口 / 目的端口sudo tcpdump -i any src port 57872 sudo tcpdump -i any dst port 80按协议sudo tcpdump -i any tcp sudo tcpdump -i any udp sudo tcpdump -i any icmp组合与 / 或 / 非某 IP 的 TCPsudo tcpdump -i any host 172.66.147.243 and tcp80 或 443sudo tcpdump -i any port 80 or port 443排除某 IPsudo tcpdump -i any not host 127.0.0.1某 IP 的 HTTP端口80sudo tcpdump -i any host 172.12.32.78 and port 80TCP 标志进阶SYN 包握手第一步sudo tcpdump -i any tcp[tcpflags] tcp-syn ! 0# SYN 且非 ACK纯 SYNsudo tcpdump -i any tcp[tcpflags] tcp-syn ! 0 and tcp[tcpflags] tcp-ack 05. 读已有 pcap读文件并过滤tcpdump -r 文件路径/文件名.pcap port 80读文件只看前 20 个sudo tcpdump -r 文件路径/文件名.pcap -c 20读文件ASCII 显示 HTTPtcpdump -r ~/Desktop/tcp-http.pcap -A port 806. tcpdump 与 Wireshark 过滤对照目的tcpdumpWireshark某 IPhost 10.2.72.1ip.addr 10.2.72.1源 IPsrc host 10.2.73.219ip.src 10.2.73.219端口 80port 80tcp.port 80只要 TCPtcptcp只要 ICMPicmpicmp只要 DNSport 53dns3. Wireshark 常见显示过滤器显示过滤器只在已经抓好的 pcap 里筛选不改变抓包内容。语法错了会红色对了是绿色。1. 逻辑运算符符号含义示例或and并且tcp and port 80||或or或者port 80 or port 443!或not非not arp2. IP 相关源或目的包含该 IPip.addr 10.2.73.21源 IPip.src 10.2.73.21目的 IPip.des 10.2.34.56某网段部分版本支持ip.addr 10.2.73.0/243. 端口与协议过滤协议的话直接输入就行tcp # 所有 TCP udp # 所有 UDP icmp # 所有 ICMP dns # DNS http # HTTP明文 tls # TLS/HTTPS过滤端口需要指定协议tcp.port 80 # TCP 端口 80 tcp.port 443 # HTTPS tcp.srcport 57872 # 源端口 tcp.dstport 80 # 目的端口 udp.port 53 # DNS 端口4. TCP 标志握手 / 挥手 / 异常含 SYNtcp.flags.syn 1含 ACKtcp.flags.ack 1含 FIN挥手tcp.flags.fin 1RST连接被拒或重置tcp.flags.reset 1纯 SYN握手第 1 步tcp.flags.syn 1 tcp.flags.ack 0SYNACK握手第 2 步tcp.flags.syn 1 tcp.flags.ack 15. DNS下面的 qry专门指 query 部分 的字段只显示 查询域名里包含 baidu 的 DNS 包dns.qry.name contains baidu只显示 DNS 查询里域名完全等于www.example.com的包dns.qry.name www.example.com只要 querydns.flags.response 0只要 responsedns.flags.response 16. HTTP明文httphttp.request # 只要请求http.response # 只要响应只看请求方法为 GEThttp.request.method GETHost 头包含 example 的请求或响应http.host contains example只看 HTTP 响应状态码是 200 的包http.response.code 2004xx、5xx 错误http.response.code 4007. HTTPS / TLStlsClient Hello: tls.handshake.type 1Server Hellotls.handshake.type 2tcp.port 443 tls8. Wireshark 实用操作非过滤但常用操作作用右键包 → Follow → TCP Stream看一次 TCP 会话完整内容右键包 → Follow → HTTP Stream看 HTTP 请求响应全文Statistics → Conversations看哪些 IP/端口通信最多点击包 → Response in frame / Request in frame跳到配对的请求/响应4. 按场景选命令速查场景tcpdump 抓包Wireshark 查看ping 网关tcpdump -i any icmp -w ping.pcapicmp ip.addr 网关IPDNS 查询tcpdump -i any port 53 -w dns.pcapdnsHTTP 访问tcpdump -i any port 80 -w http.pcaptcp.port 80然后httpHTTPS 访问tcpdump -i any port 443 -w https.pcaptcp.port 443然后tls排查连不上tcpdump -i any host 目标IP -w fail.pcaptcp.flags.reset 1减少噪音抓包时就加host/port!ip.addr 127.0.0.1