news 2026/9/10 20:01:15

Wireshark抓包实战:从登录报文分析到MD5弱类型绕过

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Wireshark抓包实战:从登录报文分析到MD5弱类型绕过

1. 为什么 Day5 的新手适合从“抓包 + 绕过”这对组合切入

Day5 是个很有意思的阶段。前面四天你可能刚装好虚拟机、配好环境、跑通第一个小实验,正在一个“什么都懂一点,又什么都摸不透”的状态。这时候如果让我推荐一个能同时撬动网络协议、前后端交互、安全测试三个方向的学习入口,我会毫不犹豫地说:把 Wireshark 打开,手动抓一次登录报文,再顺手把一个简单的 MD5 校验漏洞绕过去。

很多人会觉得这两个东西没关系。Wireshark 是观察流量的镜子,MD5 绕过是逻辑漏洞利用,一个看传输,一个看校验,怎么会凑到一天学?但实际操作一遍就会发现:抓包让你知道密码在请求里是怎么存在的,绕过让你知道接收方到底是怎么校验的。一个是输入端,一个是处理端,连起来刚好是一条完整的数据链路。新手阶段最缺的不是一个个孤立知识点,而是能把“用户在页面上输入密码 → 网络传输 → 服务端校验 → 返回结果”这条链路串起来的能力。

这个组合还特别适合两类人。第一类是刚入行安全、准备打 CTF 或者做渗透测试的新手,Wireshark 是分析流量必备工具,MD5 弱类型绕过又是 CTF 里高频出现的登录类考点,提前练熟等于给自己攒弹药。第二类是后端开发或全栈工程师,很多人写接口只知道“密码存 MD5”,却不知道这种写法在比较逻辑不当的时候等于开门放人。通过抓包看到登录请求的真实样子,再看着自己的代码被绕过一次,比看十篇安全文章都长记性。

我这篇文章会按自己实际踩坑的顺序来写:装好 Wireshark、正确使用过滤器、抓一次 HTTP 登录请求、分析 MD5 哈希值在认证里的角色、复现两种最常见的简单绕过方式,最后聊清楚正确防御应该怎么写。每个环节都会标注哪些坑新手容易踩,哪些操作需要在什么样的合法环境下进行。如果你手头有 VMware 虚拟机或者本地 Docker,建议跟着边看边做,效果比我单方面输出好得多。

2. 装好 Wireshark 后第一件事:分清两种过滤器,别急着点开始

2.1 安装环境和那个“找不到网卡”的老坑

Wireshark 的安装本身不复杂,Windows 下从官网下载安装包,一路 Next 就能装好。但有个坑我必须提:安装过程中会提示安装 Npcap,这个组件是 Windows 下抓包的核心驱动。新版安装包默认会带上,但有人手滑取消勾选,或者安装的是老版本 WinPcap,结果打开 Wireshark 发现接口列表里空空如也,或者能看见网卡但抓不到包。

如果你遇到“找不到本地网卡”或者“抓包抓不到流量”,按这个顺序排查:

  • 确认 Npcap 已经装上。打开命令行输入sc query npcap,如果提示服务不存在,重新运行安装包补装。
  • 确认 Wireshark 是以管理员身份运行。Windows 下抓包需要管理员权限,右键图标选“以管理员身份运行”,这个问题新人遇到频率极高。
  • 如果系统有多个网卡(VMware 虚拟网卡、虚拟专用网络适配器等),接口列表里会有一堆名字,先找到名字带 Ethernet、WLAN 或者对应你当前上网方式的那个,别抓错。比如你在 VMware 里操作,就选 VMnet8 或对应的虚拟网卡。

macOS 用户装完后也需要在“系统设置 → 隐私与安全性 → 本地网络”里允许 Wireshark 访问网络,否则同样抓不到包。Linux 下最简单,apt install wiresharkpacman -S wireshark-qt装完,用sudo启动就行。

2.2 捕获过滤器和显示过滤器,用错等于白抓

新手最容易犯的错,是把 Wireshark 顶部的过滤栏当摆设,什么都不填就直接开始抓,然后看着满屏花花绿绿的 ARP、DNS、TCP 保活包发懵。Wireshark 有两条过滤链路,这是决定你能不能高效抓包的关键。

捕获过滤器是抓之前设置的,它决定哪些包进入内存。语法相对简单,写在捕获选项里。比如我只想抓本机和某个 IP 之间的 HTTP 流量,就可以用:

host 192.168.1.10 and tcp port 80

显示过滤器是抓完之后,在结果里筛出符合条件的包。它用的是一套更强大的表达式,写在主界面顶部的过滤栏。比如我想从一堆包中找出所有 POST 请求:

http.request.method == "POST"

两者最大的区别是:捕获过滤器帮你省资源,显示过滤器帮你省眼睛。新手阶段建议捕获时不要加太多限制,先全量抓下来,再用显示过滤器反复筛选。为什么?因为有些问题你当时没意识到需要某个字段,要是捕获阶段就过滤掉了,后面想查都查不到。我见过不少人只抓了 80 端口,回头发现登录接口走的是 443,不得不重新抓一遍。当然,如果流量特别大、机器扛不住,那另说。

理解这两个过滤器的区别,能让你在分析网络问题时少走两个小时的弯路。我自己刚开始学的时候,就是用错了过滤器,半天看不到想要的请求,差点以为是 Wireshark 坏了。其实工具没坏,是我过滤条件写错了。

3. 抓一次“登录”,看包里的密码是怎么流动的

3.1 在本地起一个带登录页的试验环境

开始抓包之前,我强烈建议你别拿公网上的任何网站练手。一来你没授权,二来 HTTPS 流量抓下来全是密文,新手看了只会更懵。最稳妥的做法是在自己电脑上搭一个本地测试环境,流量走的是回环地址127.0.0.1,整个过程完全可控。

用 Python 的 Flask 搭一个最简单的登录接口,可以照着下面这段来:

from flask import Flask, request import hashlib app = Flask(__name__) @app.route('/login', methods=['POST']) def login(): username = request.form.get('username') password = request.form.get('password') # 先打印出收到的密码原文和它的 MD5 值 print(f"username: {username}") print(f"password raw: {password}") print(f"password md5: {hashlib.md5(password.encode()).hexdigest()}") return "login attempt recorded" if __name__ == '__main__': app.run(host='127.0.0.1', port=5000)

再用浏览器打开一个最简单的 HTML 登录页,把表单的action指向http://127.0.0.1:5000/login。这个环境足够让你观察到底层数据流动了。跑起来之后,打开 Wireshark,选择 Loopback 或 lo 网卡,开始抓包。然后正常在页面上输入用户名和密码点提交,几秒钟后回到 Wireshark 停止抓包,在显示过滤器里输入:

http.request.method == "POST"

你会看到一条发往127.0.0.1:5000的 POST 请求。双击这条记录,在中间的面板里依次展开 HTTP 协议层,找到 HTML Form URL Encoded 部分——用户名和密码就明文躺在那里。这一幕值得每个新手亲眼看一次:你在前端页面上输入的一切内容,如果没有 HTTPS 保护,在网络里就是这样的透明状态。

3.2 三次握手和分层结构,顺便就理解了

等你在 Wireshark 里找到了那条 POST 请求,往上翻几条,能看到这个连接建立时的三次握手:SYN、SYN-ACK、ACK。新手不用去背教科书里的定义,只需记住一个类比:SYN 相当于你问对方“在吗?我要发数据了”,SYN-ACK 是对方回“在的,你发吧”,ACK 是你确认“好,那我开始了”。三次握手解决的核心问题,是让双方都知道彼此已经准备好,可以开始传数据了。

再顺着封包详情面板往下看,你会看到 Wireshark 帮我们解析好的层次结构:最底层是以太网帧(Ethernet),往上是 IP 层,再往上是 TCP 层,最上面才是 HTTP 层。这四层刚好对应现实中的寄包裹流程:HTTP 是信封里的信纸,TCP 是快递单,IP 是地址系统,以太网是货车司机能看懂的路牌。每发一次请求,数据就按这个顺序层层打包,到达服务端再解包。Wireshark 把这些过程全部可视化,比你看十遍“OSI 七层模型”的文章都直观。

3.3 密码是明文,那 MD5 在哪里出现

如果你跟着上面的 Flask 代码实践,你会注意到一个细节:服务端打印出来的密码是原文,同时又计算出了它的 MD5 值。这在真实的登录系统里其实很常见——很多系统的前端或后端在传输层对密码做一次 MD5 后再校验,或者数据库里存的就是 MD5 值。麻烦的地方在于:MD5 算出来的是一个固定长度的十六进制字符串(32 位),它长得像密文,但它并不是真正的加密算法。

这里先搞清楚一个概念:MD5 是哈希函数,不是加密函数。加密是加了密还能解开的,哈希是单向的——雪崩效应极强,原文差一个字符,输出完全不同;而且从哈希值反推原文没有数学上的逆运算。你在网上看到所谓的“MD5 解密”,本质上是把海量常见字符串预先算好 MD5,存成“彩虹表”,然后拿你的哈希值去查表。如果原文是强密码且加过盐,这种“解密”基本失效。

那标题里说的“MD5 简单绕过”又绕在哪里?绕的不是 MD5 本身,而是使用 MD5 的校验逻辑。下一节我会拆解一个非常经典的例子,它在 CTF 里出现率极高,而且代码写错的人远比想象中多。

4. MD5 弱类型比较绕过:0e 字符串为什么能骗过后端校验

4.1 PHP 弱类型比较中的 0e 魔术

如果你用 PHP 写过登录校验,大概率见过类似这样的代码:

if (md5($user_input) == $target_md5) { // 登录成功 }

这行代码在普通情况下没有任何问题:用户输入的密码算出来 MD5,跟数据库里的目标 MD5 比对,相同就放行。但只要有点安全意识的人看到==md5()组合,就会立刻意识到:这里可以绕。

问题出在 PHP 的弱类型比较规则上。==比较两个值的时候,如果两边都是可以转成数字的字符串,PHP 会先把它们转成数字再比。而科学计数法表示的数字,比如0e123,会被解读为 0 乘以 10 的 123 次方,结果就是 0。也就是说,任何以0e开头、后面全是数字的字符串,在 PHP 弱比较中都会等于 0

现在把这个规则套回 MD5 场景:如果某个字符串的 MD5 值恰好是0e开头加一串数字,那么md5($user_input)和另一个同样以0e开头的 MD5 字符串用==比较时,两边转数字都等于 0,比较结果就是相等。

有一个经典的例子:字符串QNKCDZO的 MD5 值是0e830400451993494058024219903391。另一个常见例子是240610708,它的 MD5 值也是0e462097431906509019562988736854。只要目标系统的校验逻辑是md5($input) == $target_md5,并且$target_md5恰好也是这样的值,你就根本不需要知道任何人的真实密码,直接传入QNKCDZO就能通过校验。

为了让你更直观地看到这一点,我在本地 PHP 环境里跑一段代码:

<?php $input = "QNKCDZO"; $target = "0e830400451993494058024219903391"; if (md5($input) == $target) { echo "bypass success"; } else { echo "login failed"; } // 输出: bypass success

原因就是md5($input)的结果同样是0e开头,两个字符串在==下都被当成了 0。如果我把代码改成:

if (md5($input) === $target) { echo "bypass success"; }

结果就会是login failed,因为===要求类型和值完全一致,"0e830400..."是字符串,不会参与数字转换。

4.2 这个绕过有什么用,以及新手容易踩的坑

这种绕过在 CTF 的登录题里最典型:后端代码直接给出md5($password) == "某个0e开头的目标值",你只需要找到一个 MD5 也是0e开头的输入字符串,或者干脆提交目标值本身,就能登录成功。它之所以叫“简单绕过”,是因为不需要动用任何暴力破解,纯粹是利用了语言特性和比较符选择不当。

新手在复现这个姿势时,最容易踩的坑是以为所有以0e开头的字符串都能用。注意,必须是0e后面全是数字才行。0eabc这种带字母的,PHP 转换成数字时会失败,结果就是字符串,比较规则又不一样了。你可以自己多跑几个md5()看看输出,凡是0e后面混入了字母的,在弱比较里基本都不生效。

还有一个认知误区和这个技术点强相关:有人把“MD5 弱类型绕过”理解成“把目标 MD5 值反过来推出明文密码”,也就是前面说的“MD5 解密”。这是两种完全不同的思路。弱类型绕过是绕过校验规则,而不是破解哈希本身。我不会花大量篇幅教你怎么查彩虹表,一方面那是另一个话题,另一方面,真正的安全测试和 CTF 比赛也都不会停留在“查表”这种毫无技术含量的方式上,核心考察的永远是你对程序逻辑和语言特性的理解深度。

需要特别说明的是:这类实验一定要在本地环境、CTF 在线靶场或者自己搭建的测试环境里进行。不要拿这个思路去对任何没有授权的线上系统做验证,一是违法,二是你根本不知道目标系统用的什么语言和比较方式,盲试没有任何意义。

5. 只校验前端的登录接口,改一个包就能绕过

5.1 前端校验带来的虚假安全感

如果说弱类型比较是后端语言特性的坑,那前端校验就属于产品设计层面的坑,而且在这个领域出现的频率比想象中高得多。很多开发团队为了让用户感觉“密码经过了加密处理”,会在前端用 JavaScript 把密码算成 MD5,再 POST 给后端。这时候问题就来了:如果后端只判断“密码字段是否为空”,或者干脆直接以 MD5 字符串入库而不做任何哈希验证,那么整个认证就变成了一张纸。

我见过一个很典型的演示项目,前端这样写:

// 用户点击登录后,计算 MD5 再发送 const passwordHash = CryptoJS.MD5(passwordInput.value).toString(); fetch('/login', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `username=${username}&password=${passwordHash}` });

而后端代码大概是:

@app.route('/login', methods=['POST']) def login(): username = request.form.get('username') password = request.form.get('password') if len(password) > 0: # 直接登录成功 return "login success"

这种系统在普通用户手里没有任何问题,因为普通用户只会老老实实打开页面输入密码,让前端去算 MD5。但你用 Wireshark 抓一次包就会发现,所谓的“MD5 加密传输”并没有改变认证的本质——后端没有校验这个 MD5 是否对应一个正确的原始密码,它管理的是“有没有提交密码字段”。那绕过思路就简单到令人发指了:直接改掉被发送的数据包,把密码字段的值换成任意字符串,甚至换成1,后端照样放行。

5.2 用 Burp Suite 或浏览器开发者工具完成一次改包实验

要在本地靶场复现这个过程,我建议会用 Burp Suite 的同学直接上 Burp,不会用的用浏览器 F12 里的开发者工具也能完成。下面以浏览器开发者工具为例,讲一下完整的操作链路。

第一步,在本地把上面那种只做前端 MD5、后端不校验哈希的 Flask 服务跑起来。第二步,在登录页面输入一个密码,提交前打开开发者工具,切到 Network(网络)面板,勾选 Preserve log(保留日志),然后点登录。第三步,在 Network 面板里找到那条 POST 请求,右键选择 Edit and Resend(编辑并重新发送)之类的功能,或者直接在 Payload 区域把password字段的值改掉,改成任意一段字符串。第四步,点击发送,观察服务端返回结果。

如果服务端逻辑真的只是“校验字段非空”,你会看到服务端依然返回login success。而这个过程中,你并没有经过前端那些计算步骤,连 MD5 都没算,就直接通过了校验。这个实验的价值在于让你亲眼确认:前端所做的一切哈希、加密、校验,本质上都只是用户体验层面的包装,真正的安全边界必须在服务端落地。

当然,改包工具的使用要非常克制。Burp Suite 是合法的安全测试工具,但用它去改别人的线上请求,在法律和道德上都有问题。我只建议在自己可控的环境里做这种实验,比如本地 Docker 起的靶场、自己的虚拟机上部署的应用,或者 CTF 平台提供的题目环境。这一点想清楚了,你学到的技术才不会是隐患。

5.3 从抓包看到改包,一条线串起来

现在回头看我们 Day5 的所有实验,你会发现路径非常清晰:先用 Wireshark 抓到 POST 请求,看到密码在请求体里的真实形态;再根据后端代码的逻辑,思考它到底校验了什么;最后通过构造数据包来验证自己的判断。抓包和改包本质上都是为了回答同一个问题——“服务器到底相信了什么?”

这个问题问得越多,你对安全的直觉就越准。以后你看到一个登录接口,会本能地想:它校验的是密码原文,还是密码哈希?它比较哈希时用的是严格比较还是弱比较?校验逻辑放在前端还是后端?数据库里的哈希值是从哪来的?这些问题一旦成为你的习惯,很多漏洞在你眼皮底下就直接暴露了,不需要用什么高级扫描器,也不需要多复杂的 PoC。

6. 绕过之后回头补防御:这些坑在真实项目中怎么填

6.1 强制哈希比较用恒定时长函数

弱类型比较的修复方案其实很明确。第一,比较两个哈希字符串时,用严格比较运算符===而不是==;第二,更稳妥的做法是用语言自带的“恒定时长字符串比较”函数。PHP 里的hash_equals()、Python 里的hmac.compare_digest()、Node.js 里的crypto.timingSafeEqual(),都是干这件事的。使用恒定时长比较可以防止时间侧信道攻击,防止攻击者通过响应时间的微小差异逐步猜出哈希值。

很多开发者在刚开始写代码时根本不会意识到=====的差别,也不了解0e这种科学计数法字符串的转换规则。但实际上,这些语言特性在官方文档里写得清清楚楚,只是在业务代码里很少有人去注意。安全培训常说“不要相信用户输入”,这不仅仅指 SQL 注入和 XSS,也包括“不要相信用户输入的字符串在比较运算中不会触发语言特性”。把这句话当成开发习惯,能少踩很多坑。

6.2 密码存储的正确姿势:加盐哈希和专用密码函数

再往深一层说。即使你把比较符改成了严格模式,只要系统里存储的还是裸 MD5 值,风险依然存在。MD5 的碰撞攻击和彩虹表让我们早就有了共识:MD5 不适合用来存储密码,甚至 SHA-1 也一样不合适。正确做法是使用专门的密码哈希算法,比如 bcrypt、scrypt、Argon2,或者使用语言内置的password_hash()/password_verify()这类封装好的函数。

这类算法有几个共同特点:自动加盐、计算成本可调节、每次生成的哈希值随机。加盐是最关键的一环——哪怕两个用户密码完全相同,因为有盐值参与计算,最终存储的哈希值也完全不同,攻击者连“这两个用户是不是同一个密码”都没法判断。而调节计算成本,是为了让暴力破解每个候选密码都需要大量算力。这些思路对新手来说可能显得有点“超前”,但至少应该知道一个原则:不要自创密码存储方案,直接用被安全社区验证过无数遍的标准方案。

6.3 安全学习的正确方式:搭台、拆台、再补台

最后说点个人体会。很多新手学了抓包和绕过之后,容易产生一个误区,觉得“我能绕过登录接口了,我是不是也能攻击别人的网站了”。这个想法很危险,也很幼稚。真实世界里的登录系统大概率有 WAF、有 HTTPS、有多因素认证、有风控策略,不是你拿个0e字符串就能进去的。你练习用的那种“裸奔”项目,如果真出现在生产环境里,问题根本不在攻击者的技术,而在开发者的安全意识。

我自己的经验是:每学一个绕过姿势,就顺手把它对应的修复方案写一遍。学完弱类型比较,就去把代码改成===并模拟测试,确认无法绕过;学完前端校验绕过,就把校验逻辑移到服务端,再加一层限流;学完 MD5 不适用于密码存储,下一个项目里就用password_hash()。把拆台和补台当成一对动作来练习,你的技术体系才是完整的。防御知识学得越多,你对“绕过”这两个字的理解就越深,因为在安全领域,最了解盾牌薄弱点的人,往往就是那个亲手砸过盾牌的人。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 20:01:04

电源设计从入门到实战:拓扑、选型、布局与调试

电源这东西&#xff0c;被叫成“心脏”一点都不夸张。你想想&#xff0c;人没了心脏啥也干不了&#xff0c;电子电路也一样——CPU、运放、传感器、电机&#xff0c;每一颗芯片都需要一个稳定、干净的供电环境。很多刚入门的朋友总觉得电源就是插个电、接个线的事&#xff0c;可…

作者头像 李华
网站建设 2026/9/10 19:56:33

Mac智能切片软件横评:5款真正可用的AI视频自动分段工具

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

作者头像 李华
网站建设 2026/9/10 19:55:25

2024年值得关注的5个Python新库:从交互式笔记本到纯Python前端

Python生态这几年最大的特点&#xff0c;不是某一个框架突然爆发&#xff0c;而是“新库”一本书一样地冒出来。有些库刚在GitHub上挂了几天&#xff0c;星星还没捂热&#xff0c;就被后面的新项目盖过去。真正值得长期关注的&#xff0c;是那些解决了真实痛点、且作者团队有明…

作者头像 李华
网站建设 2026/9/10 19:52:37

微电网能量管理中的鲁棒优化:从不确定集建模到工程落地

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

作者头像 李华
网站建设 2026/9/10 19:48:35

MATLAB实现33节点配电网分布式发电优化配置

1. 33节点配电网与分布式发电的背景解析 电力系统领域近年来最显著的变化之一就是分布式发电&#xff08;Distributed Generation, DG&#xff09;的大规模接入。传统配电网设计时假设电能单向流动——从高压输电网通过变电站降压后流向用户。但随着光伏、风电等可再生能源的普…

作者头像 李华