☰
CTF信息搜集方法论:敏感文件与目录扫描实战指南
2026/10/16 7:07:12 网站建设 项目流程

CTF里有一句老话:不会做和没看到,往往是同一件事。很多题目卡住你半小时,不是因为你不会利用漏洞,而是因为你压根没发现那个藏在角落里的敏感文件。我自己的感觉是,CTF中的敏感信息搜集,更像是拿着手电筒在黑屋子里找钥匙——钥匙就在某个地方,关键是你有没有一套系统的找法。这篇文章想从零到一把这套信息搜集方法论讲清楚,附上我自己整理的高频敏感文件清单,适合刚入门的选手,也适合目录扫描扫完不知道下一步干嘛的兄弟。

先说一个我踩过的场景。某次web方向的模拟演练,一个入口页面只有一个登录框,我对着它试了二十分钟弱口令,全是徒劳。后来静下来想了想,用目录扫描器带了一份中等字典扫了三分钟,扫出一个.env.bak文件,下载下来里面直接躺着数据库账号名、密码和密钥。整套突破口就在这三分钟里。这个经历让我意识到,大部分时候不是题目太难,而是我们的信息搜集流程不完整,漏掉了太多本该被发现的线索。

1. 信息搜集的定位:为什么它决定了CTF的下限

1.1 信息搜集和渗透测试的信息收集有什么不同

很多人会把CTF里的信息搜集和实际攻防演练中的信息收集混为一谈,其实两者的目标不完全一致。实际演练中,信息收集的目的是梳理资产、扩大攻击面、寻找可利用的漏洞入口,是一个偏系统工程的阶段;而CTF里的信息搜集,更偏重“把题目设计者故意埋下的线索找出来”。

换句话说,CTF题目几乎是“一切皆有伏笔”。不会出现一个无意义的文件、一段多余的注释、一个随手留下的备份。这与真实世界的随机性和混乱感完全不同。这带来一个很重要的推论:如果你在CTF中发现了一个异常文件,它大概率不是“恰好存在”,而是题目特意安排的。我们搜集信息时,需要带着这种“万物皆有可能是线索”的直觉去审视每个发现。

我见过不少新手一上来就用最大字典猛扫目录,扫到一堆200就兴奋,结果发现全是静态资源,反而把真正有价值的config.php.bak给淹没了。这是思路问题——先明确目标,再动手,效率会高很多。

1.2 为什么说“信息搜集决定了下限”

说个极端点的结论:在CTF的web方向,一个信息搜集做得细致的人,可能不需要掌握多少代码审计技巧,也能拿下中等难度的题目。反过来,一个只会打已知CVE的人,如果跳过信息搜集直接进攻,大概率会在入口处卡死。

原因很简单。绝大部分题目的第一步都不是让你利用某个CVE,而是让你“找到”某个入口。这里说的入口可能是一个隐藏的目录、一份泄露的源码、一个带注释的接口文档,甚至是一段附着在图片里的字符串。这些入口全部都依赖信息搜集来发现,而不依赖你的攻击知识库有多深。

我有一次参加模拟赛,一个题目表面上是一个博客站点,扫目录扫到一个uploads/目录,里面的文件名是一串类似20231214_153022.txt的日志文件。点进去之后发现,里面记录了服务端响应的调试信息,包含一个内网IP和一个端口号。顺着这个端口号做本机端口访问,直接拿到了隐藏站点。整个过程没有一个漏洞利用动作,全是在“读信息”。

所以我觉得,信息搜集能力,才是CTF真正考察的“基本功中的基本功”。它决定了你在一个题目里能走多深,也决定了你的下限。

2. 被动信息搜集:从公开渠道把目标底细翻出来

被动信息搜集,简单说就是不直接触碰目标,而是通过搜索引擎、代码仓库、网页快照等第三方渠道去收集目标的信息。这个阶段的意义在于,它往往能给你一个“初始地图”,告诉你目标大概长什么样,可能有哪些隐藏入口。

2.1 搜索引擎语法:最快的一刀

很多人觉得搜索引擎谁不会用,但在信息搜集场景里,搜索引擎的价值被你严重低估了。这里的关键不是“搜一下”,而是用特定语法去“定向挖料”。

最常用的几个语法组合:

  • site:目标域名—— 限定域名搜索所有收录页面,可以发现一些目录扫描扫不到的隐藏页面
  • site:目标域名 filetype:txt—— 找出该域名下所有 txt 文件,日志、说明文档经常藏在里面
  • site:目标域名 inurl:admin|api|test|temp—— 从URL里找敏感路径痕迹
  • site:目标域名 intext:"password" or intext:"api_key"—— 从页面正文里找泄露的凭据痕迹

举个例子。有次别人跟我分享一道题,入口是一个普通的公司展示页,表面没有任何进入后台的链接。我用site:该域名 inurl:backup搜了一下,居然搜到了一个被搜索引擎收录的backup.zip页面链接。这告诉我们一件事:搜索引擎的爬虫比你更勤快,它已经把目标的犄角旮旯翻了无数遍。你只需要学会向它提问。

有人可能会问:“如果目标是本地靶场,没有公网域名,搜索引擎语法还有用吗?”这种情况确实受限,但你还是可以用搜索引擎搜题目作者常用的账号名、常用文件名,有时候也能歪打正着。真正的核心是把“搜索引擎语法”当成一种条件反射,在任何信息搜集阶段都先跑一遍。

2.2 代码托管平台与网盘:露天矿藏

CTF题目有时候并非只在目标站本身藏信息。题目作者可能把源码提交到公开的代码托管平台,或者把附件传到网盘上,然后忘记关闭链接。这在真实题目里不算罕见,尤其是那些由爱好者自己出题的非商业比赛。

代码托管平台的搜索语法也很简单,核心思路是搜索目标域名、题目名、作者名相关的代码片段。比如搜目标域名 + "config",或者搜题目名称 + "flag",都有可能意外发现源码片段甚至是备份仓库。更进一步,可以用代码搜索功能搜.env、database.php、wp-config.php这类常见敏感文件名,如果目标站点被约束在这些文件里,搜出来的概率相当可观。

网盘搜索引擎也是个好用的东西。很多题目会附带一个文件下载链接,这个链接可能被发布者分享在某个论坛或网盘上。如果你拿到了一个网盘分享链接的一部分,用网盘搜索工具补全链接甚至直接搜文件名,往往能把附件提前挖出来。我自己见过一题,光靠搜文件名就在网盘里找到了一个和题目环境相同版本的源码压缩包,等于提前拿到了参考答案。

2.3 历史快照与站点元数据:零成本情报源

历史网页快照是个容易被忽视的情报源。某些站点会定期抓取网页存档,这意味着你可以看到目标站点的历史版本。一个CTF题目站点如果上线过多个版本,旧版本里很可能残留了调试信息、测试接口或者题目作者留下的路径痕迹。使用互联网档案馆的网页回溯服务,输入目标域名,就可以看到它在某年某月某日的旧容貌。

站点元数据也很值得看一眼。比如从网站首页源码的<meta>标签里,偶尔能看到生成器信息、作者名、模板版本号。这些看似无用的数据,有时候能直接指向某个已知漏洞版本,或者给出一个作者喜欢用的命名规律——这个规律在目录扫描时能大幅提升字典命中率。

补充一句,被动信息搜集阶段不只是“搜一下”就完事了,它产出的每一条信息都要被记录、归类,因为后面主动探测时你会频繁需要它。我习惯用电子表格记录域名、IP、路径、文件名、可疑注释,甚至可疑图片的URL,这一步在后文会展开讲。

3. 主动探测:与目标握手,逼出隐藏文件

被动信息搜集有了底子之后,接下来进入主动探测阶段。这个阶段的特点是你直接和目标站点进行交互,通过发送请求来观察响应,从而发现那些没有被搜索引擎收录的隐藏资源。

3.1 目录扫描:粗糙但有效的一锤子买卖

目录扫描是主动探测里最常规、也最依赖“工具+字典”组合的动作。这个动作的本质,是用一个字典列举目标站点上可能存在的路径,然后根据HTTP响应状态码和内容来判断路径是否存在。

工具方面,成熟的开源扫描器有很多,比如 dirsearch、dirb、gobuster,都支持并发和递归扫描。不同工具的差异其实不大,真正的差距在字典。我见过太多人随便套一个小字典就去扫,结果扫完啥也没有就放弃了。正确的做法是准备多份字典:一份常见路径小字典(用于快速试探),一份备份文件专项字典(用于找 .bak、.swp、.old 这类文件),一份超大路径字典(用于地毯式搜索)。扫描时按“从小字典到大字典”的顺序推进,先把高危项扫出来,再考虑全面性。

一个容易被忽略的参数是“后缀名”。默认情况下很多扫描器只扫预设后缀,比如.php、.html、.asp。但真实题目里,敏感文件可能是.txt、.log、.zip、.sql、.tar.gz。我习惯把后缀列表扩成:php、html、txt、zip、sql、bak、conf、log、xml、json、tar.gz、env。一个小后缀列表,有时候比字典本体的作用还大。

扫描结果的判读也很重要。不是所有200都值得访问,也不是所有404都代表不存在。有些服务器配置了“任意路径返回200”的伪静态规则,这时候你就要看响应内容长度来判断是不是真的存在。我之前碰到过一个环境,凡是扫描器请求的路径,服务器都返回200和一个自定义的欢迎页面,只有命中真实文件时内容长度才会变化。这种时候,只盯状态码的选手就会全军覆没。

3.2 子域名与端口服务:扩大攻击面的两个抓手

如果CTF题目给的是一个域名,而不仅仅是一个IP加端口,那么子域名枚举应该排在目录扫描之前。因为子域名往往对应着完全不同的应用系统,攻击面和题目入口都可能是独立的。

子域名枚举有两种思路:一是用API方式,通过证书透明度日志来获取子域名列表,覆盖面广、速度快;二是用字典爆破,一个词一个词地尝试。两种思路各有侧重,我通常先跑API的,再用一份子域名字典补漏。拿到了子域名列表之后,对每个子域名再重复一遍被动+主动的信息搜集流程。

端口服务识别则是另一种扩大攻击面的方式。用端口扫描器对目标IP做一次全端口识别,能看到目标开放了哪些服务。如果题目环境里有个奇怪的端口,比如8000、8080、8888,或者不明服务端口,那几乎可以肯定它也是一个入口。有一个原则我一直记着:题目环境里不该出现的东西,都是线索。如果你扫到了一个来路不明的端口,多花点时间把它搞清楚,比在已知端口上较劲划算得多。

3.3 robots.txt、sitemap.xml与入口文件的阅读技巧

很多新手看到 robots.txt 只是打开看一眼就关掉,觉得这东西没什么用。但在CTF里,题目作者往往会特意在 robots.txt 里放一条指向隐藏目录的Disallow路径。这个路径可能就是通往后台、备份文件或上传目录的直接线索。

类似的还有sitemap.xml,它虽然是为了搜索引擎收录而存在的,但也可能暴露出一些你扫不到的深层页面。像crossdomain.xml、security.txt,偶尔也会出现一些题设性的提示信息。

我读这类文件有一个习惯:不只看路径,还看路径的命名风格。如果robots.txt里有一个/tmp-abc/这样的目录,那大概率作者喜欢用/目录-关键词/这种命名方式,接下来你要扫描的字典就完全可以参照这个规律来定制。这种做法,就是用一个已知索引去反推整个路径体系,命中率奇高。

还有一个入口文件容易被忽略,就是phpinfo.php或test.php这类调试页面。在真实渗透测试里,它们可能是运维失误留下的;在CTF里,它们往往是“故意”留下的信息源。从phpinfo.php的配置信息里,你可以读到绝对路径、启用的函数、扩展模块列表、乃至环境变量——这些信息在后续构造攻击链时非常有用。信息搜集时,凡是遇到这种调试口,别急着关,逐行看一看。

4. 常见敏感文件清单:那些藏在角落里的作弊纸

这一节我整理了一份在CTF中高频出现、且价值极高的敏感文件清单。每一类都简单说明一下“它为什么敏感”和“看到它之后该怎么想”。这部分的参考价值最大,建议收藏后用目录扫描器配一份对应字典去实战。

4.1 配置文件:往往藏着一整套凭据

配置文件是信息搜集里含金量最高的文件类型之一。它们之所以敏感,是因为一个站点的正常运行必然需要数据库账号、密钥、第三方接口凭据,而这些东西几乎都会出现在配置项里。

常见配置文件名包括:

  • .env—— 环境变量文件,常存放数据库连接、App Key、云服务密钥
  • config.php/config.py/settings.py—— 各类框架的配置文件
  • database.php/db.php—— 数据库连接专用配置
  • wp-config.php—— 站点标准配置文件,内含数据库账密和认证密钥
  • web.config/.htaccess—— 服务器与访问规则文件,有时也配置了连接串

拿到这些文件时,第一反应不是去找flag,而是去读配置里所有的键值对。很多配置文件中会有一项debug=true或APP_DEBUG=true,这意味着站点的调试模式被打开,访问接口时可能直接返回堆栈信息、源码路径甚至查询语句。顺着这个方向挖下去,往往能直接定位到flag所在。

4.2 备份与版本控制文件:源码泄露的经典路径

备份文件是CTF web题里最经典的敏感文件类型。它们的存在,赤裸裸地暴露了题目的源码、数据结构甚至服务器环境。

  • www.zip/backup.zip/site.tar.gz—— 整站打包的压缩包,解压后是最完整的源码
  • index.php.bak/config.php.bak—— 单文件备份,知识点型题目常用
  • .git目录泄露 —— 如果目录扫描扫到了.git,你可以用工具把整个仓库历史拉下来,查看提交记录里是否出现过被删掉的flag或敏感配置
  • .svn目录泄露 —— 和.git类似,但利用工具链略有不同
  • .DS_Store—— 虽小但有用,能列出所在目录的所有文件名,是发现隐藏文件的好帮手
  • .swp/.swo/~结尾文件 —— 文本编辑器留下的临时和备份文件,会泄露源码片段

这类文件的共同特点是:它们不是页面,而是文件。所以你的目录扫描器如果默认只扫描页面路径,可能压根不会命中它们。我自己的习惯是把压缩包后缀和备份后缀都加到扫描后缀列表里,再用一份专门的备份文件字典跑一遍。

拿到压缩包后不建议急着解压满屏找flag。先把文件结构过一遍,确认是否有版本控制目录、是否有数据库备份、是否有专门的flag相关文件。一份源码里最有价值的东西,除了flag本身,就是数据库初始化脚本——它会把整个数据结构、默认账号密码都告诉你。

4.3 文档、日志与页面注释:容易被忽略的信息

和配置、备份文件相比,文档和日志更容易被忽视,因为它们的结构不“规整”,需要读内容才能发现价值。但在CTF里,它们恰恰是最贴近“题目线索”的存在。

  • README.md/接口文档.md/ 各类手册 —— 会写明站点的功能、接口路径、调用方式,甚至给出示例账号
  • access.log/error.log—— 服务器日志会记录来路IP、请求路径、错误堆栈,其中错误堆栈往往直接暴露源码路径
  • composer.json/package.json—— 依赖清单,能看出项目用了什么框架、什么版本的组件,某些组件有已知公开漏洞就能直接打
  • Dockerfile/docker-compose.yml—— 给出运行环境的搭建方式,揭示基础镜像和网络配置
  • phpinfo.php/info.php—— 展示服务器配置的调试页面
  • 源码里的 HTML 注释 —— 这是最简单但最常见的泄露源。<!-- TODO: 删除调试接口 -->这种注释,往往是题目作者手滑留下的关键提示

读这些文件时,要注意把“路径”和“参数”都记下来。比如文档里写了GET /api/user?id=1,那说明存在一个API接口;你可以把id换成其他值尝试,或继续搜索是否有相同的API模块泄漏了详情。日志文件里如果出现了一个从来没见过的路径,那基本可以断定还有一层隐藏的入口没被发现。

4.4 常用敏感文件清单总表

我整理了一份按“文件名/出现位置/敏感度/利用思路”排列的简表,方便你用目录扫描器出结果后对照参考。

文件名出现位置敏感度利用思路
.env站点根目录、应用目录极高读数据库凭据、密钥、调试开关
.git站点根目录极高拉取历史仓库,找回被删源码和flag
www.zip根目录、备份目录极高解压还原整个站点源码
config.php.bak根目录、配置目录高获取数据库账号密码及独有配置
.DS_Store任意目录中列出目录文件列表
index.php.swp源码同目录高读取vim交换文件还原源码片段
README.md根目录、子项目中读接口信息、作者提示、部署说明
access.log/var/log、logs中观察请求路径,寻找隐藏入口
error.log/var/log、logs高堆栈信息暴露源码路径和框架类型
phpinfo.php根目录高读配置、扩展、路径、环境变量
Dockerfile根目录中理解镜像构建流程与网络端口
database.sql备份目录、根目录极高直接导入本地数据库,查表结构和默认数据

说实话,这份清单不需要背下来,你只需要理解每一类文件“为什么值钱”,扫描时就会自然形成对路径的敏感度判断。

5. 一次完整的信息搜集实验复盘:从域名到flag的路径

光讲方法论有点虚,这部分我的做法是拿一个虚构的靶机环境走一遍完整流程,帮助你把前面的东西串起来。为了不涉及实际比赛敏感信息,以下场景完全来自虚构的内部实验环境。

5.1 场景设定与第一步观察

假设我们拿到一个目标域名target.example。打开首页后是一个印象化风格的企业展示站,导航栏只有“首页、关于我们、联系我们”,没有登录口,也没有明显的动态功能。表面上看,这是个“死站”。

这时候很多人的第一反应是:是不是题目坏了?我的第一反应是开始信息搜集流程。

第一步:被动信息搜集。用搜索引擎语法搜site:target.example,结果只有首页一条记录,说明这是一个新站或收录不全的站点。再切到代码托管平台搜一下目标域名,没有任何结果。看起来公开情报并没有太多价值。

5.2 被动与主动探测的结合推进

被动情报有限,那就主动探测。先做子域名枚举,API方式扫到了一堆无关子域,字典爆破又跑出了一个隐藏子域dev.target.example。访问它,发现是一个带登录框的后台系统。到此为止,攻击面总算打开了。

接着对这个后台系统做目录扫描。先跑小字典,没发现。换后缀列表,加上env、bak、zip、git,扫到了一处/backup/.env.bak。下载下来,内容是一份环境变量快照,里面有数据库名、数据库用户、数据库密码,还有一行写着一个内网IP。

5.3 敏感文件利用链的闭环

顺着.env.bak找到数据库凭据后,下一步不是登录后台,而是确认这个数据库服务是否对公网开放。做了一次全端口识别,发现目标IP有一个非标准端口33060对外开放,尝试用MySQL协议连接,结果成功。

进了数据库之后,翻了一下表结构,看到一个表名叫hidden_flags。其实到这一步,flag已经等于躺平了。我把整条利用链拆解了一下:子域枚举找到隐藏后台 → 目录扫描配合后缀列表找到备份文件 → 备份文件泄露数据库凭据 → 开放的非标准端口确认数据库可达 → 数据库内直接读取flag。

这条链路上的每一步,单独看都“不强”。但把它们串起来之后,就形成了一个完整的闭环。这就是信息搜集方法论在实际题目中的运作方式:不追求一步到位,而是确保每一步都能为下一步提供有效输入。

5.4 复盘:如果漏掉某一步会怎样

我们做个假设:如果我在子域名枚举阶段草草收场,大概率永远不知道dev.target.example的存在,也就不可能拿到后台,更不可能知道/backup/.env.bak。如果我在目录扫描时没加env后缀,也就扫不到.env.bak。如果我在端口识别时忽略了33060这个非标准端口,数据库凭据就成了死情报。

你看,信息搜集是一条链,不是一锤子买卖。链条上任何一环掉链子,整条链就断了。这也是为什么我强调流程化、记录化。把每一步的结果都记录下来,你会发现,即便当前用不上,后续某一步的关键线索,也往往藏在前面某一步的“废信息”里。

6. 信息搜集的几个坑与提效习惯

最后聊一些实操层面的东西。信息搜集说起来简单——扫目录、查端口、读文件——但做起来你会发现有一堆隐形的坑,下面这几个是我自己常用且实际有效的应对方式。

6.1 最容易翻车的几个习惯

第一个坑是用默认字典打发一切。默认字典覆盖的是最常见的路径,但CTF题目最喜欢用“不那么常规”的路径来增加难度。如果你每次都只扫默认字典,那基本等于把题目交给运气。应对方式是准备一份自定义字典,把历年题目里出现过的敏感路径、备份文件后缀统统加进去,形成自己的词表库。

第二个坑是扫描过一次就认为“扫干净了”。目录扫描的命中率与字典、后缀、并发数、递归设置都相关,换一份字典、换一个后缀列表再扫,结果可能天差地别。我有一次扫一个站点,第一遍只扫出/uploads/,第二遍带后缀列表后扫出了/uploads/.htaccess,第三遍换了另一个大字典竟然扫出了/install/。同一目标,三遍三种结果。所以,少用“我扫过了”这个说法,多用“我换了几套字典扫过了”。

第三个坑是忽视响应内容。刚才说过,有的服务器对任何路径都返回200,如果只盯状态码,你会被虚假的积极信号带偏。看到200时,先别高兴,逐条看响应长度和内容,确认是有效页面还是欢迎页。多用“内容长度差异”来判断,而不是只看200、404、403。

6.2 让信息搜集提效的工作流

第一个习惯是“记录一切”。我用一个记事本分章节记录扫描发现的每个路径和文件,包括当时的URL、状态码、内容特征。到后期构造利用链时,这个笔记就是我的地图,能直接告诉我还有哪些路径没利用、哪些文件没打开。

第二个习惯是“先小字典后大字典”。每次目录扫描我都把扫描分成两轮:第一轮快扫,字典小、并发高,先出高危项;第二轮慢扫,字典大、稳扎稳打,查漏补缺。快扫能让你在几分钟内拿到最有价值的线索,慢扫则是把剩下来的边角料翻干净。这两个节奏搭配,用时不多,收益却最大。

第三个习惯是“自动化脚本辅助”。如果靶标环境允许,我会写一个简单的Python脚本,对扫描出来的每个文件自动下载并统计文件大小和文件头。因为很多敏感文件(比如.git目录里的对象文件、.env配置文件)不需要打开浏览器,直接下载到本地分析更快。自动化脚本让重复劳动变少,把精力集中在真正的分析上。

6.3 什么时候该收手:信息搜集的边界

这个问题容易被忽视,但值得说清楚。信息搜集不是越久越好,它有一个“边际收益递减”的问题。当你扫了四五个小时的目录、翻了几十页日志、跑了几轮子域名爆破之后,新产生的每一条信息对你解题的帮助会越来越少。这时候,与其继续漫无目的地扫,不如停下来问自己三个问题:

  • 目前收集到的信息里,有没有哪条是还没利用透的?
  • 构造一条从“已知入口”到“潜在敏感文件”的路径,是否还有缺口?
  • 如果我是题目作者,我会把下一个线索放在哪个“最意外”的地方?

答案往往在你已有的信息里,而不是下一个新扫出来的路径里。我个人的偏好是,信息搜集占总做题时间的三成左右,超过四成就说明效率下降了。这时候更应该做的事情,是回归已经收集到的信息,做一次重新整理,而不是继续扩展情报面。

信息搜集的核心永远是“知”而后“行”。把目标暴露在明面上的一切情报都翻个底朝天,然后再动手。这套方法看似粗笨,却是CTF里最稳的一条路,也是你从“碰运气选手”迈向“稳定拿分选手”的关键一步。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询