简介:面向信息安全技术应用专业的SSH协议分析教学文档,以「单兵模式分组对抗赛题资源3」为背景,紧密贴合网络协议分析课程实训、技能竞赛备赛及安全运维初学者的学习需求。文档系统梳理SSH协议三个核心阶段:密钥交换阶段重点讲解客户端与服务器各自发送公钥列表、协商匹配加密算法等细节;用户认证阶段覆盖none方式探测、密码认证与公钥认证流程;加密数据传输阶段说明会话建立后命令加密传输与结果返回机制。同时给出基于WireShark的完整分析路径:从配置Ubuntu与CentOS主机IP、启动抓包过滤,到实际登录SSH服务,逐步观察TCP三次握手、SSH版本信息、密钥交换初始化与密钥交换消息、加密数据流以及TCP断开连接等关键报文,每一步都对应预备知识中的协议过程,便于对照验证。资源包为docx文档共1个文件,压缩包约37KB,轻量易用。已有111人学习浏览,适合信息安全专业学生、实训教师及对网络协议抓包分析感兴趣的入门者下载参考。
1. 直接用 WireShark 拆 SSH 协议:从握手到加密数据传输的完整抓包实战
做信息安全或者网络运维的,几乎天天都要跟 SSH 打交道,但真正问起“SSH 连接时两端到底交换了什么、密钥怎么协商出来的、密码是怎么传过去的”,能答清楚的人不多。这份《通过 WireShark 进行 SSH 协议分析》的实训资源,就是用来解决这个问题的——它不是给你讲一堆协议 RFC 的抽象概念,而是把 SSH 协议的工作过程拆成算法协商、密钥交换、用户认证、服务请求、数据传输、连接关闭六个阶段,然后带着你在 WireShark 里一步一步抓包、逐包对照分析。适合正在学网络协议分析的信息安全专业学生,也适合想补强协议底层认知的运维和安服工程师——毕竟抓包分析这件事,光看文档学不会,必须有能照着操作的步骤和能对上号的报文特征,这份资源恰好把两边都补齐了。
2. SSH 协议的三阶段模型:算法协商、密钥交换与用户认证是怎么串联的
2.1 算法协商:客户端和服务器的“能力清单”是怎么对齐的
SSH 连接建立的第一个阶段是传输层协议握手,眼前要解决的事情就一件:通信双方得先确认彼此都支持哪些算法,然后从中挑出一套双方都认的组合。资源里对这部分讲得很细:SSH 协议支持多种密钥交换算法(比如 diffie-hellman-group-exchange-sha256、ecdh-sha2-nistp256 这一类)、多种加密算法(3des-cbc、aes128-ctr、aes256-gcm 等)、多种 MAC 算法(hmac-md5、hmac-md5-96、hmac-sha1、hmac-sha1-96 等)。因为不同客户端和服务端对这些算法的支持情况不一样,所以必须有一个协商过程来对齐双方的能力。
协商的逻辑其实不复杂,可以理解成“客户端出题、服务端匹配”:客户端把自己支持的算法列表按优先顺序发给服务端,服务端从客户端的列表第一个算法开始,逐个在自己的支持列表里查找,匹配上就用这个,匹配不上就继续看客户端的下一个,直到成功或者全部失败。这个规则适用于每一类算法——密钥交换算法、加密算法、MAC 算法都是这么一个个协商出来的。如果某一类算法全部匹配失败,整个 SSH 连接就直接断掉,不会进入后续阶段。这套机制在实际抓包里对应的是 SSH_MSG_KEXINIT 消息,客户端和服务端各发一条,报文里能看到完整的算法列表,是分析 SSH 握手的第一个关键观察点。
2.2 密钥交换:不传密钥本身,却能让双方拿到同一把会话密钥
算法协商完成之后,紧跟着就是密钥交换。这一步的设计意图很明确:后续的数据加密需要一把对称密钥,但这把密钥不能直接在网络上传输,否则第三方截获了就全完了。所以 SSH 协议用的是 Diffie-Hellman 类的密钥交换算法——通信双方各自生成私钥,通过交换公开参数计算出一个共享密钥。即使第三方把交换过程中的报文全部抓下来,也无法推算出最终的密钥,因为离散对数问题在计算上不可行。这就是资源里强调的“安全动态生成交互密钥”的含义。
在实际抓包里,这一步会看到 SSH_MSG_KEXDH_INIT(客户端发起,携带自己的公钥材料)和 SSH_MSG_KEXDH_REPLY(服务端回复,携带服务端公钥和签名)。这两条报文之后,双方各自计算出共享密钥 K 和会话标识符 H,后续所有的加密通信都基于这把会话密钥。分析抓包时要注意:这时候看到的载荷如果是明文结构的协议消息,说明密钥交换还没完成;一旦进入加密阶段,WireShark 识别出来的就不再是具体的 SSH 消息类型了,而是统一的“Encrypted packet”或类似标识——这正是区分密钥交换阶段和加密传输阶段的分水岭。
2.3 用户认证:none 探测、密码与公钥的完整判定逻辑
密钥交换完成之后进入用户认证阶段。资源里把认证过程展开成了五个步骤,每一步对应报文里的一段交互逻辑。第一步是客户端先发一个认证方式为“none”的请求,这个请求本身就是一种探测——看看服务端到底要求哪些认证方式。第二步是服务端收到 none 请求后,回复一个认证挑战报文,里面携带服务端支持、且要求该用户完成的认证方式列表。
第三步和第四步是核心:客户端从服务端给的列表里挑一种方式,发起真正的认证请求。密码认证就是传用户名加密码,由服务端比对设备本地或远程认证服务器上的记录;公钥认证则分两个阶段——先验证公钥本身是否合法,再验证客户端用私钥对特定数据做的数字签名。这里有个容易忽略的点:如果公钥不合法,认证直接失败;公钥合法但签名验证不过,同样失败。第五步是服务端根据该用户配置决定认证是否结束,一条路径是认证成功且不需要其他方式,直接回复成功;另一条路径是认证成功但还要继续其他认证,会再发挑战;还有两种情况是认证失败后继续尝试,或者累计失败次数达到上限后服务端直接断开连接。抓包分析时,报文里的 SSH_MSG_USERAUTH_REQUEST 和 SSH_MSG_USERAUTH_FAILURE / SSH_MSG_USERAUTH_SUCCESS 可以完整还原这段判断过程。
3. 实训环境搭建与抓包准备:双虚拟机拓扑、IP 规划与 WireShark 过滤条件
3.1 拓扑与 IP 配置:Ubuntu 与 CentOS 双机互联
这份实训资源的实验拓扑是两台 Linux 虚拟机:一台 Ubuntu 作为 SSH 客户端,一台 CentOS 作为 SSH 服务端。资源里明确写了 IP 规划:Ubuntu 配置为 192.168.x.x(对应 IPA),CentOS 配置为另一网段的 IPB,两个地址在同一个虚拟网络里互联互通。实操时我一般习惯用 VMware 的自定义 NAT 或仅主机模式,让两台虚拟机处于同一子网,确保能 ping 通再往下走。
在 Ubuntu 上配置 IP 的常见做法是直接改 netplan 配置(新版 Ubuntu)或者用 /etc/network/interfaces(老版本),CentOS 上则可以用 nmcli 或直接改 ifcfg 文件。下面给一个 Ubuntu 侧的最小配置示例(假设网卡名为 ens33,网段 192.168.10.0/24):
# Ubuntu 客户端,编辑 /etc/netplan/01-network-manager-all.yaml network: version: 2 renderer: networkd ethernets: ens33: addresses: - 192.168.10.10/24 gateway4: 192.168.10.1 nameservers: addresses: [192.168.10.1]配置完执行sudo netplan apply生效,用ip addr确认地址已经绑上。CentOS 侧同理,把地址配成同网段的另一个地址(比如 192.168.10.20/24),确保两端能互通。这里有个实践细节:虚拟机的网络模式决定了抓包能不能看到 SSH 流量,桥接模式下流量会走物理交换机,NAT 模式下包要经过虚拟网关,通常建议用 NAT 或仅主机模式来减少无关广播流量,让 WireShark 的过滤结果更干净。
3.2 启动 WireShark 并配置过滤条件:只留 SSH 流量
抓包前先想清楚要过滤什么。SSH 服务默认跑在 TCP/22 端口,如果抓包的时候同时有其他网络活动,捕获窗口里会混进 ARP、DNS、NTP 等各种噪声包。配置过滤条件的方法是在 WireShark 主界面上方的显示过滤器栏里输入过滤表达式。两种做法:捕获过滤器(Capture Filter)在开始抓包之前设置,语法是tcp port 22,这样网卡驱动层面就只把 22 端口的包交上来,能显著降低抓包文件体积;显示过滤器(Display Filter)在抓完包之后设置,语法是tcp.port == 22,适合已经抓了全量流量、事后过滤的场景。
我一般推荐把两种都做一遍:先设好捕获过滤器,确保抓到的东西足够纯净;分析过程中再用显示过滤器做二次筛选,比如只看某个 TCP 流的包。捕获过滤和显示过滤的语法容易混淆,前者是 BPF 语法、没有等号,后者是 Wireshark 的 DSL、字段后面跟==。下面是对应的配置方式:
# 捕获过滤器(Capture Options -> Capture Filter) tcp port 22 # 显示过滤器(Filter 栏直接输入) tcp.port == 22 && ip.addr == 192.168.10.10 # 只看 SSH 协议层消息,不看底层 TCP 确认包 ssh注意显示过滤器里ip.addr ==匹配的是源或目标任一地址,如果想要严格的单向流量,需要写成ip.src == 192.168.10.10或ip.dst == 192.168.10.10。另外,ssh这个过滤器只匹配被 WireShark 识别为 SSH 协议层的报文,而 SSH 流量在 TCP 层之上,如果先输入tcp.port == 22再叠加&& ssh,可以把底层的 TCP ACK 包过滤掉,只留下真正有协议内容的包,分析阶段这样用非常顺手。
3.3 从 Ubuntu 发起 SSH 登录并抓取完整交互过程
环境准备好之后就可以开始抓包了。打开 WireShark,选择承载虚拟机流量的网卡接口(VMnet8 或 eth0 之类的虚拟网卡),先启动捕获,再从 Ubuntu 终端向 CentOS 发起 SSH 登录请求:
# 在 Ubuntu 客户端发起 SSH 连接 ssh 192.168.10.20 # 首次连接会提示确认主机指纹,输入 yes 继续 # 然后输入 CentOS 对应用户的密码完成登录这里的交互过程本身就是一次完整的 SSH 协议演示:输入ssh命令触发 TCP 三次握手,然后立即进入 SSH 版本交换、算法协商、密钥交换、用户认证四个关键阶段。登录成功后如果执行几条命令再退出,还能抓到服务请求和数据传输阶段的报文。建议多抓几轮——第一次登录抓认证过程,登录后执行ls、whoami等命令抓数据传输过程,exit退出抓连接关闭过程。一轮抓完点停止捕获,Ctrl+S 保存为 pcapng 文件,后续分析就不用反复重做实验了。养成“抓完就存”的习惯很重要,因为虚拟机环境里的会话状态随时可能变化,重新复现一次握手并不总是一模一样的节奏。
4. 六步拆解 SSH 会话:从 TCP 三次握手到四次断开的报文对照分析
4.1 整体报文序列:六个分析点对应的包特征
资源里的实训步骤把 SSH 协议分析划分成六个阶段:TCP 建立连接、SSH 服务版本信息、密钥交换初始化消息、密钥交换消息、加密数据、TCP 断开连接。对应到 WireShark 的报文列表里,每个阶段有明确的标志性报文,搞清楚“阶段 → 报文特征”的映射关系,分析的时候就不用从头到尾翻包了。下面这张表把六个阶段的观察要点列出来,对照表里的线索在报文列表里逐包核对就行:
| 分析阶段 | 标志性报文 | 关键字段或特征 | 观察目的 |
|---|---|---|---|
| TCP 建立连接 | SYN / SYN-ACK / ACK 三条包 | TCP 三次握手标志位、序号 | 确认连接建立的完整性和方向 |
| SSH 版本信息 | Protocol 版本交换报文 | 明文 banner,如 SSH-2.0-OpenSSH_7.4 | 识别两端 SSH 实现与版本 |
| 密钥交换初始化 | SSH_MSG_KEXINIT | 算法列表、cookie 随机数 | 分析协商过程与算法优先级 |
| 密钥交换消息 | KEXDH_INIT / KEXDH_REPLY | 公钥材料、签名、DH 参数 | 理解共享密钥如何生成 |
| 加密数据 | 加密后的 application data | 已加密,WireShark 无法解析内部结构 | 确认加密生效及加密算法 |
| TCP 断开连接 | FIN / FIN-ACK / ACK 四条包 | TCP 四次挥手标志位 | 确认会话正常关闭 |
表里这几个特征在抓包里非常显眼:TCP 建立连接的三条包是所有会话的开端,在 WireShark 里标记为 SYN、SYN-ACK、ACK 的包特别好认;SSH 版本信息是 SSH 连接里第一条协议层报文,内容是完全明文的;KEXINIT 之后的包进入密钥交换,报文大小一般比较大,KEXDH_REPLY 里能看到服务端签名信息;再往后所有数据都变成密文,WireShark 的 SSH 解析器会显示为“Encrypted packet”,这一步标志着加密通道正式生效。
4.2 逐个阶段的报文级验证:TCP 握手与版本交换
对照表里的线索逐包分析时,第一个要看的是 TCP 三次握手。点开第一条 SYN 包的 Ethernet II 和 IP 头部,能看到源 MAC 是 Ubuntu 虚拟机的虚拟网卡地址,目的 MAC 是 CentOS 的虚拟网卡;IP 层源地址是 192.168.10.10、目标地址是 192.168.10.20;TCP 层源端口是随机分配的一个高位端口(比如 52034),目标端口固定是 22。这里有个值得留意的细节:TCP 三次握手的 SYN-ACK 包里的确认号,等于客户端 ISN(初始序号)+1,WireShark 默认启用了相对序号显示,所以实际抓包里看到的 Seq=0、Ack=1 是相对值而非绝对值,分析 Windows 缩放或者排查重传时要切到绝对序号再看一眼。
紧接着的三条包是 SSH 版本交换。SSH 连接建立后的第一条协议消息以明文形式传输,内容类似SSH-2.0-OpenSSH_7.4这样的 banner 行。客户端和服务端各发一条,互相告知自己的协议版本和软件版本。分析这条消息可以直接在 WireShark 的报文详情里展开 SSH Protocol 层,看到完整的版本字符串。版本信息有两个用途:一是确认两端都是 SSH 2.0(SSH 1.x 已经废弃,遇到 1.99 这种兼容模式要特别小心安全性);二是根据 banner 里的 OpenSSH 版本号排查已知漏洞——比如某些 OpenSSH 版本存在 CVE 公告的漏洞,版本信息就是判断依据。
4.3 密钥交换与加密数据的判别:明文边界在哪里
KEXINIT 和 KEXDH 这两组报文是 SSH 分析里信息量最大、也最容易看晕的部分。KEXINIT 报文里的 cookie 是随机数,不必深究;关键在于算法列表,展开报文详情能看到 KEX 算法、Server Host Key 算法、Encryption 算法、MAC 算法各有一个列表,每个列表里是客户端或服务端按优先级排列的算法名。分析协商结果时,取客户端列表的第一个算法,看它是否出现在服务端列表里,就能预判最终选中的算法。比如客户端第一个写的是curve25519-sha256,服务端列表里也有,那协商结果大概率就是它。
KEXDH_INIT 是客户端发给服务端的公钥材料,里面是客户端侧生成的 DH 公开值;KEXDH_REPLY 是服务端返回的,里面携带服务端公钥、服务端对交换材料的签名,以及用于生成共享密钥的参数。WireShark 的 SSH 解析器能把这两个消息类型解析出来,展开就能看到具体字段。从 KEXDH_REPLY 之后,客户端和服务端各自计算出共享密钥,紧接着的 NEWKEYS 消息标志着加密通道正式启用——之后的报文内容全部变成密文,WireShark 里会显示为 payload 不可读的状态,只有 TCP 头部还能正常解析。判断“加密是否生效”最简单的方法就是看报文内容:加密后的包在详情面板里只有字符长度和对齐信息,不会再出现可读的协议结构。
4.4 认证过程的报文还原:none → 挑战 → 成功/失败循环
用户认证阶段在抓包里表现为一串 USERAUTH 消息。资源里把认证逻辑展开得很细,对应报文看就能理解为什么 SSH 认证不是一次性通过的:客户端先发一条SSH_MSG_USERAUTH_REQUEST,认证方式写 none,用户名写实际登录的用户——这个请求的目的是触发服务端返回挑战。服务端收到后回复SSH_MSG_USERAUTH_FAILURE,报文的authentications that can continue字段列出允许的认证方式,比如 password、publickey。
接下来客户端从列表里挑一种发起真正的认证请求。密码认证的报文里能看到method name: password,但密码本身看不见——它是被加密通道保护着的。公钥认证比较特殊,会先发一个publickey方式的请求做公钥合法性探测,服务端返回失败但声明publickey可继续,客户端再发起带签名的正式请求,服务端验证签名成功后返回SSH_MSG_USERAUTH_SUCCESS。分析这段交互时,重点对照资源里说的“认证次数达到最大值则断开”——如果抓包看到连续多个 USERAUTH_FAILURE 后跟了 TCP FIN,说明服务端因为认证失败次数超限主动断开了连接,这是排查 SSH 爆破攻击时非常有用的判据。
5. 避坑与常见问题:SSH 抓包分析中典型翻车点的排查记录
5.1 抓包一片空白:方向和接口选错导致捕获不到任何 SSH 流量
现象:WireShark 启动捕获后,从 Ubuntu 发起 SSH 登录,但窗口里一个包都没有,或者只有少量无关的广播包。
原因:最常见的是选错了捕获接口。虚拟机场景里,物理网卡和虚拟网卡并存,流量根本不走选中的那个接口。其次是 SSH 端口不是 22,实验环境改过 sshd 配置,监听了其他端口,捕获过滤器tcp port 22自然什么都抓不到。
解决:先在 Ubuntu 里执行ip addr和ip route确认默认路由走哪个接口,然后到 WireShark 的接口列表里找到对应的虚拟网卡(VMware 环境通常是 VMnet8 或名字里带 vmnet 的接口)。不确定的话,用无过滤条件的方式抓几秒看有没有任何流量,确定接口有包再套过滤条件。SSH 端口方面,在 CentOS 上执行ss -tlnp | grep ssh确认监听端口,按实际端口修改捕获过滤器。
5.2 SSH 层解不出来:中间多了一层奇怪的协议或 IP 分片干扰
现象:部分 SSH 报文在 WireShark 里没有解析成 SSH Protocol 层,而是显示为 TCP 或 TLS(没错,SSH 的加密特征有时会被误判),或者某些包显示为 IP 分片、需要重组才能看全。
原因:WireShark 对 SSH 的协议解析是启发式的——它先识别 TCP 端口 22 上的流量,再通过 banner 文本确认协议。如果中间隔了 GRE 隧道、VXLAN 之类的封装,或者报文因为 MTU 问题被 IP 分片,启发式解析就可能失效。误判成 TLS 的原因是 SSH 的加密数据流和 TLS 的 Application Data 在特征上有相似性,端口不是 22 时容易搞混。
解决:让 WireShark 强制按 SSH 解析——右键点击报文详情里的 TCP 层,选择 “Decode As”,把端口或协议强制指定为 SSH。分片问题优先检查虚拟机的 MTU 设置,把两端 MTU 统一为 1500,尽量避免分片;已经抓到的分片包可以在 WireShark 里开启 “Reassemble fragmented IP datagrams” 偏好选项,通常在 Edit → Preferences → Protocols → IP 里能找到。
5.3 抓不到密码和命令内容:对“加密”抱有不切实际的预期
现象:从 Ubuntu 发起 SSH 登录时抓到了认证请求报文,但展开报文详情发现看不到密码、看不到执行命令的具体文本,期望的明文字段全是空的。
原因:这是对 SSH 协议机制的错误预期。SSH 设计的目的就是加密保护整个会话——密码、命令、回显全部在加密通道里传输。密钥交换完成后,所有应用层数据都变成密文,WireShark 只能识别出“这一段是加密数据”,不可能还原出明文内容。如果哪个工具声称能从 SSH 抓包里直接提取密码,那它要么是拿到了会话密钥,要么是在实施中间人攻击,都不是正常的抓包分析范畴。
解决:密码层面的明文本来就不该出现在抓包里——这正是 SSH 的安全性所在。想要看清加密后的内容,可以用抓包分析里的“会话密钥注入”方法:在 debug 模式下启动 OpenSSH 服务端并开启sshd -Ddd级别的日志,用 SSLKEYLOGFILE 的方式导出会话密钥(注意:OpenSSH 的密钥导出需要特定编译选项,不是所有发行版都支持),再把密钥导入 WireShark 完成流量解密。这是教学里常用的验证手段,平时排障一般用不到,知道有这条路就行。
5.4 SSH 认证连续失败被断开:UAUTH_FAILURE 后紧跟 FIN 包
现象:在 WireShark 里看到多条 USERAUTH_FAILURE 之后,紧接着出现 FIN 或 FIN-ACK 包,SSH 连接被服务端主动关闭。
原因:客户端在多次认证尝试中提供的凭据都无法通过验证,累计失败次数达到服务端配置的上限(OpenSSH 默认 MaxAuthTries 是 6),服务端按协议规定强制断开连接。这种情况既可能是密码确实输错了,也可能是自动化脚本在爆破。
解决:在 CentOS 的/etc/ssh/sshd_config里确认MaxAuthTries参数,默认是 6,可以适当调低来加固;同时查看/var/log/secure或/var/log/auth.log确认失败来源 IP。从分析角度说,抓包里出现这个模式说明连接是被认证策略主动终止的,不是网络问题,排查方向应该转向凭据和认证配置。
5.5 TCP 层反复重传导致 SSH 交互缓慢:虚拟化环境的经典问题
现象:SSH 登录后敲命令明显卡顿,抓包里出现大量 TCP Retransmission、Duplicate ACK 包,SSH 本身的协议报文占比很低。
原因:虚拟机环境下 CPU 调度延迟、虚拟网卡的中断合并策略、或者宿主机网络负载波动都可能导致 ACK 响应不及时,触发 TCP 重传。很多时候这不是 SSH 配置问题,而是底层虚拟网络的问题。
解决:先确认是不是慢启动或延迟 ACK 导致——在 CentOS 上执行sysctl net.ipv4.tcp_sack和sysctl net.ipv4.tcp_timestamps检查相关参数,但常规手段是把虚拟网卡的“RX/TX 队列”绑定到不同 CPU、关闭虚拟机的 TCP 分段卸载(TSO/GRO),这些配置在 VMware 虚拟网卡的属性里可以调整。带宽充裕的前提下,也可以在 Ubuntu 侧调大 TCP 缓冲区:sysctl -w net.core.rmem_max=16777216这类操作临时改一下试试,通常能明显缓解卡顿。
6. 把抓包分析变成日常排障习惯:Follow Stream、导出对象与解密通道的进阶玩法
整套实验走完一遍之后,抓包分析的思路可以沉淀成日常排障里能复用的习惯。第一个进阶技巧是 “Follow TCP Stream”——在 WireShark 的报文列表里选中任意一条 SSH 包,右键选择 Follow → TCP Stream,就能看到这次会话的完整字节流。虽然 SSH 加密通道里看到的只是一堆不可读的密文,但通过 Stream Content 窗口可以确认会话的字节总量、确认报文是否完整、有没有数据在传输中被截断。配合每一条 SSH 消息的长度分布,可以快速判断一次登录过程是否在某个阶段中断了——比如只有 KEXINIT 没有后续报文,问题大概率卡在算法协商或密钥交换阶段。
第二个技巧是导出对象和证书信息。在 WireShark 的 File → Export Objects 菜单里,能看到从流量里还原出来的可识别对象。SSH 流量本身没有 HTTP 那样方便的对象导出,但服务端公钥和主机密钥信息可以在 SSH 协议详情里直接查看。排查 SSH 中间人攻击时,这个方法很实用——把当前连接的服务端公钥指纹记下来,和服务器上ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub输出的指纹做对比,不一致就说明连接被劫持了。我每次排查 SSH 连接异常,都会顺手做一次指纹比对,成本极低但能排除最严重的安全隐患。
第三个值得养成的习惯是结合 tshark 命令行做批量分析。WireShark 的图形界面适合交互式探索,但真正处理大量 pcap 文件还是得靠命令行。比如要统计一段时间内所有 SSH 连接的来源 IP 和尝试次数:
# 统计所有 SSH 流量的源 IP 与其发起的连接次数 tshark -r ssh_capture.pcapng -Y "tcp.port == 22" -T fields -e ip.src | sort | uniq -c | sort -rn # 只看 TCP 三次握手成功的连接,即出现 SYN-ACK 的流 tshark -r ssh_capture.pcapng -Y "tcp.flags.syn == 1 && tcp.flags.ack == 1" -T fields -e tcp.stream | sort -u | wc -l # 导出每个 TCP 流的前三个报文方向,判断握手是否完整 tshark -r ssh_capture.pcapng -Y "tcp.port == 22" -T fields -e tcp.stream -e tcp.flags.str | head -50这段命令里的关键在于-Y过滤语法和-T fields的字段输出组合。第一条命令统计源 IP 的分布,爆力破解的特征是同一个 IP 出现大量短连接;第二条命令只匹配 SYN-ACK 包,统计完成了握手的连接数,如果完成的连接数远小于握手尝试数,说明大量请求根本没进入 SSH 协议层就被拒绝了;第三条命令看每个 TCP 流的标志位序列,正常是[SYN] → [SYN, ACK] → [ACK] → [PSH, ACK](SSH banner 会带 PSH 标志),看到[RST]直接出现则说明端口未开放或防火墙拦截。
做这套分析有一个习惯我从开始用 WireShark 起就一直保持:抓包后先存原始 pcapng 文件,再做任何过滤和分析。原因很简单——显示过滤器可以随时改,过滤条件设错了重新输入就行,但如果原始文件丢了,就得重新搭环境复现整个 SSH 会话,成本完全不一样。从那以后我每次做协议分析都强制走一遍“先存原始包 → 再过滤 → 按阶段逐包核对 → 最后用 tshark 做统计”的流程,这套流程在这份实训资源对应的 SSH 分析场景里屡试不爽,希望帮到你。
本文还有配套的精品资源,点击获取