
简介Dirsearch-master 是基于Python开发的目录扫描工具面向渗透测试人员、安全初学者及Web开发者用于快速发现网站潜在的敏感目录和隐藏文件。工具支持HTTP、HTTPS与SOCKET等多协议扫描可自定义字典、多线程并发、递归探测子目录并实时显示扫描状态大幅提升目录枚举与漏洞排查效率。压缩包内含217个文件以py源码50个、pyc编译文件92个和txt字典/说明57个为主另有md文档、YAML配置、Dockerfile及HTML报告模板整体大小仅933KB结构清晰便于二次开发与部署。目前已有2188人学习适合希望系统掌握目录扫描原理、或需要直接用于安全测试脚本环境的读者。其中附带默认配置与报告模板可帮助快速上手并定制专属字典从而更精准地评估目标站点安全状况。1. 目录扫描工具 dirsearch-master安全巡检里绕不开的 Python 目录犁如果你负责的系统上过线大概率遇到过这种场景某次巡检拿到几十个待测地址想知道哪些路径暴露了不该暴露的后台入口、备份文件或临时调试页人工一个个点只能看到首页换个路径就漏掉。dirsearch 这类工具就是干这个的——它用 Python 写按字典逐个请求目标路径通过响应码判断路径是否存在几分钟就能把隐藏在根目录之外的资源从上千个 URL 里拎出来。这份源码包的意义不只是能跑而是它的字典分类、线程模型和输出格式都能直接嵌进你的巡检流程。适合做安全测试、后端运维和资产管理的开发者装好环境敲一条命令就能用想深挖也有足够的改造空间。2. 扫描器内侧的 socket 与并发请求是怎么被发出去的2.1 请求与响应的最小闭环socket 层发生了什么很多人以为目录扫描就是拿 HTTP 库发 GET 请求实际真正干活的是更底层的 socket 连接。dirsearch 基于 Python 标准库里的 socket 与 http.client 实现不需要额外安装所谓“socket 插件”——标准库本身就是最稳定的连接层组件。一次扫描请求的最小闭环是建立 TCP 连接 → 发送 HTTP 请求行和请求头 → 读取响应状态码 → 关闭连接这一步封装的参数就是命令行里的 --timeout 和 --retries。为了说清楚底层逻辑我写了一段最小实现的伪代码能让你直观看到请求路径时 socket 层做了什么import socket def fetch_status(host: str, path: str, timeout: float 7.5) - str: # 建立 TCP 连接timeout 是 socket 层的超时阈值 sock socket.create_connection((host, 80), timeouttimeout) # 手动拼 HTTP 请求行Connection: close 表示用后即断 req ( fGET {path} HTTP/1.1\r\n fHost: {host}\r\n User-Agent: Mozilla/5.0\r\n Connection: close\r\n\r\n ) sock.send(req.encode(utf-8)) # 只读取第一段响应就够状态码和 Location 头都在里面 resp sock.recv(4096).decode(iso-8859-1, errorsignore) status resp.split( )[1] if in resp else 000 sock.close() return status print(fetch_status(example.com, /admin))代码逻辑不复杂但几个细节值得抠一下create_connection 内部封装了 TCP 三次握手timeout 参数直接作用于 socket 阻塞读请求行里必须带 Host 头否则多数 Web 服务直接回 400recv(4096) 只读取第一段网络数据因为目录扫描只需要状态码和少数响应头不必等完整响应体。这段代码能跑但真实场景中大量连接会因目标半开、防火墙丢包而失败需要重试和超时收缩dirsearch 把这些逻辑收敛成了命令行参数你不用碰 socket 代码也能控制连接行为。2.2 并发模型从单线程到线程池的差异初版扫描器最常见的写法是顺序请求每个路径扫 5000 条字典要等十几分钟非常浪费。dirsearch 的做法是线程池并发维护一个任务队列每个路径作为一个任务丢给线程池Worker 线程从队列里取任务、发请求、收状态码、把结果写回公共列表。默认线程数是 25你可以用 -t 参数调整这正是它快的原因。线程数不是越大越好。每开一个线程扫描器就要维护一个独立的 socket 文件描述符线程数过高会让目标负载飙升也容易耗尽本机文件描述符。对常见场景我一般分三档本机或内网测试环境开 40~60公网目标开 15~30遇到带防护系统的目标直接降到 10 以下并配合 --delay 使用。配合线程模型的还有 Keep-Alive。有些版本默认使用短连接有些支持连接复用区别在于短连接每次请求都做一次完整的三次握手目标响应慢时大量时间耗在握手上连接复用能让一个 socket 连续发送多个请求显著降低延迟。这也是为什么同样线程数下dirsearch 在实际内网扫描里往往比纯短连接的脚本快一倍以上。2.3 同类工具横评为什么选 dirsearch 而不是其他目录扫描工具不少我整理过一张选型对照表重点看运行环境、字典生态和结果输出三项。工具运行环境字典生态结果格式适合场景dirsearchPython 3丰富按类型分类JSON/CSV/MD 等常规 Web 巡检、内网批量测试gobusterGo 单二进制依赖自己准备文本目标环境没有 Python 时应急ffufGo 单二进制灵活但需自配JSON 等FUZZ 模糊测试玩法更底层御剑Windows GUI内置精简字典界面展示单台机器快速手工排查dirsearch 的优势不在极致性能而在完整可用性开箱自带的字典覆盖常见 Web 框架和备份路径默认输出格式对后续处理友好参数设计贴近实际使用习惯。作为 Python 工具它二次开发门槛也低可以直接 import 核心模块或通过子进程调用这是它在我的工具集里长期占位的主要原因。3. 快速跑通一次真实扫描命令行参数与字典选择3.1 安装与目录结构拿到源码包第一步做什么先把下载的源码包解压到固定目录然后确认一下顶层结构。dirsearch-master 的核心内容包括入口脚本 dirsearch.py、存放字典的 db 目录、封装 HTTP 与导入逻辑的 lib 目录以及默认生成的 report 报告目录。简单看一遍目录能帮你理解后面所有参数的作用范围。unzip dirsearch-master.zip -d ~/tools/ cd ~/tools/dirsearch-master ls -la # 确认 Python 版本与依赖是否满足 python --version python dirsearch.py --version命令含义unzip 解压后进入工具根目录ls 查看入口文件是否存在python dirsearch.py --version 验证解析器和依赖是否正常。dirsearch 依赖 requests 和 urllib3 等常用库如果你跑类似 import 报错说明当前 Python 环境缺包用 pip install -r requirements.txt 一次补齐。我建议把这个目录固定放在 ~/tools/ 下后续写巡检脚本直接引用绝对路径避免每次重新解压。依赖安装这一步常被跳过遇到缺包报错才回头装。检查 requirements.txt 文件是否存在执行安装pip install -r requirements.txt # Windows 下如果系统同时有 py2 和 py3注意把 pip 指向 python3 python3 -m pip install -r requirements.txt无论用哪种方式装完务必再跑一次 --version 验证导入是否成功这一步能过滤掉大部分环境问题比扫描中途报错再排查省时间。3.2 基础命令拆解从 -u 到 -e 的完整扫描姿势扫一个目标的最少命令只需要指定 URL 和扩展名但实际使用远不止这些。先看最简化版本python dirsearch.py -u http://192.168.1.10 -e php,html,json-u 指定目标 URL-e 是扩展名字列表逗号分隔。这里的关键点是URL 要包含协议头扩展名不要带点。很多人习惯写 .php工具会拼成 /admin.php.php结果全是 404。再叠加实际巡检中常用的参数形成一条完整命令python dirsearch.py -u https://target.example.com \ -e php,jsp,json,env \ --random-agent \ --timeout 5 \ --delay 0.2 \ -x 403,404 \ -o report.json --format json逐项说--random-agent 从内置 UA 池里随机选一个 User-Agent避免默认 UA 被识别成扫描器--timeout 5 把 socket 超时调到 5 秒适合多数响应快的目标--delay 0.2 让每个请求间隔 0.2 秒属于轻量限速既不明显拖慢速度也能减少被防护系统标记的概率-x 403,404 把 403 和 404 从结果里排除只保留有价值的响应-o 与 --format 组合指定输出文件和格式。3.3 字典构成与扩展名逻辑扫描质量的第一道闸口扫描质量一半取决于字典。dirsearch 自带的 db 目录下不是单一字典而是按用途拆分common 类包含常规路径如 admin、login、backupsoftware 类针对常见中间件和框架的默认路径另有一些针对特定场景的专用字典。扫目标前先翻字典列表比盲目用超大字典更合理。常见做法是先用默认小字典快速摸底再从结果里判断技术栈换针对性字典做第二轮。比如某次扫描发现目标响应里带 JSP 特征我直接切到软件字典里针对 Tomcat 和 Spring 的路径列表很快找到了 actuator 和 swagger-ui。扩展名参数配合字典使用时要理解工具拼接逻辑字典里写的是路径前缀工具会把每个前缀依次加上你传入的扩展名组合。也就是说 -e php,json 实际产生 /admin.php 和 /admin.json 两组请求请求量是字典条数的 N 倍。所以我通常只加两到三个看家扩展名避免请求量翻倍后把目标或本机带宽打满。提示默认字典以路径为主很少带有查询串的完整 URL。如果目标路由是前端框架加 REWRITE 规则这类字典通常效果有限需要对字典做针对性设计这部分在第 4 章展开。4. 调优与控制用线程、超时和自定义字典稳定放大扫描效果4.1 自定义字典围绕备份文件与 API 路径做定制自带字典覆盖通用场景真正决定效率的是为目标量身定制的附加字典。我维护了一份固定补充列表包含备份文件、配置文件、调试接口和管理入口每次扫描都会带上# 自定义扩展字典片段路径不含协议头和扩展名 admin/ admin/console/ api/ api/v1/ api/v2/docs actuator/ actuator/health actuator/env .env .git/HEAD backup/ backup.zip config.php.bak db.sql phpinfo.php swagger-ui/ swagger-ui/index.html把这个列表存成 txt每行一个路径用 -w 指定路径加载python dirsearch.py -u http://target.example.com \ -w my_dict.txt \ -e php,bak,zip \ --random-agent -x 404这段字典设计的核心是覆盖“真实运维会留下但没人刻意清理”的东西备份文件、环境变量文件、代码仓库元数据和接口文档。路径命名按运维直觉写命中率往往很高。注意 my_dict.txt 必须是 UTF-8 编码Windows 记事本保存时选 UTF-8 而不是 ANSI否则扫描结果里会出现乱码。4.2 并发与超时调优线程数、延迟、重试怎么配并发参数不能照搬默认值要按目标网络状况调整。我总结的经验是先看目标响应速度再决定线程。如果目标首页在 1 秒内返回线程可以给 30如果响应要 3~5 秒线程越高越容易把连接堆在 TIME_WAIT 状态反而拖慢速度这时候更要加大 timeout 而不是线程数。一个可靠的起步配置python dirsearch.py -u http://target.example.com \ -t 20 \ --timeout 10 \ --retries 2 \ --random-agent \ --delay 0.1-t 20 在线程和安全之间取平衡--timeout 10 给慢速服务器留足响应时间--retries 2 允许对失败的请求做两次重试。参数之间是联动的timeout 太小会让正常请求被误杀重试次数增加反而放大了请求量timeout 太大又会让卡死连接长期占用线程槽位。目标端口和 HTTP 服务都正常但响应偏慢时timeout 给 10~15 秒是安全区间。4.3 输出与归档让结果能对接后续处理流程扫描结果不要只看终端要落盘。dirsearch 支持多种输出格式我固定使用 JSON原因很简单JSON 可以被后续脚本直接解析做去重、排序和统计比较方便。python dirsearch.py -u http://target.example.com \ -e php,json,zip \ -o report_20250110.json --format json输出之后我会用一个小脚本清洗数据按状态码分组并提取 URL 和响应长度import json with open(report_20250110.json, encodingutf-8) as f: data json.load(f) grouped {} for item in data.get(results, []): status str(item.get(status)) grouped.setdefault(status, []).append(item.get(url)) print(f[{status}] {item.get(url)} len{item.get(content-length)})这段脚本的用途是把结果从原始格式里抽出来形成一眼能看懂的状态码分组列表。过滤掉 404 和 403 后重点把目光放在 200、301、302 上200 代表路径真实存在301 可能是后台入口做了跳转302 要再看 Location 头判断是否指向登录页。只打印有效结果避免被几百条 404 刷屏。5. 避坑指南目录扫描最容易翻车的几个环节5.1 现象目标所有路径全部返回 403某次扫描测试目标首页打开完全正常但 dirsearch 扫任何路径都回 403连根路径都如此。原因往往在请求特征而不是路径上默认 UA 字符串包含扫描器特征目标安全设备直接拦截或目标对高频请求触发速率限制403 是人为拒绝。解决方法是伪装请求来源加 --random-agent 随机选 UA或直接用 -H 手动指定浏览器特征头python dirsearch.py -u http://target.example.com \ --random-agent \ -H Accept: text/html,application/xhtmlxml \ -H Referer: http://target.example.com/ \ -x 403这类问题在大厂安全网关和 CDN 防护场景下尤其常见。403 不一定代表路径不存在也可能是被策略拦了所以先确认是不是请求特征问题再决定要不要排除 403。5.2 现象扫描中途进度条不动socket 连接卡死线上目标扫描到一半进度停滞终端没有任何报错CPU 占用也不高。原因通常是目标半开连接或防火墙对非标准扫描行为做丢包处理导致大量 socket 处于 SYN_SENT 状态另一种可能是本机文件描述符被耗光线程池里的任务都在等 socket 释放。解决的顺序很重要。先降线程数并加超时限制再改系统层限制python dirsearch.py -u http://target.example.com \ -t 10 --timeout 8 --retries 1 # Linux 下临时调大文件描述符上限 ulimit -n 65535socket 卡死的另一个隐性原因是 DNS 解析超时目标域名用 CDN 或内部域名时解析耗时很长看起来像扫描卡住。排查时先用 curl -I 测一下目标响应如果 curl 正常而扫描卡住再逐项调 socket 参数别一上来就怀疑网络出口。5.3 现象浏览器能访问的页面扫描结果全是 404典型场景是目标用前端框架或伪静态规则浏览器访问 /user/123 显示正常内容但文件系统里根本没有 user 目录。dirsearch 发请求时是在问“这个路径是否对应可访问资源”而框架路由是接管所有请求后由应用层决定渲染什么状态码一贯返回 200 或 404取决于框架配置不取决于文件是否真实存在。解决方法是调整扫描策略别只盯着物理路径。目标转向接口和资源类型路径比如 /api/v1/user、/static/js/、/assets/或者用带查询串的接口路径配合少量参数测试。扫描动态路由目标时我会先用浏览器和代理流量抓一批真实访问过的路径把它们作为第二轮字典的输入这比固定字典可靠得多。5.4 现象JSON 报告里出现乱码和字段缺失Windows 终端下扫描结果正常打开 JSON 文件却发现路径字段有乱码或者某些字段直接缺失。原因分两层一是自定义字典保存成了 GBK 编码工具按 UTF-8 读取时解析失败二是个别请求没有正常返回状态码响应体为空导致对应字段没写入。解决时先转码再扫描# 转字典为 UTF-8 格式 iconv -f GBK -t UTF-8 my_dict.txt dict_utf8.txt python dirsearch.py -u http://target.example.com \ -w dict_utf8.txt \ -o report.json --format json还有一类乱码来自控制台输出而非报告文件。Windows 终端默认代码页是 GBKUTF-8 的中文路径会被显示成乱码但写入文件的内容是正确的养成扫完以后直接读文件的习惯不要依赖终端打印。检查乱码前先确认你打开报告用的编辑器是什么编码我常年用 UTF-8 打开极少再遇到这类问题。6. 把它改造成持续扫描工具定期巡检与结果验证让 dirsearch 发挥更大价值的方式是把它卷进一个自动化流程里而不是每次手动敲命令。我维护了一个简单的巡检脚本每周对一批资产跑一轮目录扫描自动命中文档并归档#!/bin/bash # 批量巡检从 targets.txt 读取目标逐轮扫描 mkdir -p reports while read -r target; do safe_name$(echo $target | md5sum | cut -d -f1) echo [] scanning $target python ~/tools/dirsearch-master/dirsearch.py \ -u $target \ -e php,json,zip,env \ --random-agent \ --timeout 8 \ -x 404,403 \ -o reports/${safe_name}.json --format json done targets.txt脚本逻辑是把目标列表逐行读入每个目标生成一个以哈希命名的 JSON 报告。有了批量报告以后我会加一个验证环节对每个报告的 200 响应做二次确认排除静态资源文件和登录跳转干扰。我的习惯做法是用一条 awk 或 Python 命令统计状态码分布如果某目标 200 数量异常多先看一下是不是所有路径都返回 200——那大概率是框架兜底页面不是真正暴露的目录。有一次我扫一个临时维护系统把一堆响应 200 的静态资源当成了后台入口写进报告审计同事复查时发现那些路径只是公共 CSS 和图片结论被打了回票。从那以后我每次扫完先跑一遍状态码分布统计确认 200 列表里没有静态资源后缀再做结论。这个验证动作已经成了固定习惯。整套流程跑下来字典、线程参数和输出格式都是可追溯的新接手的同事也能根据脚本和报告快速复现。工具源码包本身不复杂复杂的是把它放进你的工作上下文里持续打磨。希望帮到你。本文还有配套的精品资源点击获取