1. 漏洞概述
敏感信息泄露(Sensitive Information Disclosure)是指网站在无意间向用户暴露了敏感数据。这些数据可能是由于配置不当、代码错误或开发者疏忽造成的。
常见的泄露形式包括:
- 前端 HTML/JS 源码中硬编码了密码、API Key 或内网 IP。
- 报错信息(Debug 模式)直接回显到了前端页面,暴露了物理路径或数据库结构。
- 目录浏览(Directory Listing)未关闭,导致备份文件(.bak, .swp)或源代码被下载。
本次关卡演示的是最典型、也是由于程序员疏忽导致的一种低级漏洞:在前端 HTML 注释中遗留了测试账号密码。
2. 闯关实操 (Exploitation)
第一步:常规尝试与信息收集
打开关卡页面,首先看到的是一个登录框。我们先尝试使用已知的账号 vince / 123456 进行登录。
登录成功后,页面跳转并展示了一段王小波《黄金时代》的经典语录。此时,习惯性地右键查看该页面的网页源代码(F12),并没有发现什么隐藏的有用信息。
第二步:回溯并审查前端源码
既然登录后的页面没有线索,我们退回到 初始的登录页面 。
在登录页面,我们再次右键选择“查看网页源代码”。向下拉动代码,仔细审查 HTML 结构。
果然,在表单代码 <div class="form_main"> 的闭合标签下方,我们发现了一段 HTML 注释:
</div><!-- 测试账号:lili/123456-->
</div><!-- /.widget-body -->
第三步:验证漏洞
我们立刻提取注释中泄露的信息:
- 账号:
lili - 密码:
123456
返回登录框,输入这组账号密码,点击 Login,成功登录!我们通过开发者无意间留下的“后门注释”,轻松获取了系统的访问权限。
3. 源码分析 (Code Review)
我们来看看后端 findabc.php 的源代码,为何会导致这种泄露。
<!-- ... 省略上方 PHP 逻辑代码 ... -->
<div class="clearfix">
<label><input class="submit" name="submit" type="submit" value="Login" /></label>
</div>
</form>
<?php echo $html;?>
</div><!-- 测试账号:lili/123456-->
</div><!-- /.widget-body -->
<!-- ... 省略下方 HTML 代码 ... -->
漏洞成因分析:
- 开发习惯不良:在开发或测试阶段,程序员为了方便记忆或交接,顺手把测试账号写在了 HTML 注释
<!-- ... -->里。 - 发布前未清理:在项目上线部署到生产环境之前,没有进行严格的代码审计和清理工作。
- HTML 注释的特性 :PHP 引擎在解析
.php文件时,只会处理<?php ... ?>标签内的代码。对于 HTML 标签(包括注释),PHP 会 原封不动 地输出给客户端浏览器。只要用户查看网页源码,这行注释就暴露无遗。
(注:不仅如此,通过查看上方的 PHP 源码,我们发现代码中甚至使用了 setcookie('abc[pw]',md5($_GET['password']),time()+36000); 将密码的 MD5 值直接存在了 Cookie 中,这也是一种非常不安全的敏感信息处理方式。)
4. 修复建议
防止此类敏感信息泄露的方法非常简单但至关重要:
- 上线前代码审查:在代码合并和上线部署前,必须剔除所有包含敏感信息(账号、密码、内网 IP、API 密钥等)的调试代码和测试数据。
- 区分前后端注释:
- 如果需要在代码中留下备忘录,应使用 服务端语言的注释(例如 PHP 中的
//或/* ... */)。服务端注释在处理完毕后不会被发送到用户的浏览器。 - 绝对不要 使用 HTML 的
<!-- ... -->或 JavaScript 的//来记录任何涉及业务逻辑、权限或配置的敏感信息。
- 如果需要在代码中留下备忘录,应使用 服务端语言的注释(例如 PHP 中的
- 禁用 / 删除测试账号:生产环境的数据库中不应存在默认的、弱口令的测试账号(如本例中的 lili/123456)。