WireShark SSH协议分析实战:从抓包到密钥交换与认证全解析

发布时间:2026/10/4 16:26:48

WireShark SSH协议分析实战:从抓包到密钥交换与认证全解析 简介这份资源是面向信息安全技术应用专业学生与网络协议分析初学者的实训文档聚焦通过 WireShark 对 SSH 协议进行抓包与解析帮助读者理解安全远程登录协议的完整工作流程。内容围绕密钥交换、用户认证与加密数据传输三个阶段展开并配套算法协商、服务请求、会话建立与连接关闭等环节的报文分析要点同时给出从配置 IP、设置过滤条件到逐条对照分析 TCP 连接、SSH 版本信息、密钥交换初始化消息、加密数据及断开连接的实训步骤适合课程实验与赛题训练场景。资源包共 1 个 docx 文件约 37KB以图文讲解与操作指引为主便于直接用于实验对照与笔记整理。目前已有 111 人学习可作为 SSH 协议分析与 WireShark 实操的入门参考。1. 从一次 SSH 登录抓包说起这份赛题资源到底能解决什么很多人第一次用 WireShark 抓 SSH 流量看到的就是一堆加密的二进制除了 TCP 握手和版本号剩下全是黑匣子。这份《通过 WireShark 进行 SSH 协议分析3》就是冲着这个痛点来的——它把 SSH 从 TCP 建连、版本协商、密钥交换、用户认证到加密数据传输的完整链路拆成六个可对照抓包文件逐步验证的分析点。资源本身是信息安全技术应用专业的单兵模式赛题资源配套分组对抗赛题适合正在准备技能竞赛的学生、需要给学生演示协议分层原理的讲师以及想从抓包角度真正看懂 SSH 协商过程的运维人员。它不教你配 SSH 服务而是教你用 WireShark 把一次 SSH 登录拆开看搞清楚每一帧在协议栈里干了什么。2. SSH 协议三阶段与 WireShark 过滤表达式先搞懂再抓包2.1 密钥交换、用户认证、数据传输到底在抓什么SSH 协议的工作过程可以拆成三个阶段每个阶段在 WireShark 里的可观测程度完全不同。密钥交换阶段是唯一能看到算法协商明文的窗口客户端和服务器互相发送自己支持的算法列表然后按客户端列表顺序逐个匹配。常见做法是双方依次协商密钥交换算法、加密算法、消息认证码算法和压缩算法每种算法都从客户端列表取第一个去服务器列表里找匹配上就锁定匹配不上就取下一个全部失败则服务器直接断开连接。这个阶段抓包能看到 SSH_MSG_KEXINIT 报文里列出的算法清单是分析 SSH 安全配置的入口。用户认证阶段开始报文内容就进入加密通道了。客户端先发一个认证方式为 none 的请求服务器回复自己支持的认证方式列表客户端再选一种发起正式认证。密码认证方式下服务器把收到的用户名密码和本地或远程认证服务器比对公钥认证方式下服务器先检查公钥合法性再用数字签名验证客户端。这个阶段在 WireShark 里只能看到报文长度和方向看不到具体用户名密码这是 SSH 的设计使然不是抓包工具的问题。数据传输阶段客户端把要执行的命令加密后传给服务器服务器解密执行再把结果加密回传。通信结束或空闲超时后关闭会话。这个阶段抓到的包全是加密载荷分析价值在于确认会话建立成功、数据方向正确、连接关闭正常。2.2 过滤表达式怎么写才能只留下 SSH 流量WireShark 的显示过滤表达式是分析效率的关键。抓包时如果不过滤SSH 流量会被淹没在 ARP、DNS、HTTP 里。我一般会先用tcp.port 22把 SSH 流量单独拎出来再根据分析阶段叠加条件。# 只显示 SSH 流量 tcp.port 22 # 只看 TCP 三次握手和四次挥手 tcp.port 22 (tcp.flags.syn 1 || tcp.flags.fin 1) # 只看 SSH 版本协商报文 tcp.port 22 tcp.len 0 tcp.payload contains SSH- # 只看密钥交换初始化消息 tcp.port 22 ssh.protocol SSH_MSG_KEXINIT # 排除加密数据只看协议交互 tcp.port 22 !ssh.encrypted_packet第一行是最基础的端口过滤SSH 默认走 22 端口如果服务端改过端口把 22 换成实际端口即可。第二行用来快速定位连接建立和断开的时间点SYN 和 FIN 标志位是 TCP 层的锚点。第三行利用 SSH 版本协商阶段发送的明文标识字符串通常以SSH-2.0-开头这是整个 SSH 会话里唯一不带加密的文本内容。第四行依赖 WireShark 的 SSH 协议解析器它能识别出 KEXINIT 这种未加密的控制报文。第五行是反向过滤把加密载荷排除掉只留下协议控制帧适合分析协商过程。提示如果 WireShark 版本较老ssh.protocol字段可能不可用可以退回到tcp.payload[0:1] 14这种按消息类型码过滤的方式14 对应 SSH_MSG_KEXINIT。2.3 实验环境搭建IP 配置与抓包点选择赛题资源里给了 Ubuntu Linux 和 CentOS Linux 两台主机的 IP 配置步骤这是整个实训的基础。常见做法是给 Ubuntu 配一个 A 段地址CentOS 配一个 B 段地址确保两台机器能互通。抓包点选在 Ubuntu 的网卡上因为客户端发起的 SSH 连接出站流量在客户端抓最完整能看到客户端发送的算法列表原文。# Ubuntu 端配置 IP示例 sudo ip addr add 192.168.1.10/24 dev eth0 sudo ip link set eth0 up # CentOS 端配置 IP示例 sudo ip addr add 192.168.1.20/24 dev eth0 sudo ip link set eth0 up # 验证连通性 ping -c 3 192.168.1.20IP 地址按实际实验环境调整关键是两端在同一网段。ip addr add是临时生效重启后丢失赛题环境里够用。ping验证三层可达如果 ping 不通先查网卡状态和防火墙别急着开 WireShark。抓包点选在 Ubuntu 的 eth0 上过滤表达式用host 192.168.1.20 tcp.port 22这样只抓 Ubuntu 和 CentOS 之间的 SSH 流量排除其他干扰。3. 对照抓包文件逐帧分析六个分析点的操作路径3.1 TCP 建立连接与 SSH 版本信息识别第一步分析 TCP 建立连接在 WireShark 里过滤tcp.port 22 tcp.flags.syn 1能看到三次握手的前两个包客户端发 SYN服务器回 SYNACK。第三个 ACK 包通常和 SSH 版本协商报文合在一起因为 TCP 连接建立后客户端立刻发送版本字符串。展开第三个包的 TCP 载荷能看到类似SSH-2.0-OpenSSH_8.9p1的文本这是 SSH 服务端版本信息。Frame 3: 74 bytes on wire TCP: 192.168.1.10:54321 - 192.168.1.20:22 [ACK] SSH: Server protocol version: SSH-2.0-OpenSSH_8.9p1版本信息是明文传输的这是 SSH 协议设计的一部分用于双方确认协议版本兼容性。如果版本字符串不匹配比如客户端只支持 SSH-1.99 而服务器只支持 SSH-2.0连接会直接断开。分析时注意版本号后面的软件标识OpenSSH 的版本号能反映服务端的大致补丁级别但不要据此下安全结论版本号可以伪装。3.2 密钥交换初始化消息的算法列表解读密钥交换初始化消息是 SSH 协议里信息密度最高的明文报文。在 WireShark 里过滤ssh.protocol SSH_MSG_KEXINIT展开报文详情能看到四个算法列表kex_algorithms、encryption_algorithms、mac_algorithms、compression_algorithms。每个列表里按优先级排列了客户端支持的算法。SSH_MSG_KEXINIT Cookie: 8a3f... kex_algorithms: curve25519-sha256, ecdh-sha2-nistp256, diffie-hellman-group14-sha256 encryption_algorithms: chacha20-poly1305openssh.com, aes128-ctr, aes192-ctr mac_algorithms: hmac-sha2-256, hmac-sha1, hmac-md5 compression_algorithms: none, zlibopenssh.com客户端和服务器各发一个 KEXINIT双方按客户端列表顺序匹配。比如客户端第一个密钥交换算法是 curve25519-sha256服务器列表里也有那就锁定这个算法。如果服务器不支持 curve25519就取客户端第二个 ecdh-sha2-nistp256 继续匹配。这个匹配过程在抓包里看不到逐次尝试只能看到最终协商结果因为协商是双方本地计算不产生额外报文。注意算法列表里出现 hmac-md5 或 hmac-sha1 这类弱算法说明服务端或客户端配置较老生产环境建议禁用。赛题环境里保留这些算法是为了演示协商过程不要照搬到实际服务器。3.3 密钥交换消息与加密数据的分界点密钥交换消息SSH_MSG_KEXDH_INIT 和 SSH_MSG_KEXDH_REPLY是密钥交换阶段的核心但这两个报文的内容在 WireShark 里已经部分加密或编码能看到的是密钥交换的公开值比如 Diffie-Hellman 的交换公钥。真正让分析者困惑的是分界点从哪个包开始SSH 载荷变成完全加密的分界点在 NEWKEYS 消息之后。客户端和服务器各自发送 SSH_MSG_NEWKEYS表示后续报文将使用协商好的密钥加密。在 WireShark 里NEWKEYS 之后的包ssh.encrypted_packet字段会变为 true载荷显示为 Encrypted packet。这时候再想分析内容就不可能了只能看报文长度、方向和时序。# 过滤出 NEWKEYS 消息 tcp.port 22 ssh.protocol SSH_MSG_NEWKEYS # 过滤出加密数据包 tcp.port 22 ssh.encrypted_packet第一条命令定位分界点第二条命令查看加密后的数据流。分析加密数据时关注的是包长度分布和交互节奏。比如密码认证时客户端发送的认证请求包长度通常固定服务器回复的认证成功或失败包长度也相对固定通过长度差异可以推断认证结果这是侧信道分析的入门思路赛题里常用来考察对加密通道可观测性的理解。3.4 用户认证阶段的报文交互还原用户认证阶段虽然载荷加密但报文交互模式有规律。客户端先发 none 认证请求服务器回认证挑战客户端再发正式认证请求。在 WireShark 里过滤tcp.port 22 tcp.len 0按时间顺序看包的方向和长度。No. Time Source Destination Length Info 5 0.001 192.168.1.10 192.168.1.20 82 SSH: Client: Encrypted packet 6 0.002 192.168.1.20 192.168.1.10 90 SSH: Server: Encrypted packet 7 0.003 192.168.1.10 192.168.1.20 98 SSH: Client: Encrypted packet 8 0.005 192.168.1.20 192.168.1.10 86 SSH: Server: Encrypted packet第 5 包是客户端 none 认证请求第 6 包是服务器认证挑战第 7 包是客户端正式认证请求第 8 包是服务器认证结果。长度差异反映了认证方式的不同密码认证的请求包比公钥认证的请求包短因为公钥认证要传公钥或签名。如果第 8 包之后还有认证挑战说明服务器要求多因素认证客户端需要继续完成其他认证方式。3.5 TCP 断开连接与会话关闭的时序验证通信结束或空闲超时后SSH 会话关闭TCP 连接进入四次挥手。在 WireShark 里过滤tcp.port 22 (tcp.flags.fin 1 || tcp.flags.reset 1)能看到 FIN 或 RST 包。正常关闭是四次挥手一方发 FIN另一方回 ACK然后另一方发 FIN一方回 ACK。异常关闭是 RST通常出现在认证失败次数达到最大值后服务器强制断开。# 查看 TCP 流时序图 tcp.port 22 tcp.flags.fin 1分析断开连接时注意 FIN 包之前有没有加密的会话关闭消息。SSH 协议在关闭会话前会发送 SSH_MSG_CHANNEL_CLOSE 和 SSH_MSG_DISCONNECT这些消息也是加密的只能通过包长度和时序推断。如果看到 RST 而不是 FIN说明连接被强制中断常见原因是认证失败次数超限或服务器配置了空闲超时。4. 避坑与排查SSH 抓包分析里最容易翻车的五个点4.1 抓不到 SSH 包只看到 TCP 重传现象WireShark 里过滤tcp.port 22只有 SYN 重传没有后续报文。原因客户端和服务器网络不通或者服务器 SSH 服务没启动。解决先在客户端ping服务器再telnet 服务器IP 22确认端口开放。如果 ping 通但 telnet 不通检查服务器防火墙和 sshd 服务状态。赛题环境里常见的是 IP 配错网段或网卡没启用。4.2 版本协商报文显示乱码现象TCP 载荷里看到的不是SSH-2.0-开头的文本而是一堆乱码。原因抓包点选错了抓到了其他协议的流量或者过滤表达式写成了tcp.port 22但实际 SSH 服务跑在非标准端口。解决先确认 SSH 服务端口用ss -tlnp | grep ssh查看监听端口再调整过滤表达式。如果端口正确但内容乱码检查 WireShark 的协议解析设置确保 SSH 协议解析器已启用。4.3 KEXINIT 报文里算法列表为空现象展开 SSH_MSG_KEXINIT 报文算法列表字段显示为空或解析失败。原因WireShark 版本较老SSH 协议解析器不支持新算法名称或者报文被分片导致解析不完整。解决升级 WireShark 到较新版本常见做法是用 3.6 以上版本。如果升级后仍为空检查 TCP 流是否完整用tcp.stream eq N过滤出完整流再分析。4.4 加密数据包长度异常现象认证阶段某个方向的包长度突然变大或变小与预期不符。原因认证方式不同导致载荷长度差异比如公钥认证的请求包比密码认证长或者客户端发送了额外的心跳或保活消息。解决对照认证流程判断当前处于哪个阶段结合包的方向和时序推断。如果长度异常且连接随后断开检查服务器认证次数限制配置。4.5 断开连接时看到 RST 而不是 FIN现象TCP 连接以 RST 结束没有正常的四次挥手。原因服务器强制断开连接常见于认证失败次数达到最大值、空闲超时或服务器主动拒绝。解决回看认证阶段的报文交互数一下认证挑战和认证请求的次数。如果认证失败次数达到配置上限服务器会直接发 RST。赛题环境里这是预期行为用来演示认证失败处理流程。5. 从抓包到验证用 tshark 批量提取 SSH 协商结果WireShark 图形界面适合逐帧分析但赛题环境里经常需要批量验证多个抓包文件或者把分析结果导出成结构化数据。我一般会用 tshark 做批量提取它是 WireShark 的命令行版本适合脚本化处理。# 提取所有 SSH 流的版本协商信息 tshark -r ssh_capture.pcap -Y tcp.port 22 tcp.payload contains \SSH-\ -T fields -e frame.number -e ip.src -e ip.dst -e tcp.payload # 提取 KEXINIT 报文的算法列表 tshark -r ssh_capture.pcap -Y ssh.protocol \SSH_MSG_KEXINIT\ -T fields -e frame.number -e ssh.kex_algorithms -e ssh.encryption_algorithms -e ssh.mac_algorithms # 统计加密数据包的数量和方向 tshark -r ssh_capture.pcap -Y tcp.port 22 ssh.encrypted_packet -T fields -e frame.number -e ip.src -e ip.dst -e tcp.len第一条命令提取版本协商报文-Y是显示过滤-T fields指定输出字段-e指定要提取的字段名。tcp.payload contains SSH-利用版本字符串的明文特征定位。第二条命令提取 KEXINIT 的算法列表ssh.kex_algorithms等字段在 tshark 里的名称和 WireShark 图形界面一致。第三条命令统计加密数据包输出帧号、源 IP、目的 IP 和 TCP 载荷长度用来分析加密通道的流量模式。参数说明-r指定输入文件-Y是显示过滤表达式-T fields表示按字段输出-e后面跟字段名。如果字段名不确定可以先用tshark -r file.pcap -T pdml导出 XML 格式搜索字段名。常见坑是 tshark 版本和 WireShark 版本不一致导致字段名差异建议用同一套安装包。验证方法把 tshark 提取的结果和 WireShark 图形界面里逐帧看到的内容对照确认算法列表、版本字符串、加密数据包数量一致。如果 tshark 输出为空先检查过滤表达式里的引号转义bash 里嵌套引号容易出错常见做法是把过滤表达式写到文件里用-Y引用或者用单引号包裹整个表达式。从那以后我每次分析 SSH 抓包都强制先跑一遍 tshark 提取版本和算法列表再打开图形界面逐帧看交互时序。图形界面容易陷入细节命令行能快速建立全局视图。这份赛题资源的价值在于它把六个分析点串成了一条完整的验证链路从 TCP 握手到断开连接每一步都有对应的抓包特征和判断依据。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/4 16:21:48

ESP32 AI硬件工程化实战:通信、容错、OTA与安全边界

1. 从"点亮一颗灯"到"跑通一个模型":AI硬件的分水岭在哪很多人第一次把 ESP32 接上大模型 API,看到串口里打印出一段像模像样的回答,第一反应都是"我做了一个 AI 硬件"。这个兴奋点我完全理解,因为…

2026/10/4 21:17:00

AI工程从零到部署:完整实践指南与踩坑记录

老实说,《ai-engineering-from-scratch》这个标题看起来像是一个短期突击计划,但真正把它做完之后,我觉得它更像一面镜子——照出一个新手在AI工程这条路上一路踩坑、填坑、重新爬起来的全过程。过去大半年我基本就是这个状态:零基…

2026/10/4 21:17:00

从RAG到RIG:OpenRig解决多跳知识问答的工程实践

1. 从RAG到RIG:为什么"先生成再检索"救不了多跳问题上个月我们在内部知识库上线的RAG问答系统,被业务方连续问倒了三次。三次都栽在同一类问题上:"A方案和B方案冲突时,合同模板里哪一条优先?"&quo…

2026/10/4 21:17:00

openrig实践:配置驱动多智能体编排框架的安装、部署与工程落地

openrig 是我最近在折腾的一个开源项目——准确说,是一个配置驱动的多智能体编排框架。它在圈子里不算火,但用下来很顺手,解决了一个我之前反复纠结的问题:agent 的逻辑散落在代码里,每加一个工具、每改一次流程都要动主程序,时间一长整个项目变成一座动不了的积木塔。这篇文章…

2026/10/4 21:12:00

从 failed to load plugins 看插件系统:加载失败根因与排查

我不止一次在启动日志里被一行failed to load plugins或plugins did not activate的告警搞得头皮发麻。尤其是那些把插件机制做得比较“野”的工具,装了一堆插件,最后启动时某个不显眼的报错让你排查一整个下午。这次不聊某个具体产品,而是从…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑