ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

敏感目录泄露与目录扫描实战:从dirsearch到字典爆破的完整指南

敏感目录泄露与目录扫描实战:从dirsearch到字典爆破的完整指南 做安全评估这些年我最深的感受是很多看似固若金汤的系统最后突破口往往不是0day而是一个没人注意的备份文件。今天想和你认真聊聊我在实际项目中一直在用的目录扫描三件套dirsearch工具、字典爆破手段、以及如何从扫描结果里发现敏感目录泄露的蛛丝马迹。这篇文章不会只贴命令我会把为什么这样做、踩过哪些坑、扫描结果怎么看都摊开来说清楚。无论你是刚入门的安全爱好者还是需要做自查的运维/开发同学都能从中找到可以直接上手的东西。1. 敏感目录泄露被低估的Web安全盲区1.1 那个藏在备份文件里的数据库配置先说个真实经历。去年我参与一个授权范围内的安全评估项目目标站点的Web应用本身防护做得相当不错常规注入点、上传点都没有可利用的洞。就在大家准备收工的时候我在站点域名后面加了个/backup/然后跑了一轮目录扫描。结果在返回的200状态码列表里发现一个site_backup_202409.zip将近40MB。下载解压后里面除了源码还躺着一个config/database.php数据库地址、账号、密码全部明文。这个被忽视的备份文件直接让整个测试深度提升了一个级别。后来跟开发复盘时发现这个文件是运维同学在升级前随手打包放在web目录下的想着“临时放一下”结果一放就是大半年。说实话这类情况在真实环境里太常见了这也是为什么我一直坚持目录扫描不是可选步骤而是信息收集阶段必做的基础动作。1.2 敏感目录泄露的典型类型用一张表把常见泄露类型说清楚也好在扫描时有的放矢。类型常见文件名/路径风险等级备份压缩包.zip、.tar.gz、.bak、backup/、www.zip高可能包含源码和配置源码仓库残留.git/、.svn/、.hg/高可通过工具还原源码临时文件.swp、~结束的文件、.old、.temp中可能泄露编辑中的代码配置文件.env、config.php.bak、settings.py、web.config高直接泄露密钥/连接串日志文件access.log、error.log、runtime/log/中泄露访问记录、参数管理后台入口/admin、/manage、/login、/console中扩大攻击面测试脚本phpinfo.php、test.php、info.php、demo.php中泄露环境信息这些泄露的本质都是**“不该被web目录暴露的东西被放进了web根目录”**。目录扫描工具做的就是主动去探测这些“不该存在”的路径是否真的存在。1.3 目录扫描在安全评估流程里的位置很多刚接触安全测试的朋友会有个误区拿到目标就直接上漏扫扫完复制报告就完事。但漏扫和目录扫描解决的问题不一样。漏扫器会把重点放在已发现页面的参数、组件版本漏洞上而目录扫描做的是路径层面的发现它帮你把整个站点的“地图”画出来。很多漏扫器发现不了的问题——比如未公开的测试接口、遗留的备份包、隐藏的后台地址——恰恰是目录扫描最容易捞到的。所以我的习惯是先指纹识别再目录扫描最后再做针对性漏扫。顺序不能乱指纹决定了字典怎么选字典又决定了扫描结果的上限。2. dirsearch安装三连从报错到跑通的完整过程2.1 为什么一上来会遇到unable to locate package dirsearch很多朋友习惯用系统包管理器装工具第一反应就是sudo apt install dirsearch。在Kali上这一般没问题但对用Ubuntu、Debian或者自己服务器做测试的同学来说经常会在这一步看到一行红字unable to locate package dirsearch这里先解释清楚不是你的网络问题也不是工具不存在而是默认的软件源里没有收录dirsearch这个包。Debian系发行版的软件包收录有自己的节奏目录扫描这类安全工具未必都在官方源里。遇到这个报错有些人会去折腾apt源反而绕了远路。dirsearch的官方推荐方式本来就是从GitHub仓库运行没必要在包管理器这条路上死磕。2.2 最可靠的安装路径git clone pip 依赖我的标准做法是源码运行步骤不复杂顺手把依赖也装好。# 1. 确认 Python3 和 Git 已安装 python3 --version git --version # 2. 克隆 dirsearch 仓库 git clone https://github.com/maurosoria/dirsearch.git # 3. 进入目录并安装依赖 cd dirsearch pip3 install -r requirements.txt # 4. 验证能否运行 python3 dirsearch.py --version依赖这一层很多人会忽略。dirsearch依赖若干第三方Python库比如requests、certifi、colorama等。如果直接运行python3 dirsearch.py -h报错提示缺少某个Module就是requirements.txt没装好。用pip3 install -r requirements.txt一次性装完是最省事的。提示如果当前环境存在多个Python版本记得确认pip3对应的是你要用的那个Python3。否则可能出现“有requests但还是提示ImportError”的精分现场。装好之后跑一条最简单的命令做自检python3 dirsearch.py -u http://testphp.vulnweb.com -e php能正常扫出一个列表就说明环境没问题了。第一次跑的时候注意看终端的输出格式它会把状态码、响应大小、目标URL分颜色展示这套输出规则后续在筛结果时会反复用到。2.3 版本升级与工具目录管理从GitHub克隆的方式还有个好处升级方便。在仓库目录里执行git pull即可更新到最新版本。在真实项目中我通常会在自己的工具目录下建立一个tools/文件夹所有这类命令行走的工具都放在一起避免散落在各个临时目录里找不到。另外建议养成一个好习惯不要直接修改原工具目录下的默认字典把自定义字典单独放一个目录这样每次升级工具代码或者更新仓库时自己的字典资产不会被冲掉。3. 六个扫描参数决定目录扫描的最终质量3.1 基础组合-u、-w、-e先看一个最典型的用法python3 dirsearch.py -u https://target.com -w /path/to/dict.txt -e php,html,bak三个参数分别表示目标URL、字典文件、追加扩展名。这里重点说下-e。dirsearch扫描时会对字典里的每个路径尝试追加这些后缀。比如字典里有一条admin加上-e php,bak后工具会同时探测admin、admin.php、admin.bak三条路径。实际扫描时扩展名的选择要跟着站点技术栈走。如果指纹识别发现目标用PHP就带上php看到ASPX就带aspx看到Spring Boot多关注json、yml这类配置文件后缀。为了省时间我一般第一轮只带上最可能的1-2个后缀第二轮再追加其他后缀扫一遍。3.2 并发与速率的平衡-t 与 --delaypython3 dirsearch.py -u https://target.com -t 30 --delay0.5-t指定线程数--delay是每个请求之间的延迟时间。新手上来喜欢把线程拉到100觉得扫得快就完事了。但线程过高会带来两个现实问题目标服务器扛不住直接触发WAF把IP封掉导致后半段全部是误报或超时扫描本身会产生大量并发请求有可能对目标业务造成实际影响。在授权测试里这属于非常不专业的做法。我自己的经验是普通中小站点线程20-30足够目标较稳或者带宽有限降到10如果遇到WAF直接加--delay1甚至更大把请求频率降下来宁可扫慢一点也要保证扫描结果可信。目录扫描比的是结果质量不是耗时长短。3.3 递归扫描-r 和 --max-recursion-depthpython3 dirsearch.py -u https://target.com -r -R 2-r开启递归扫描当发现一个目录后会继续在这个目录内部跑一遍字典-R控制最大递归深度。举例子发现/admin/目录递归扫描会继续探测/admin/login.php、/admin/config.bak这类深层路径。但这个功能需要谨慎开启。递归会把扫描时间变成指数级增长而且很容易把深层目录里的噪音也扫出来。我的建议是第一轮全站扫描不开递归先拿浅层路径拿到结果后对感兴趣的目录单独用-r再扫一遍。比如python3 dirsearch.py -u https://target.com/admin/ -r -R 3 -w dict/special.txt这种“分层扫描”思路比一次性开启无限递归要高效得多。3.4 过滤噪声-x、--exclude-status 与响应大小限制python3 dirsearch.py -u https://target.com -x 403,404 -S-x用来排除指定状态码最常用的就是把403和404过滤掉。-S是简单输出模式让输出更简洁。真正高级的过滤是为了对付“软404”。很多框架不存在的路径也会返回200但响应大小基本固定。这类结果不排除会把整个扫描结果污染掉。dirsearch提供了两个很实用的参数--min-response-size500 --max-response-size10000设置响应大小范围后过小或过大的响应会被自动过滤大部分软404会被挡在外面。另外还有个--exclude-texts参数可以指定响应体里出现某些文本时视为无效比如python3 dirsearch.py -u https://target.com --exclude-textsPage Not Found,Resource Not Found这个参数在处理开发框架自带的404页面时特别有效。3.5 结果输出--format 和 -o扫描结果要及时落盘别指望终端翻屏。dirsearch支持多种输出格式python3 dirsearch.py -u https://target.com -o result.json --formatjson python3 dirsearch.py -u https://target.com -o result.txt --formatplain实际工作中我一般同时输出JSON和纯文本两份。JSON用来后期脚本处理纯文本用来快速人工翻阅。如果你有后续整理报告的需求JSON格式会友好很多——每个结果都包含URL、状态码、响应大小、重定向地址等结构化字段直接用脚本转成表格就行。4. 字典爆破的秘密为什么同一个工具有人跑得深有人跑得浅4.1 字典爆破的技术原理目录扫描器在工作时做的事情其实很朴素拿字典里的每一个路径拼接成URL向目标发送HTTP请求然后根据响应状态码和内容判断路径是否存在。所以它本质上就是一次基于字典的“爆破”——不是去突破什么认证而是爆破“路径”本身。这里有个容易被忽略的点状态码的判断逻辑。常见情况下200表示路径存在403表示存在但禁止访问301/302表示路径存在且发生了重定向。404表示不存在。这四种状态码基本够用了。但真实的Web环境远比这个复杂所以我会在下一章专门讲误判的问题。理解了这个原理你就会明白扫描结果的天花板完全取决于字典的质量。工具只是帮你发请求的字典才决定了你能看到多大范围的“地图”。4.2 常用字典资源与内置字典dirsearch自带的字典按场景做了分类在db/目录下字典文件适用场景dicc.txt通用中小型站点directories.txt目录型路径common.txt最常见路径速度快php.txtPHP站点专用backup.txt备份文件、临时文件admin.txt后台路径burp-parameter-names.txt参数名爆破外部资源里最出名的当属SecLists的Discovery/Web-Content目录里面有大量分类精细的字典比如raft-large-directories.txt、big.txt、Common-PHP-Filenames.txt等。我的建议是拿SecLists作为扩充弹药库日常还是以dirsearch自带字典为主因为它是经过脱敏和去噪的误报率控制得比较好。4.3 如何构建自己的行业字典与其满世界找“神级万能字典”不如花一个小时从目标本身提取路径规律。下面三个方法亲测有效。第一从站点的JS文件里收路径。打开开发工具把站点的所有JS文件过一遍API接口路径、管理端路径、静态资源路径都会暴露出来。把这些路径整理进字典再对目录扫描做补充效果远比通刷字典好。第二根据站点的技术栈生成定向路径。不同框架有固定的敏感文件习惯。比如ThinkPHP站点跑index.php、runtime/、.envSpring Boot站点关注actuator/、swagger-ui.html、application.ymlWordPress站点关注wp-json/、xmlrpc.php。这些路径在通用字典里不一定有但定向字典里命中率极高。第三按目标的信息做变体。如果你知道目标的子域名命名规律开发者的文件名习惯比如喜欢用拼音缩写、日期命名完全可以把这些内容批量生成进字典。比如某个站点接口习惯用/api/v1/getUserInfo这种命名那你就在字典里加入/api/、/api/v1/、/api/v2/这类前缀组合。这里补充一个我常用的“笨办法”用脚本把基础路径和后缀做笛卡尔积生成组合字典。比如一份基础路径清单有1000条想生成同时包含php、bak、old、zip的变体跑一小段Python就能完成。组合字典在第二轮补扫时很管用。4.4 与Burp Suite爆破字典的联动既然提到了Burp Suite就把这块也展开说说。在真实测试中dirsearch和Burp Suite经常是搭配使用的配合好了能形成112的效果。玩法一把dirsearch的结果作为Burp的Target。扫描结束后把确认存在的URL发送到Burp的Sitemap后续针对这些路径做请求修改、重放、参数探测比直接拿完整域名做测试要精准得多。玩法二把Burp抓包得到的路径反向整理成字典。用Burp代理浏览目标站点收集所有真实请求的URL、路径、参数名导出后整理成自定义字典再用dirsearch去跑一遍相同路径的变体。这种方式特别适合针对未公开的接口——真实请求里透露出路径规律后你可以推测出相邻、同规则的其他接口。玩法三用Burp Intruder做参数级爆破。dirsearch管的是路径发现Intruder管的是参数和值。比如通过目录扫描发现了一个/api/query接口接下来用Intruder加载burp-parameter-names.txt逐个测试可能存在的参数名。这两者不是替代关系而是先后关系。这里插一句关于“burpsuite爆破字典”的说明——很多朋友问到底用哪份字典。其实Burp Intruder对字典格式没有特殊要求一行一个payload即可。你可以把SecLists的相关字典直接加载也可以把dirsearch的burp-parameter-names.txt拿来用。不需要去下什么“专用秘传字典”理解了爆破目录、爆破参数各自的逻辑选字典就不会迷茫了。5. 扫描结果的鉴别逻辑200不一定真存在403不一定进不去5.1 状态码判断的再梳理很多新手拿到扫描结果看到一堆200就激动看到403就跳过。这种二元判断在真实环境里会漏掉大量有价值的信息。先看一个我常用的状态码快速判断表状态码通常含义我们该怎么做200路径存在可访问直接访问确认内容301/302存在重定向跟过去看目标地址可能是后台或登录页401/403存在但无权访问不要急着跳过尝试改请求头、用不同方法访问404不存在默认排除500服务器错误可能是存在但代码报错值得看一眼429请求频率过高说明扫太快了停一停特别想说一下403。很多人看到403就认为“进不去没价值”但很多时候403只是服务器层面拦截了目录列表访问不代表目录里的文件不能直接访问。比如/uploads/可能403但/uploads/xxx.jpg是开放的。我一个朋友的项目里目标站点/.svn/返回403结果直接访问/.svn/wc.db却能下载因为那条规则只拦了目录没拦文件。对每个403我推荐花十秒钟手动请求一次验证后再划掉。5.2 软404最容易被忽视的假阳性软404的本质是所有不存在的路径目标都会返回200但响应内容是同一个“页面不存在”的提示页。如果扫描时不去过滤你会看到几百条200以为找到了大量敏感路径点开全是同一个模板。识别软404有几个常用办法看响应大小。如果一大批200结果的响应大小都接近比如都在3000字节左右这大概率是同一个软404页面看页面标题。把所有200结果的标题抓出来统计如果高度重复就是软404看关键词。比如经过统一处理的404提示页通常包含“Page Not Found”“数据不存在”这类固定文本。dirsearch本身提供了一些规避机制但最稳妥的还是将确认存在的路径手动请求一遍。我见过不少人拿了一堆软404的结果去写报告被开发同事嘲笑了很久。目录扫描最忌讳的就是不加判断地粘贴结果。5.3 找到敏感目录后的进一步验证扫描只是第一步确认结果才是体现功力的地方。我的验证流程是固定的直接请求看状态码和响应体确认不是软404关注重定向目标因为有些路径本身没内容但会跳到后台登录页检查备份文件是否可下载如果可下载下载后注意不要随意解压执行里面的内容避免触发安全告警记录证据把URL、状态码、响应头、关键内容截个图或者用curl保存响应到本地。立即纳入报告我会在测试过程中维护一个“有效资产”表格每个确认结果填一行URL、类型、风险描述、复现方式。这套流程走完才算真正把目录扫描结果的价值挖出来了。6. 一次授权测试全流程复盘从指纹识别到报告落地的细节6.1 授权确认与范围界定每次测试开始前我最先做的不是开工具而是确认两件事目标范围是否书面授权授权书里是否写明了域名/IP段和时间窗口。目录扫描会产生大量请求如果没有提前跟目标确认清楚很容易被认为是恶意扫描测试性质就变味了。所以授权确认是所有后续步骤的前提这一步省不得。6.2 从指纹识别到扫描策略调整假设这次测试的是一个中型企业门户网站。先用浏览器访问看响应头里的Server、X-Powered-By再查看页面源码里的框架特征确认是NginxPHP站点疑似ThinkPHP框架。这时候扫描策略就很清晰了python3 dirsearch.py -u http://target.com -e php,json,yml -t 20 \ -w db/dicc.txt --formatjson -o phase1.json第一轮用常规字典快速摸底排除403/404。拿到结果后对关注的路径做第二轮递归python3 dirsearch.py -u http://target.com/admin/ -r -R 2 \ -e php,bak,zip -t 15 -x 403,404同时在另一个方向用专门沉淀的ThinkPHP路径清单补一轮。这套组合拳打下来基本能把站点的主要暴露面摸全。6.3 结果复核与报告编写扫描阶段结束后把JSON结果导入本地Excel/脚本做排序和过滤重点是看200状态的条目逐个手工验证。拿真实项目来说最后筛出的有效条目通常只占原始结果的一成左右包括/runtime/目录可列举内含日志文件/.env泄露数据库连接信息/backup/portal_2023.sql数据库备份文件可下载/admin/login.php后台地址确认存在登录页面可正常访问。每一条我都做了复现验证截图保存再写进报告。报告里不只是罗列URL还写清“该路径目前可访问建议限制访问权限/迁移备份文件/清理测试残留”方便开发直接照着修。6.4 扫描工具的边界与个人体会dirsearch虽然好用但它终究只是一个“发请求的机器”。工具替代不了人的判断以下几点是我反复踩坑后总结的不要迷信默认字典。不同行业、不同框架的站点敏感路径差异很大通用字典保障的是下限自建字典才能抬高上限。时刻关注测试目标的状态。扫描过程中偶尔用浏览器打开目标首页确认站点响应正常。如果目标业务受到明显影响立即调低线程或者暂停。保留完整的请求日志。目录扫描是主动探测行为留下日志既是专业的体现也是为了后续复查方便。记录下每一次扫描的时间、字典、参数。这样发现某个路径时能知道它是哪轮扫描发现的、是什么上下文。没有上下文的结果价值会大打折扣。7. 防御视角从攻击者的扫描反推自己的加固清单7.1 如果暴露面已经出来了怎么快速止血目录扫描这项技术本质上没有正邪之分关键在于使用的人。防御方完全可以用同样的工具来审视自己的Web应用。定期用dirsearch对自家站点跑一轮把扫描出来的敏感文件当成一次“预演”就能在真实入侵发生前堵住漏洞。止血操作可以按下面这个顺序来删除web目录下的备份包、测试脚本、临时文件——这是最高优先级成本最低治疗最彻底禁止web服务器解析/下载特定扩展名文件比如.sql、.bak、.env、.git等在Nginx/Apache配置里直接deny掉对后台路径增加访问控制不能只靠“路径足够隐蔽”IP白名单或内网访问是底线定期扫描并建立基线每次版本发布后跑一次目录扫描对比新增路径及时发现残留文件。7.2 关于敏感目录泄露的认知升级很多开发同学觉得“文件放在深处就没人知道”这种想法往往就是泄露的源头。目录扫描工具的存在恰恰证明了一件事只要路径可被HTTP访问就一定会被探测到。因此真正有效的方法不是把敏感文件藏起来而是让它根本无法通过web访问——比如放到web根目录之外或者配置访问鉴权。实践中凡是做了这两点的站点即使目录扫描跑得再猛敏感目录泄露的风险也能大幅降低。技术对抗的终极形态永远是安全意识的对齐。最后再分享一个我常用的收尾动作每次跑完目录扫描我会把确认的有效路径汇总整理成一份“敏感路径清单”既作为交付报告的一部分也会在下次测试相同目标时作为参考。这份清单会记录时间、URL、状态码、当时的修复建议。时间长了它就成了一个非常有价值的历史对比库——哪个路径曾经泄露过、是否修干净了、是否又回潮了一眼就能看出端倪。目录扫描的意义从来不止于发现而是持续发现、持续收敛。这就是我一直坚持用它的原因。
返回列表