1. 为什么我建议你用 dirsearch 做目录扫描
先给不熟悉的读者解释一下“目录扫描”是干什么的。一个网站从外面看只有一个域名和一个主页,但服务器上往往还藏着很多没有在页面上公开的资源——比如后台登录入口、旧版本的备份文件、上传接口、配置出问题的.git目录、开发环境遗留的测试文件等等。这些资源如果被有心人捡到,可能就直接拿到系统权限了。
目录扫描做的事,本质上就是用“字典”去猜——把常见的目录名、文件名一个一个拼到目标 URL 后面,发起请求,根据服务器返回的状态码判断这个路径是否存在。这就是 wordlist 暴力枚举的思路,属于 Web 安全测试里最基础、也最容易出效果的一种手段。
dirsearch 是这类工具里我最常用的一个。它是开源项目,更新频率不错,字典库比较全,默认配置下就能跑出不少东西,而且支持多线程,速度不算慢。它还支持递归扫描、自定义扩展名、自动生成报告,这些功能在做渗透测试或者 Web 应用安全评估的时候都非常实用。
对你来说,如果你正准备入门 Web 安全,或者你是一名开发/运维想检查一下自己服务器上有没有不小心暴露的敏感目录,dirsearch 都是一个成本低、上手快、效果直接的工具。这篇主要讲 Windows 环境下的完整安装步骤,以及我在实际使用中踩过的那些坑和总结的参数调法。
2. Windows 安装前的准备和工具选型分析
2.1 为什么 Windows 上安装反而容易出幺蛾子
很多人觉得 Windows 装个 Python 工具很简单,其实不然。dirsearch 是 Python 写的命令行程序,依赖第三方库,Windows 上最容易出问题的几个点:Python 环境变量没配好、pip 源下载慢导致超时、终端编码格式不对导致中文路径乱码。这几个问题我在帮同事装的时候几乎每次都碰到,所以这篇文章把安装前后的细节都给你写全。
2.2 选 Git 克隆还是下载 ZIP 包
先说结论:我建议你用 Git 克隆,实在没有 Git 再下载 ZIP。原因有三个:
- 后续可以
git pull快速更新,而 dirsearch 的字典和规则确实会不定期更新,旧版本对新出的框架路径识别效果会有差距。 - Git 克隆得到的目录结构完整,不会出现 ZIP 解压后少文件、目录层级错乱的情况。
- 如果你以后想提交 issue 或者参与贡献,Git 环境早晚要有。
不过 ZIP 包有一个好处:不用先装 Git,适合临时环境。两条路我都给你写清楚。
3. 安装步骤全实录:从零开始跑通 dirsearch
3.1 环境检查:确认 Python 已经装好
dirsearch 当前版本要求 Python 3.7 以上。打开命令提示符(cmd),输入:
python --version如果显示类似Python 3.10.11这种,说明已安装。如果提示“不是内部或外部命令”,说明检查 Python 没装,或者装了但环境变量没配。装 Python 的时候要留意安装器第一个界面有一个“Add Python to PATH”的复选框,务必勾选,这是 Windows 上最容易忽略的一步。
如果你确实不想重装 Python,只想在当前用户下修复环境变量,手动加一下也行:打开“设置 → 系统 → 关于 → 高级系统设置 → 环境变量”,在用户变量 PATH 里加入 Python 安装目录和它的Scripts子目录,保存后重开 cmd 再验证。
3.2 方式一:Git 克隆安装(推荐)
首先确认 Git 是否可用:
git --version没有 Git 的话,去官网下载 Windows 版 Git,安装时全部默认选项就行。一路 Next,装完重开终端。
然后找一个干净的目录,例如C:\tools,执行:
cd C:\tools git clone https://github.com/maurosoria/dirsearch.git cd dirsearch此时目录里应该能看到dirsearch.py这个主文件。接着安装依赖:
pip install -r requirements.txt如果你的 Python 是 3.10 或更高版本,大概率直接就能装上。如果 pip 下载太慢,可以临时指定国内镜像源:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple这一步安装的依赖主要是requests、urllib3、certifi这些 HTTP 请求相关的库,dirsearch 本身没有特别重型的依赖,装起来非常快。
3.3 方式二:下载 ZIP 包安装
如果你没有 Git,也可以打开 GitHub 项目主页,点击绿色的“Code”按钮,选“Download ZIP”,解压到C:\tools\dirsearch。然后同样进入目录执行:
cd C:\tools\dirsearch pip install -r requirements.txt这种方式的缺点是之后每次更新都要重新下载解压,因为项目采用持续更新模式,新字典会定期补充,用 Git 会方便很多。
3.4 验证安装:跑通第一条命令
这一步非常关键,很多人在网上找了一堆教程,结果第一步就卡住了。进入项目目录后,执行:
python dirsearch.py --help如果能看到一大段参数说明,说明安装成功。如果提示ModuleNotFoundError: No module named 'requests',说明依赖没有装上,回到上面重新执行 pip 安装即可。
我用一个我惯用的“快速自检”命令,不仅能验证安装,还能顺便看工具是否正常工作:
python dirsearch.py -u http://testphp.vulnweb.com/ -t 5这里我拿的是一个公开的测试站点作为例子,响应正常的话几秒钟后你就能看到状态码列表。如果你不想扫描外部站点,也可以在你本机搭一个简单的 Apache 或者用python -m http.server 8080起一个临时服务来试。
3.5 一个小问题:Windows 终端的编码坑
装完之后运行,如果输出里出现明显的乱码,比如中文或者特殊字符显示成方块。这是因为 Windows 终端默认的编码格式和 Python 输出的 UTF-8 不匹配。在 cmd 里先执行:
chcp 65001把活动代码页切到 UTF-8,再运行 dirsearch,基本就能解决。如果你用的是 Windows Terminal 或者 PowerShell,一般没这个问题。
4. 核心参数与实际使用场景解析
这一节是全文重点中的重点。dirsearch 参数不算多,但每一个用好了都能让效率翻倍。我会从“开箱即用”到“精细调节”逐层展开,配合我实际测试时的经验讲。
4.1 基础命令:从最简单的开始
python dirsearch.py -u https://www.example.com这条命令会使用默认的字典db/dicc.txt(普通字典),默认线程数 25,默认扩展名空(即不追加任何扩展名)。跑起来以后,你会看到类似这样的输出:
[12:00:01] 200 - 12KB - /index.html [12:00:02] 301 - 0B - /admin -> /admin/ [12:00:03] 403 - 1KB - /server-status每一行由四部分组成:请求时间、状态码、响应大小、发现路径。如果 301 后面带箭头,说明服务器做了重定向,实际路径是箭头后面的那个,这种情况常见于目录重定向到带斜杠的路径。
实际心得:默认命令适合跑一个你完全不熟悉的目标,先摸个底。但不要满足于默认结果,下面这些参数是真正拉开差距的地方。
4.2 指定扩展名:让扫描结果更完整
Web 服务器上同一个路径可能对应多个文件,比如config.php、config.bak、config.zip。dirsearch 默认不留扩展名时,只检测原始路径,非常容易漏。
推荐这样用:
python dirsearch.py -u https://www.example.com -E php,html,bak,zip,txt-E是--extensions的简写,作用是除了原始路径外,还会追加这些扩展名再跑一遍。比如你原来的字典里有一条/config,那它还会尝试/config.php、/config.bak、/config.zip。这相当于把字典量扩大了N+1倍。
经验之谈:对于国内站点,我一般至少会加php,html,bak,txt。对于 Java 为主的站点,可以加jsp,do,action,json。再加上.git、.svn这类隐藏目录的检测,很多敏感文件就是这么扫出来的。
4.3 双字典组合:普通字典和暴力字典分开跑
dirsearch 默认携带的db目录里有很多字典,常见的有:
db/dicc.txt:通用普通字典,覆盖大量常见路径,速度适中。db/big.txt:超大字典,路径多,扫描耗时长,适合对重点目标做地毯式排查。db/backup.txt:专门找备份文件的字典。db/php.txt:针对 PHP 站点的路径字典。
日常使用我会分两轮:
第一轮用普通字典快速扫描,拿大方向:
python dirsearch.py -u https://www.example.com -w db/dicc.txt -E php,bak,txt -t 20第二轮用备份字典补充扫描,专门找漏网之鱼:
python dirsearch.py -u https://www.example.com -w db/backup.txt -E zip,tar.gz,rar,sql -t 104.4 线程数的调优策略
-t参数控制线程数,默认是 25。线程数不是越大越好,我实测下来的经验是:
- 本机或内网测试时可以开到 100,速度非常快。
- 外网目标建议控制在 10~30,线程太高容易被服务器接入层限速,反而会出现大量超时和假阴性(也就是路径其实存在,但因为请求被丢弃,导致漏报)。
- 遇到响应明显变慢或者大量超时的时候,降低线程数反而比硬扛更有效率。
实测记录:我曾经对外网一个中等规模站点用 25 线程跑完大约 60 秒,然后用 100 线程再跑,结果花了 3 分钟,因为大量请求超时重试。所以不要把线程数当成“性能越高越好”,要懂得观察服务器状态和输出进度。
4.5 排除状态码:过滤掉噪音
扫描结果里会出现大量 404、403 这样的“无效信息”。403 有时是有意义的(说明路径存在但禁止访问),但很多服务器对不存在的路径也统一返回 403,这时候就需要过滤。
常用过滤方式:
python dirsearch.py -u https://www.example.com -x 403,404-x参数会让这些状态码的结果直接不显示。我建议你不要一上来就把 403 排除,而是先跑一遍不带过滤的命令,观察一下目标服务器的响应模式。如果一个站点把不存在的路径全返回 403,那第二条命令再加-x 403会清爽很多。
还有一种情况是反代或 CDN 对不存在的路径返回 200 和一个统一的报错页面,这属于比较难缠的情况。dirsearch 允许通过--exclude-sizes排除特定响应大小的结果,另外也可以加-F或者把 200 结果里响应体的大小作为判断依据。不过这属于进阶玩法,后面我会单独讲。
4.6 递归扫描阴性结果后再深挖
默认 dirsearch 找到一个目录后不会继续往里跑,比如找到/admin/,不会自动扫/admin/upload/、/admin/config/。如果想把一个已知的目录内部结构摸清楚,用递归参数:
python dirsearch.py -u https://www.example.com --recursive -R 2-R指定递归深度,--recursive开启递归。这个功能在测试后台目录时特别有用。需要注意的是递归会显著拉长扫描时间,建议配合白名单指定只对某些路径递归,比如--recursive-status 200-299,只对响应成功的路径继续深挖。
4.7 结果保存与报告格式
扫描完成后,dirsearch 默认会在reports/目录下生成报告,格式有 plain、json、xml、html、csv 等。手动指定保存的方式是:
python dirsearch.py -u https://www.example.com --format=json -o report.jsonJSON 报告更适合后续脚本分析,HTML 适合阅读和归档。我个人的习惯是每次重要扫描都保存 JSON,然后用一个小脚本把结果按状态码分类汇总,方便复盘。
5. 完整实操演示:扫描一个测试站点并解读输出
这一节我拿一个我本地搭建的实验环境做演示。我用 PHP 写了一个简单的测试应用,在/backup、/admin/upload等路径上放了几个模拟文件,真实环境大家一定不要未授权扫描,最好在自己的靶机或者本地环境练习。
5.1 第一步:快速摸底扫描
python dirsearch.py -u http://127.0.0.1:8080 -E php,html,bak,txt -t 30我故意在字典路径之外保留了/backup和/admin,dirsearch 内置字典很容易就命中。跑了 40 多秒,输出类似这样:
[10:20:01] 200 - 15KB - /index.php [10:20:02] 302 - 0B - /admin/ -> /admin/login.php [10:20:03] 200 - 2KB - /backup/config.php.bak [10:20:04] 403 - 1KB - /server-status [10:20:07] 200 - 4KB - /docs/readme.txt注意看/backup/config.php.bak这一条。能扫出.bak文件是非常有价值的,因为这通常意味着源码或配置泄露。在这个模拟场景里,config.php.bak里确实放了一份数据库连接配置的备份,其中包含账号和密码的占位符。这就是目录扫描为什么重要的最好例子——你永远不会在主页上看到这些文件的链接,但它们确实就在那里。
5.2 第二步:针对敏感目录的递归扫描
发现/admin/存在后,我单独针对它做递归扫描:
python dirsearch.py -u http://127.0.0.1:8080 -E php,json -x 404 --recursive --recursive-status 200-399这里参数拆解一下:
-x 404:不显示 404,减少噪音。--recursive-status 200-399:只对返回成功的路径继续递归扫描,避免无谓深挖不存在的目录。-E php,json:PHP 应用加上这两种扩展名比较契合。
很快就跑出了/admin/upload/和/admin/logs/。这个结果改变了后续测试的方向——如果这是真实授权测试,上传功能往往是突破点,日志文件可能包含攻击痕迹或调试信息,都是高价值目标。
5.3 第三步:验证结果,不只看状态码
扫描结束不代表万事大吉。工具说 200 的路径,你要手动访问确认内容;工具说 403 的路径,有可能是真实存在但不允许访问,也有可能是 WAF 拦截。我遇到过一次情况是某路径返回 403,但用GET加一个特殊请求头后就变成了 200,这说明是边缘层的访问控制而不是真的不存在。
所以我的固定流程是:先扫,再打开浏览器逐个验证 200 和可疑的 403/302,重点看响应内容的大小、标题关键词、页面结构。响应大小可以作为重要判据,比如全是 12KB 的系统报错页,那基本都是不存在的路径被统一重定向了,可以放心忽略。
6. 报告的解读思路:从 200 到 403 都别忽略
很多人扫完就看一眼 200 的结果,觉得完事。实际上目录扫描最有价值的信息往往藏在混合状态码里:
- 200:路径存在且可访问,常规关注对象。
- 301/302:路径存在,发生了重定向,说明该路径后面可能还有内容,值得跟随重定向继续探测。
- 401/403:路径存在但禁止访问,有时候这是比 200 更有价值的线索,说明服务器对该路径做了访问控制,后面可能藏了重要内容。
- 500:路径存在但服务器崩溃了,可能是动态脚本回传了异常,也存在一定价值。
结合响应大小看,如果一批 404 结果响应大小全一样,那是正常现象;但如果某一条 404 的响应大小明显不同,比如多了一个版本号或者一串报错字符串,说明这条路径可能被真实处理了,值得单独验证。
我建议你把扫描结果按状态码分组,然后对每一个非 404 的状态码做一次手工确认。这种习惯比“跑完收工”要严谨得多,它能帮你发现很多工具上看起来“没有价值”的信号。
7. 常见问题与故障排查手册
7.1 安装环节的报错处理
| 报错信息 | 原因 | 解决方案 |
|---|---|---|
python 不是内部或外部命令 | Python 没安装或没加入 PATH | 重装并勾选 Add Python to PATH,或手动配置环境变量 |
No module named 'requests' | 依赖库未安装 | 执行pip install -r requirements.txt,建议同时指定国内镜像源 |
SSL: CERTIFICATE_VERIFY_FAILED | 证书验证失败 | 可以加-k参数跳过证书验证,仅限授权测试环境 |
UnicodeDecodeError | 字典或目标路径包含非 UTF-8 字符 | 在 cmd 中执行chcp 65001,或在读取自定义字典时先确认字典编码为 UTF-8 |
7.2 扫描过程中常见的几个问题
问题一:扫到一大半突然卡住不动了。
多数情况不是程序死了,而是目标服务器或者中间的防护设备把你的 IP 临时封禁,连接超时导致大量重试。先按Ctrl+C停止,把线程数调低再跑,或者等待解封后再继续。
问题二:全盘扫描全是 404,一个有效路径都没有。
这时候先检查目标是否真的活跃,直接在浏览器访问一下主页确认。如果确认目标没问题,那就是字典太小,换成big.txt试试,同时加上常见扩展名。另外检查一下是不是被 WAF 统一返回了 404——如果手动访问一个不存在的路径也返回 200,说明服务器对未匹配路径的兜底处理不一致,需要结合响应大小做过滤。
问题三:跑出来一堆 200,但手动访问全是同一个错误页。
这种属于“软404”现象,服务器不存在的路径统一返回 200 和报错页。解决办法是选一个肯定不存在的路径(比如/this_does_not_exist_12345),记录它的响应状态和大小,然后用--exclude-sizes排除这个大小。例如:
python dirsearch.py -u https://www.example.com --exclude-sizes=1089问题四:递归扫描时间太长。
限制递归深度、只对白名单路径递归,或者加--recursive-status条件,能大幅减少无效请求。
7.3 自定义字典的经验补充
dirsearch 自带的字典已经不错,但真实目标的情况千变万化,强烈建议你花时间积累自己的字典。我的习惯是这样的:
- 把每次有效扫描中发现的路径,去重后追加到一个长期维护的自定义字典里。
- 针对常见 CMS 系统(如 WordPress、Drupal、ThinkPHP)维护独立的路径字典。
- 字典行数不求多而求精,几百条高质量路径比几万条滥竽充数的东西效率高得多。
自定义字典的编码必须保存为 UTF-8,Windows 记事本默认的 ANSI 编码会让 dirsearch 读取乱码,这也是一个容易踩的坑。
8. 使用边界与合规提醒
写到这里,我必须认真强调一下使用边界。目录扫描是一种主动的路径探测行为,它会向目标服务器发起大量请求,这本身就是一种网络访问行为,任何未经授权的扫描都有法律风险。
只对自己有明确授权的目标进行测试,例如:
- 你自己搭建的网站或靶场。
- 你所在公司授予你测试权限的系统。
- 公开的、明确允许安全测试的平台。
如果你是在学习阶段,我强烈建议你在本地或实验环境里操作,搭建一个简单的 Web 应用,用自己的扫描器去探索它的目录结构,理解整个过程比急着“实战”有意义得多。
从实际经验来看,扫描能力只是安全测试链条里最前端的一环。真正有价值的是你基于扫描结果所作出的判断——哪些路径指向核心资产、哪些异常响应暗示着配置缺陷、哪些线索可以组合成一条完整的攻击链路。工具能帮你找到入口,但是否能安全、规范、有效地走下去,靠的是你的专业判断和经验积累。
保持对技术的敬畏,也保持对规则的遵守。在这条路上走得多远,取决于你有多扎实的基本功,而不是你掌握了多少“攻击手法”。
9. 最后分享一点我的个人体会
我自己的使用心得是:dirsearch 不应该作为一个“跑一次就完”的一次性工具,它在整个测试周期里可以反复出现。刚开始可以先快速摸底,拿到整体目录结构;发现敏感路径后,针对这些路径做深度的递归扫描;测到后期再回头用它单独验证某些特定类型的备份文件。每一轮的参数配置和结果侧重点都不一样,灵活调配比死记硬背参数重要得多。
如果你用的是 Windows,强烈建议把终端从自带的 cmd 换成 Windows Terminal 或者直接在 VS Code 里集成的终端来跑,编码支持好、输出可滚动、多标签方便对比多个扫描结果,整体体验会提升一大截。
一个小小的实用技巧作为结束:如果你经常在 Windows 上跑 dirsearch,可以写一个批处理脚本,把自己常用的参数组合和报告输出路径封装成一个命令,例如scan.bat your_target.com php json之类的格式。这样每次用的时候不用敲一长串参数,算是给自己的日常工作加一个顺手的小工具。
这个工具本身并不复杂,真正拉开差距的,是你对目标的理解深度和对结果的判断能力。希望这篇写下来的安装过程和使用心得,能让你少绕几次弯路。