
这个标题看起来很直白——用Wireshark抓登录密码。但我先把话放在前面这篇文章的教学场景是你自己搭建的测试环境、你自己发起的抓包、你有权抓取的网络流量。做安全测试也好学习网络协议也好前提是你对目标系统有合法授权。把Wireshark对准别人的网站、别人的网络然后试图还原人家的口令这属于法律问题不是技术问题。这篇文章讲的是原理是HTTP协议为什么“裸奔”以及作为普通用户和开发者你该怎么防住这种抓包。我最早接触到这个场景纯属工作需求。公司内部有个老系统登录还是HTTP运维死活不信这个有风险觉得“内网没事”。我当场打开Wireshark让他自己输入账号密码然后给他看数据包里的明文。他看完之后第二天就去申请HTTPS证书了。这件事给我的触动特别大很多人不是不知道风险而是不知道风险长什么样。把抓包这一套讲清楚本质上是帮人建立对网络的“透视眼”。下面我按自己的实际操作流程来写从原理到实战从HTTP到HTTPS再到防御思路尽量把每一步为什么这么做、遇到问题怎么排查都说透。1. HTTP凭什么会把密码“交出来”网络协议的设计逻辑先搞清楚一个底层问题Wireshark不是一把“万能钥匙”它没有破解能力它做的事情只有一件——把经过网卡的数据包原样拷贝一份然后按协议规范拆开给你看。它能抓到密码不是因为Wireshark多厉害而是因为HTTP协议本身就没有加密。1.1 数据包本质上是一封“明信片”你访问一个HTTP网站输入账号密码点击登录浏览器发出的HTTP请求在网络里是以明文形式传输的。打个粗俗但准确的比方这就像你往邮局寄了一张明信片收件人、正文内容、你的落款署名全写在正面任何经手这封明信片的人翻过来就能看到。而HTTPS则相当于把明信片装进了一个只有收件人才能打开的保险箱邮递员能看到的只有收件地址打不开内容。Wireshark就是那个“经手明信片的人”的角色它默默记下了每一个过路数据包的完整内容。其中一旦包含POST请求正文里就躺着用户名、密码而且通常连加密都省了。1.2 HTTP请求的四段式结构一个标准的HTTP POST请求包拆开来看大致是这么四块内容请求行例如POST /login.php HTTP/1.1说明向哪里提交数据请求头Host、User-Agent、Cookie、Content-Type等描述信息空行分隔头部和正文的标识请求正文usernameadminpassword123456这种键值对Wireshark的厉害之处在于它不需要你手动去拼这四个部分。它已经按照HTTP协议规范把请求解析成了结构化字段。你只需要选中一个HTTP请求包在下方的面板里展开Hypertext Transfer Protocol这一层就能看到Method、URI、Host等字段。再点一下HTML Form URL Encoded用户名和密码就清清楚楚列在那里。1.3 明文不是“设计漏洞”是历史遗留很多初学者会问HTTP这么不安全当初为什么不直接做成加密的这是因为HTTP诞生于上个世纪90年代初当时的应用场景是实验室之间共享静态文档压根没人想到后来会用它传银行卡密码。加密需要额外的CPU算力在那个年代是实打实的性能负担所以HTTP选择了裸奔。后来的HTTPS是在HTTP外面套了一层TLS/SSL相当于给老房子加装防盗门而不是把老房子推倒重盖。所以你现在看到的任何一个还在用HTTP的登录系统不是“有漏洞”而是“全身都暴露在空气里”。Wireshark抓密码之所以能成立根本原因就一句话基于HTTP协议的应用登录数据包本身没有做任何保密处理。2. 从零开始安装Wireshark与抓到第一个HTTP包实操部分来了。如果你的电脑上还没有Wireshark这一步不要跳过。很多人的第一道坎不是看不懂数据包而是压根没抓到自己想要的包。2.1 安装时最容易踩的两个坑Wireshark官网的下载没什么难度选对操作系统版本一路Next就行。但有两个细节值得注意第一个坑安装过程中会提示安装Npcap或WinPcap。这是Windows下抓包必须的底层驱动弹出的对话框一定要勾选“Install Npcap”。如果你用的是Win10/11建议选Npcap而非老旧的WinPcap它对新硬件的兼容性更好也支持Wireshark的高级功能比如环形缓冲区。不少人在这一步图省事取消勾选装完Wireshark发现根本选不到网卡、抓不到任何数据回头再装驱动又要折腾半天。第二个坑Wireshark的默认权限在部分操作系统上不够抓包。Linux下如果以普通用户打开Wireshark经常看到网卡列表是空的这是因为缺少CAP_NET_RAW权限。简单粗暴的解法是sudo wireshark但更规范的做法是把用户加入wireshark用户组sudo usermod -aG wireshark $USER改完用户组后记得重新登录一次。不然后面你抓到的所有包都可能是空的这个坑极其隐蔽。2.2 选对网卡一半的抓包问题都出在这里Wireshark启动后第一个界面是网卡选择列表。笔记本用户常常困惑Wi-Fi已经连通了为什么选择了WLAN网卡后抓不到任何数据这里的原因通常有两个。一是你盯着某个网卡看但实际流量走了另一个网卡。比如虚拟机通过NAT上网时物理发往外部网络的流量会经过宿主机虚拟出的网卡只抓物理网卡就能漏掉虚拟机里的流量。二是你没开混杂模式。Wireshark默认情况下只抓取发给本机的包要抓同网段其他设备的流量你自己有权抓的情况下得在网卡设置里勾选混杂模式Promiscuous Mode。判断自己是否选对了网卡的办法很直接随便打开一个网页看Wireshark主界面是不是有大量绿色和蓝色的数据包在快速滚动。如果几秒钟过去还是一片死寂基本可以断定网卡选错了或者权限有问题。2.3 先用一条过滤器看HTTP请求长什么样Wireshark的过滤器分两种抓包过滤器Capture FilterBPF语法和显示过滤器Display Filter。日常调试中用得最多的是显示过滤器它不会丢包只是帮你从已抓到的数据里筛出关心的那部分。要只看HTTP流量在工具栏的过滤框输入http然后回车。此时界面上只剩HTTP相关的数据包一个典型的HTTP GET请求会长这样字段含义示例值No.包的序号12Time相对时间3.456789Source源IP192.168.1.108Destination目的IP93.184.216.34Protocol协议HTTPLength包长字节486Info摘要信息GET / HTTP/1.1需要注意的是Length这一列偶尔会让人困惑。热搜词里有人问“为何只能显示520字节数据怎么显示2090个字节数据”这里解释一句数据包长度是由网卡MTU最大传输单元决定的以太网默认MTU是1500字节超过这个大小的数据会被拆成多个分片包。Wireshark里看到单个包只有几百字节不代表请求内容只有几百字节它可能被TCP层拆分成了多个段。想看到完整请求不要盯着单个包要用后面要讲的“跟踪流”功能。3. 实战演示在测试环境里把登录密码“还原”出来下面进入正题。我在本地搭了一个测试站完全没有加密用来模拟那种老旧的HTTP登录系统。这个环境你完全可以在自己电脑上复现不要拿别人的系统练手。3.1 搭建一个最简单的HTTP登录页如果你有Docker跑一个带登录页的测试容器是最省事的办法。没有Docker也没关系直接写一个最简单的Python HTTP服务器都能模拟# -*- coding: utf-8 -*- # 仅供本地安全实验使用 from http.server import HTTPServer, BaseHTTPRequestHandler import urllib.parse class LoginHandler(BaseHTTPRequestHandler): def do_POST(self): length int(self.headers.get(Content-Length, 0)) body self.rfile.read(length).decode(utf-8) print(收到登录数据:, body) self.send_response(200) self.end_headers() self.wfile.write(bLogin success) def log_message(self, format, *args): pass if __name__ __main__: server HTTPServer((0.0.0.0, 8080), LoginHandler) print(测试登录服务器已启动: http://localhost:8080) server.serve_forever()这段代码不是为了做产品它的唯一目的是提供一个你能合法抓包的目标。访问http://localhost:8080随便填账号密码提交密码会被POST到服务器同时也会出现在你的网络里。3.2 抓包参数过滤表达式与定位方法打开Wireshark选择环回接口Loopback通常叫lo或Adapter for Loopback Traffic Capture。访问本地服务时流量不经过物理网卡只走环回接口选错了照样抓不到。为了让抓包过程更干净显示过滤器可以直接写成http.request.method POST这个表达式会把所有POST请求过滤出来。浏览器访问本地8080端口、点击登录按钮的瞬间Wireshark里应该出现一条新的POST记录。双击这条记录Wireshark会打开一个数据包详情窗口。依次展开这几层Frame物理层封装Ethernet II/Linux cooked capture链路层Internet Protocol Version 4网络层源IP、目的IPTransmission Control Protocol传输层源端口、目的端口Hypertext Transfer Protocol应用层在HTTP这一层往下找到HTML Form URL Encoded: form data点开小箭头你会看到username: admin password: 123456明文密码就这么躺在数据包里。甚至不需要这一步直接在Wireshark主界面选中这个POST包右键 → 跟踪 → HTTP流会弹出一个窗口左边显示请求右边显示响应请求正文里的usernameadminpassword123456一眼就能看到。3.3 数据包里有编码但没有加密这里要区分一个概念Wireshark里看到的密码有时不是原始字符而是URL编码后的结果。比如密码是a bcPOST正文里会变成ab%26c。空格编码成特殊符号编码成%XX。这种编码只是为了在URL里传输安全本质上仍然是明文任何人都可以轻松还原。同理有些老系统在提交前用Base64对密码做一层处理看上去是“加密”了实际只是另一种形式的编码。Base64解码工具遍地都是这层伪装在Wireshark面前毫无意义。所以当你看到有人说“我抓到了密码但它是密文”大概率只是遇到了URL编码或Base64编码而不是真正的加密。区分编码和加密是判断一个系统是否安全的基本功。3.4 顺带解决一个常见困惑如何查看完整数据内容热搜词里提到“Wireshark 为何只能显示520字节数据怎么显示2090个字节数据”。这个现象其实就是TCP分片。当一个HTTP响应超过MTU1500字节时底层会切成多个TCP分段Wireshark默认按单个帧展示所以你看到每个包可能只有几百字节。要查看应用层的完整数据有两个方法选中任意一个属于该TCP连接的包右键 →跟踪 → TCP流Wireshark会把该连接上的所有TCP载荷按顺序拼接起来完整呈现整个HTTP消息在显示过滤器里输入tcp.len 0过滤出实际承载数据的TCP包再逐个拼接查看你甚至可以调整Wireshark的列显示加上TCP payload字段直接看到每个包里的实际内容。这一步对分析大文件传输、视频流分包特别有用。4. HTTPS之下Wireshark还能这么玩但前提完全不同讲完HTTP的明文问题自然绕不开HTTPS。今天的互联网上绝大多数网站都已经上了HTTPS直接用Wireshark抓HTTPS流量能看到的现象只有一行TLSv1.3 Application Data内容你根本打不开。4.1 为什么HTTPS抓不到密码TLS握手的秘密HTTP加上TLS之后浏览器和服务器在正式传输数据前先要经过一次握手协商出一个对称加密密钥。这个密钥只存在于两端的内存里网络里传输的数据全部用这个密钥加密后再发出去。Wireshark截获的只是一堆看起来毫无规律的字节。TLS的设计里有“前向保密”机制意思是每一段新的连接都会生成临时密钥旧的密钥即使泄露也不影响之前的通信内容。这正是HTTPS和HTTP最本质的差别HTTP是不设防的裸奔HTTPS是保镖护送。4.2 本地环境下如何解密自己的HTTPS流量这里需要澄清一个常见的误解Wireshark在一些条件下确实能看到HTTPS的明文内容比如你抓的是自己本机的流量并且自己设置了SSLKEYLOGFILE环境变量。具体操作是在系统环境变量里新增项SSLKEYLOGFILE指向一个文件路径例如C:\Users\你的用户名\Desktop\sslkeys.log然后重启浏览器。现代浏览器Chrome/Firefox支持在启动时读取这个环境变量每次TLS握手时把会话密钥写入该文件。Wireshark里依次打开 编辑 → 首选项 → Protocols → TLS在(Pre)-Master-Secret log filename里填上刚才的文件路径。配置完成后重新抓包Wireshark会把该日志文件里的密钥和网络中的密文做配对一旦配对成功原来显示的TLSv1.3 Application Data就会自动解码成HTTP/1.1 200 OK之类的明文内容。不过要强调一句这个方案只能破解你自己的浏览器流量。你在本机设了密钥日志TLS会话的密钥就保存在本机Wireshark才能据此解密。如果是别人的电脑、别人的浏览器你既无法设置环境变量也拿不到密钥文件自然解密不了。4.3 为什么“在网络上截获HTTPS流量再解密”不现实理论上如果攻击者同时截获了客户端和服务器之间的密文并且掌握了协商出的密钥就能解密。但密钥是在两端内存里生成的不在网络里传输除非攻击者能攻破其中一端的主机获取内存数据否则只能靠暴力破解。现代TLS用的对称加密算法比如AES-256暴力破解在当前算力下毫无可行性。再加上前向保密机制即使某次会话的密钥泄露了也只影响这一条会话不会蔓延到历史流量。所以大家一定要理解Wireshark抓HTTPS域名是很容易的——比如热搜词里有人问“wireshark 抓https域名包”——你确实能看到这个TCP连接发往哪个IP、证书的SNI扩展里写着哪个域名但这就是极限了。再往下全是加密内容。5. 现实威胁再进一步攻击者怎么拿到别人电脑上的密码Wireshark常被用于被动抓包也就是站在旁边看数据流经过。但在真实攻击场景里攻击者想要的往往是别人的密码。这就必须主动介入网络通信让数据流从攻击者的电脑上走一遍。下面这些手法讲清楚是为了防御不是为了做坏事。5.1 ARP欺骗让流量“绕道”经过攻击者在一个局域网里主机A和主机B通信时数据包在链路层是通过MAC地址寻址的。攻击者可以向网络中发送伪造的ARP应答包把网关对应的MAC地址改成自己的MAC地址。这样一来局域网内其他用户上网的流量都会被引导到攻击者机器上攻击者再把流量转发给真正的网关中间就做了一次“窃听转接”。Wireshark在这种情况下能派上用场攻击者选定一张网卡开混杂模式所有流经的HTTP流量都会被抓到密码自然也在里面。这种攻击在技术上早就很成熟许多工具能做但把它跑在别人的网络上同样是违法行为。5.2 DNS欺骗与钓鱼的本质DNS欺骗的思路更直接攻击者伪装成DNS服务器告诉受害者的电脑“你要访问的域名对应这个IP”而这个IP是攻击者事先搭建的钓鱼服务器。受害者输入账号密码数据直接发到攻击者的服务器上Wireshark连抓包都不需要了服务器后端直接记录一行数据库日志。这类攻击的本质是信任关系的伪造。HTTP协议默认不校验服务器的真实身份所以任何中间节点声称自己是目标网站时浏览器都会选择相信。HTTPS的CA证书体系正是为了解决这个问题服务器必须拿出由权威CA签发的证书证明自己的身份。5.3 安全部署清单什么样的系统才扛得住抓包经历了从密码裸奔到中间人攻击的完整链路防御思路其实很清晰按优先级排序防护层具体措施解决的问题传输层全站HTTPS禁止HTTP回退明文内容泄露协议层启用HSTS强制浏览器只走HTTPS连接中间人降级攻击应用层登录接口做频率限制、验证码撞库与暴力破解服务端密码存储使用bcrypt/argon2加盐哈希数据库泄露后密码不被逆向用户侧避免在公共Wi-Fi输入敏感信息必要时使用VPN局域网监听风险这里特别说一下HSTS。即使网站部署了HTTPS如果用户手动输入http://访问第一次连接仍是明文。HSTS的作用是让浏览器记住“这个站点永远只用HTTPS”从根源上杜绝降级攻击。对这个知识点感兴趣的话用Wireshark抓一次HSTS响应头就能看到它是如何工作。5.4 抓到密码之后写在实验报告里的技术结论如果你在授权范围内做了一次抓包实验那你可以把这次实验沉淀成一份技术结论参考格式如下实验目标验证某测试站点是否存在明文密码传输实验方法Wireshark抓取HTTP登录流量定位POST请求实验现象POST正文中直接出现password字段的明文值风险评估局域网内任意用户可以捕获该口令整改建议启用HTTPS、关闭HTTP端口、登录页启用安全头这正是我的实际经验抓包实验本身价值并不在于“抓到密码那一刻的兴奋”而在于你由此理解了网络协议的安全边界能把这些知识转化成对系统、对用户的保护。我从那次给运维同事展示抓包结果以后就养成了检查任何系统登录页是否强制HTTPS的习惯项目上线前必定会做一轮流量层面的安全自查。回到题目本身——Wireshark抓密码本质是HTTP协议明文的必然结果。知道这个事实既能帮你理解网络调试中“看不见内容”的种种现象也能帮你在设计系统时把安全考虑放到第一步。最后再说一句实在话但凡你的登录系统还在用HTTP就该把它当作最高优先级问题处理这类问题不是“会不会被入侵”而是“什么时候被入侵、被谁看到”。