
敏感文件泄露的核心不是能下载到一个文件而是拿到源码之后读懂了它。 这四关的终点都不是下载到压缩包而是从源码里翻出一个不设防的后门文件访问它Flag 就出来了。⚠️ 本文所有测试均在授权靶场中完成仅用于安全学习与防御研究请勿用于未授权目标。〇、先看通关记录关卡难度泄露点关键动作备份文件泄露1 级网站根目录的backup.zip猜文件名 → 下载 → 解压审计 → 访问后门SVN 泄露旧版2 级.svn/entries.svn/text-base/读文件列表 → 拉.svn-base副本 → 访问后门SVN 泄露新版2 级.svn/wc.dbSQLite下载wc.db→sqlite3查文件名 → 访问后门Git 泄露2 级.git/目录浏览未关解析.git/index→ 拿文件名 → 访问后门四关殊途同归先用任意方式拿到文件清单再从清单里挑出可疑的后门文件直接访问它。一、什么是敏感文件泄露1.1 定义与危害定义服务器上本该只在内部使用的文件源码、备份、配置、版本控制元数据被放在了 Web 目录下且可被直接访问攻击者顺着 URL 就能拿到。本质不是代码写错了而是部署时忘了收拾。这是它和注入类漏洞最大的区别——所以它更像信息收集的延伸而不是注入的同类。危害泄露源码与数据库密码 → 顺藤摸瓜找到后门、密钥、Flag → 为进一步的 RCE 铺路。1.2 必背常见敏感文件清单类型文件名示例泄露什么源码备份www.zip、web.zip、backup.zip、website.tar.gz整站源码数据库备份db.sql、database.sql、backup.sql数据库数据编辑器备份index.php.bak、index.php~、index.php.swp单文件源码配置文件.env、config.php、web.config数据库密码、密钥版本控制.git/config、.svn/entries源码 版本信息系统文件/etc/passwd、/proc/self/environ系统信息日志文件/var/log/apache2/access.log用于 LFI to RCE 这一关的靶场描述是我有一个备份我网站的好习惯——基本等于明示去猜备份文件名。二、核心机制为什么直接访问后门就能拿 Flag这是这几关最容易困惑的地方为什么下载了源码、看到那个文件名访问一下 Flag 就出来了因为那个文件本身就是个后门。它的源码长这样?php $flag_file /tmp/flag.txt; if (file_exists($flag_file)) { $content file_get_contents($flag_file); echo htmlspecialchars($content, ENT_QUOTES | ENT_SUBSTITUTE, UTF-8); } else { echo flag 文件不存在; } ?逐行翻译成人话代码在做什么$flag_file /tmp/flag.txt只认一个地址机密文件在这file_exists(...)先看看它在不在file_get_contents(...)在就整个读出来echo htmlspecialchars(...)打印到页面上它和正常网页的区别只有一个正常页面index.php后门文件bac123321123.php访问前要验证吗要登录、鉴权、参数校验不要访问后做什么按业务逻辑处理二话不说读/tmp/flag.txt并输出一句话直接访问能拿到 Flag不是因为这个 URL 有魔法而是因为服务器上躺着一个不设防、专门用来读 Flag 的脚本。而知道这个文件叫什么名字就是从泄露的源码里来的——这才是源码审计的价值你看到的不是页面表象而是服务器的底牌。三、实战复盘3.1 1 级备份文件泄露目标从网站备份文件中拿到源码找到读 Flag 的入口。思路靶场描述我有一个备份我网站的好习惯等于把方向说了——去猜备份文件名。Payloadhttp://靶场地址/backup.zip成功下载到整站源码压缩包。审计与利用解压backup.zip翻源码目录。发现一个命名很可疑的文件 ——bac123321123.php正常业务不会这么取名。打开一看正是第二章那个读/tmp/flag.txt的后门。直接访问http://靶场地址/bac123321123.php拿到 Flag。小结这关考的不是技术难度而是信息收集的常识——备份文件名有固定字典猜中即可。3.2 2 级SVN 源码泄露旧版text-base信息收集用dirb扫目录dirb http://靶场地址/ /usr/share/wordlists/dirb/common.txt扫出/.svn/entries返回 200 —— 确认存在 SVN 源码泄露。原理开发者用 SVN 管理代码发布网站时忘了删掉.svn隐藏目录。而这个目录里.svn/entries记录了所有受版本控制的文件列表。.svn/text-base/文件名.svn-base每个文件在版本库中的原始副本纯源码。利用访问http://靶场地址/.svn/entries拿到文件列表。列表里有个随机命名的文件极其可疑3b96e9fc-ae54-46bf-9e30-c167f825d7cf.php拉它的源码副本确认http://靶场地址/.svn/text-base/3b96e9fc-ae54-46bf-9e30-c167f825d7cf.php.svn-base看到的正是第二章那个后门。既然确认是后门直接访问原文件http://靶场地址/3b96e9fc-ae54-46bf-9e30-c167f825d7cf.php拿到 Flag⚠️ 易错点三种 URL只有两种能通访问路径结果原因/3b96e9fc-...php✅网站根目录下真实存在这个文件服务器执行它/.svn/text-base/3b96e9fc-...php❌ 404.svn/text-base/下只有.php.svn-base没有.php/.svn/text-base/3b96e9fc-...php.svn-base✅源码副本服务器当静态文件返回浏览器显示或下载要分清执行和显示 以.php结尾 → PHP 处理器执行它输出运行结果 以.php.svn-base结尾 → 不匹配.php的处理规则服务器只把它当普通文件原样吐出来。 所以副本用来看代码原文件用来跑代码。3.3 2 级SVN 泄露进阶新版wc.db这一关出题人把上一关的捷径堵了——.svn/text-base/目录被删掉。但 SVN 从 1.7 开始换了存储方式源码依然在。SVN 版本源码存哪怎么利用旧版 1.7.svn/text-base/*.svn-base直接访问副本或用dvcs-ripper批量还原新版≥ 1.7.svn/wc.dbSQLite 数据库下载wc.db用sqlite3查询利用扫到/.svn/发现text-base/没了但多了一个wc.db约 12K。下载下来curl -o /tmp/wc.db http://靶场地址/.svn/wc.db用sqlite3查文件清单NODES表是核心sqlite3 /tmp/wc.db SELECT local_relpath FROM NODES WHERE kindfile;列表里又出现一个随机命名的可疑文件ef217624-b2d3-4bad-8b33-9b975db7d46a.php直接访问它成功返回 Flag。NODES表关键字段字段说明local_relpath文件在工作副本中的相对路径如index.phpkind类型file/dirchecksum文件校验和指向真正的源码副本content内容字段对普通文件通常为空见下方提醒⚠️一个容易踩的坑不少教程会写SELECT content FROM NODES WHERE ...来直接读源码。但在 SVN 1.7 里普通文件的content字段基本都是NULL——真正的文件内容被单独放在.svn/pristine/校验和前两位/校验和.svn-base通过checksum关联。 所以稳妥的做法是先用local_relpath拿到文件名清单再顺着checksum去读pristine/嫌麻烦就直接上dvcs-ripper一键还原。3.4 2 级Git 源码泄露.git/index漏洞确认直接访问http://靶场地址/.git/目录浏览是开着的返回了标准结构HEAD config index objects/确认存在 Git 源码泄露。原理和 SVN 一样开发者发布时忘了删.git目录。其中文件 / 目录作用.git/HEAD指向当前分支.git/config仓库配置.git/index核心索引记录当前版本所有文件的路径与哈希.git/objects/所有文件内容的压缩对象利用用 VSCode 打开.git/index二进制文件右侧的文本解码区能看到明文文件路径。直接读出了index.php 3367f1809c1eb10b2e87c5544da3a097.png 3b96e9fc-ae54-46bf-9e30-c167f825d7cf.php ← 可疑那个随机命名的.php就是后门。直接访问它http://靶场地址/3b96e9fc-ae54-46bf-9e30-c167f825d7cf.php拿到 Flag另一种思路还原整站源码index只给文件名要拿内容还得配objects/用工具一把梭python3 GitHack.py http://靶场地址/.git/.git/index为什么能直接看出文件名它是二进制格式但其中的文件路径是以明文、用\0分隔存储的——所以随便一个文本 / 十六进制编辑器往右边一看文件名就全露出来了不用装任何工具。四、SVN 与 Git一张表和一个比喻这两个漏洞常被统称源码泄露双雄核心区别在于文件内容怎么存维度SVNGit核心目录.svn/.git/关键文件.svn/entries旧、.svn/wc.db新.git/index、.git/HEAD内容存储直接存原文副本text-base/、pristine/存压缩对象objects/拿源码难度低访问.svn-base就能看中要用工具GitHack还原对象常见利用读entries/ 查wc.db找文件名读index找文件名或用工具还原一个好记的比喻SVN 像复印机把原稿复印一份塞进你的抽屉.svn/text-base找到复印件内容直接就能看。Git 像保险箱把原稿锁进保险箱.git/objects只给你一张清单.git/index清单写着文件在哪但要把原稿掏出来得用工具。两者本质完全一样开发者忘了把管理工具的抽屉从网站目录里搬走被攻击者翻了个底朝天。五、工具速查用途工具 / 命令目录扫描找泄露点dirb、dirsearch、御剑还原 SVN 源码rip-svn.pl -v -u http://目标/.svn/dvcs-ripperKali 自带还原 Git 源码python3 GitHack.py http://目标/.git/解析新版 SVNsqlite3 wc.db SELECT local_relpath FROM NODES WHERE kindfile;手动看 Git 索引VSCode或xxd .git/index六、安全防御建议运维 / 开发者视角这一节的答案很朴素敏感文件泄露几乎全是部署环节的疏忽防御重点是上线前把不该留在 Web 目录里的东西清掉。发布前清理版本控制目录.svn、.git、.hg一律删除更稳妥的做法是用git archive/svn export导出干净副本再部署。备份文件不放 Web 目录备份产物放在 Web 根目录之外或至少加鉴权备份完及时删除。关闭目录浏览Nginxautoindex off;、ApacheOptions -Indexes。在 Web 服务器层直接拒绝拦截.svn、.git、.bak、.swp、.zip、.sql、.env等路径 / 后缀的访问。源码与运行目录分离Web 根目录只放对外需要的文件。统一错误信息不要把详细报错回显给用户避免二次泄露路径信息。七、总结这一专题四关下来真正的收获不是会下载.zip而是这条固定套路找泄露点目录扫描 常识字典backup.zip、.svn、.git……。拿文件名清单text-base目录、wc.db的NODES表、.git/index本质都是文件清单的三种不同载体。审计清单业务不会用随机 UUID 给.php命名——越不像人取的名字越像后门。直接访问后门它不设防不需要参数访问即执行。