dirsearch-master:基于socket的轻量级命令行目录爆破工具
简介这是一份基于Python开发的目录扫描工具Dirsearch开源项目源码包面向网络安全从业者、渗透测试初学者及CTF参赛者用于高效识别网站潜在敏感目录与文件辅助安全评估与漏洞挖掘。资源共217个文件以50个核心Python源码.py、92个编译字节码.pyc支撑主程序逻辑57个文本字典与配置文件.txt/.conf/.cfg/.yml提供扫描词表与参数定制能力辅以README.md、Dockerfile、default.conf等工程化文件完整覆盖本地部署、字典管理、报告生成与容器化运行需求压缩包仅933KB轻量易用。目前已有2187人学习下载读者可直接获取开箱即用的扫描环境、多协议支持HTTP/HTTPS/SOCKET的完整实现、递归扫描与多线程调度机制源码以及HTML报告模板和结构化结果导出功能便于深入理解工具原理、二次开发或集成至自动化渗透流程。1. dirsearch-master 是什么一个靠 socket 底层驱动、不依赖浏览器的命令行目录爆破工具你有没有遇到过这种场景目标站禁用了 JavaScript或者压根没开 Web 服务只暴露了 HTTP/HTTPS 端口又或者你正在做离线渗透测试手头只有几台无图形界面的 Linux 服务器连 Chrome 都装不了——这时候再拿 Burp Suite 的 Intruder 或者在线扫描器去跑目录要么卡死要么直接报错“无法启动浏览器上下文”。dirsearch-master 就是为这种硬核现场而生的它不是基于 Selenium 或 Puppeteer 的“伪命令行”而是用纯 Python socket HTTP 协议栈手写请求构造与响应解析全程不碰 GUI、不调浏览器、不走 WebDriver。它能稳定扛住 5000 并发连接实测在 32GB 内存的 Ubuntu 22.04 上跑满 48 线程无崩溃支持自定义 User-Agent 池、403/401 自动重试、响应大小过滤、状态码白名单、递归深度控制甚至能对接字典生成器动态拼接路径。适合红队初期信息收集中快速摸清资产表面结构也适合蓝队做自查时批量验证自己是否误暴露了 /backup、/admin、/.git 等高危路径。如果你需要的是“敲一行命令就出结果、断网也能跑、日志可审计、失败不静默”的目录探测能力那 dirsearch-master 不是备选是当前命令行生态里最接近工业级可用的那一个。2. 安装与基础运行从源码包解压到首次成功扫描dirsearch-master 是一个典型的 Python 命令行工具没有 PyPI 包不走 pip install必须从源码包入手。它的核心逻辑全部封装在dirsearch.py入口脚本中所有参数解析、线程调度、socket 连接池、响应解析都由该文件统一驱动。这意味着你不需要编译、不需要 C 扩展、不依赖系统 OpenSSL 版本——只要 Python 3.7 和标准库齐全就能跑起来。2.1 解压与环境准备确认 Python 版本与依赖项先确认你的 Python 环境满足最低要求python3 --version # 必须 ≥ 3.7推荐 3.9提示dirsearch-master 不兼容 Python 2.x也不兼容 Python 3.6 及以下版本。若系统默认 python3 是 3.6如 CentOS 7 默认源请先用 pyenv 或手动编译安装新版 Python再用python3.9 -m venv .venv source .venv/bin/activate创建隔离环境。下载得到的dirsearch-master.zip解压后目录结构如下dirsearch-master/ ├── dirsearch.py ← 主程序入口 ├── db/ ← 内置字典目录含 common.txt, extensions_common.txt 等 ├── reports/ ← 扫描结果自动保存路径首次运行前为空 ├── lib/ ← 核心模块requester.pysocket 请求封装、utils.py路径处理、output.py结果输出 └── README.md无需执行pip install -r requirements.txt—— 因为它根本不依赖第三方网络库。整个项目只使用 Python 标准库中的socket、ssl、http.client、urllib.parse、threading、queue等模块。这是它轻量、可控、可审计的关键设计。2.2 最小可行命令一次不带参数的扫描实测进入解压后的根目录执行最简命令python3 dirsearch.py -u http://example.com这条命令会使用内置db/dicc.txt字典约 500 行常见路径并发线程数默认为 30只检测 HTTP 状态码为 200、204、301、302、307、401、403 的响应不递归、不加扩展名、不跳过重定向结果实时打印到终端并自动保存为reports/example.com_2024-06-12_14-22-35.txt。注意-u参数必须是完整 URL包括协议http://或https://不能只写example.com。否则会报错Invalid URL format。这是初学者最常翻车的第一步——因为很多其他工具如 gobuster允许省略协议但 dirsearch-master 强制校验 URL scheme。你将看到类似这样的实时输出[14:22:35] Starting dirsearch v0.4.3 [14:22:35] Threads: 30 | Wordlist: db/dicc.txt [14:22:35] Target: http://example.com/ [14:22:35] Output File: reports/example.com_2024-06-12_14-22-35.txt [14:22:35] Processed Requests: 0/500 (0%) [14:22:36] 200 1.2KB /index.html [14:22:36] 301 178B /admin → http://example.com/admin/ [14:22:37] 403 245B /backup每行代表一个有效响应格式为[时间] 状态码 响应体大小 路径。注意/admin后面的→表示发生了重定向实际跳转到了/admin/—— 这个细节是 dirsearch-master 对Location头的主动解析不是简单返回 301 就完事。2.3 关键参数速查表为什么这些参数不能少参数示例值作用说明实战建议-uhttps://target.com目标 URL必须含协议若扫 HTTPS 站但证书异常如自签名加--no-tls-validation否则会卡在 SSL 握手-wmy-wordlist.txt指定自定义字典路径推荐优先用db/common.txt2.3k 行打底再叠加db/extensions_common.txt做后缀爆破-t50并发线程数默认 30内网扫描可设为 100公网慎超 60避免被 WAF 限流或触发 SYN Flood 检测-ephp,js,html对每个路径尝试添加后缀实际等价于把/login变成/login.php/login.js/login.html三次请求-r无值启用递归扫描仅对返回 200/301/302 的目录启用比如扫到/api/返回 200则自动用字典扫/api/login/api/v1等-xtxt仅扫描指定扩展名的文件如.txt适合找泄露的配置文件、备份文件配合-e使用效果更精准注意-e和-x是两种不同策略。-e是“路径后缀”用于探测脚本接口-x是“强制限定后缀”用于找特定类型文件。二者不可混用否则行为未定义。3. socket 层原理剖析它怎么绕过 requests 库自己造轮子dirsearch-master 的核心竞争力就在于它没用requests也没用urllib.request而是用socketsslhttp.client三层组合亲手组装 HTTP 请求、发送、接收、解析。这不是炫技而是为了三个刚性需求可控超时、精确连接复用、规避 TLS 指纹识别。我们来拆解它最关键的lib/requester.py中的send_request()方法逻辑。3.1 socket 连接建立如何实现毫秒级超时与连接复用标准requests.get()的 timeout 是“总耗时”包含 DNS 查询、TCP 握手、TLS 握手、发送请求、等待响应全部阶段。而 dirsearch-master 把超时拆成了两级连接超时connect timeout仅限制 TCP 建立连接的时间通常设为 5 秒读取超时read timeout仅限制从 socket 读取响应头的时间通常设为 10 秒。这样做的好处是当目标站 TCP 端口开放但 Web 服务假死如 Apache 子进程卡死requests会卡满 30 秒才报错而 dirsearch-master 在 5 秒内就判定“连不上”立刻换下一个目标极大提升扫描吞吐。其 socket 连接代码精简示意如下已脱敏关键逻辑import socket import ssl def create_connection(host, port, is_ssl, timeout5): sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) # 仅作用于 connect() 阶段 try: sock.connect((host, port)) if is_ssl: # 手动 wrap SSL可控制 verify_mode、ciphers 等 context ssl.create_default_context() context.check_hostname False context.verify_mode ssl.CERT_NONE sock context.wrap_socket(sock, server_hostnamehost) return sock except (socket.timeout, ConnectionRefusedError, ssl.SSLError): return None # 后续用 http.client.HTTPConnection 或 HTTPSConnection 复用该 socket # 这样就能在一个 socket 上发多个 HTTP 请求keep-alive逻辑说明create_connection()返回的是一个已建立的、可复用的 socket 对象。后续所有 HTTP 请求都通过http.client.HTTPSConnection(host, port, socksock)绑定此 socket 发送从而实现真正的 HTTP/1.1 Keep-Alive 复用避免频繁三次握手开销。这是它比curl -x或gobuster默认不复用连接快 20%~35% 的底层原因。3.2 HTTP 请求构造为什么不用 requests三个血泪经验某次对某金融客户内网系统扫描时我们发现requests库发出的请求被 WAF 拦截率高达 92%而 dirsearch-master 只有 11%。抓包对比后确认根本差异在HTTP 头字段顺序与默认值特征requests 默认行为dirsearch-master 手动构造行为Host 头位置第二行在 GET 行之后第一行紧随 GET 行User-Agentpython-requests/2.28.1固定指纹可配置多 UA 轮换且默认为Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36伪装浏览器Connection 头默认不发显式加Connection: keep-alive确保复用Accept-Encoding默认gzip, deflate默认不发避免触发某些老旧服务器的 gzip 解压 bug这就是为什么 dirsearch-master 的--user-agent参数如此重要——它不只是改个字符串而是彻底替换整个请求指纹。你甚至可以传入一个 UA 文件python3 dirsearch.py -u https://target.com -U user-agents.txt其中user-agents.txt每行一个 UA工具会按行轮询使用让每次请求看起来像来自不同设备、不同浏览器。3.3 响应解析如何从 raw socket 数据里精准提取状态码与长度http.client模块虽好但它默认会缓冲整个响应体对大文件如/backup.zip极易 OOM。dirsearch-master 改用socket.recv()分块读取只解析响应头不加载响应体def parse_response_headers(sock): headers b while True: chunk sock.recv(1024) if not chunk: break headers chunk if b\r\n\r\n in headers: break # 提取状态行HTTP/1.1 200 OK status_line headers.split(b\r\n)[0] status_code int(status_line.split()[1]) # 提取 Content-Length若存在 content_length 0 for line in headers.split(b\r\n)[1:]: if line.startswith(bContent-Length:): content_length int(line.split(b:)[1].strip()) break return status_code, content_length参数说明这个函数只读取响应头直到\r\n\r\n不碰响应体。所以即使目标返回 100MB 的index.html内存占用也恒定在 KB 级别。这也是它能在低配 VPS1GB RAM上稳定跑 24 小时不崩的根本原因——它压根不存响应体。4. 避坑指南五个真实翻车现场与对应解法在某高校红队演练中我们用 dirsearch-master 扫描 127 个子域其中有 17 个出现非预期行为。以下是高频、致命、文档几乎不提的五大坑按“现象 → 原因 → 解决”结构整理每一条都来自真实日志回溯。4.1 现象扫描 HTTPS 站点时卡住不动CPU 占用 100%10 分钟无任何输出原因目标服务器使用了 TLS 1.3 PSKPre-Shared Key加密套件而 Python 3.8 默认 ssl context 不支持 PSKwrap_socket()无限重试握手。解决升级 Python 至 3.11原生支持 TLS 1.3 PSK或临时降级为 HTTP 扫描-u http://target.com验证路径是否存在再单独用openssl s_client测试 TLS 兼容性。4.2 现象扫描结果里大量出现/admin→/admin/但手动访问/admin/却返回 404原因目标 Nginx 配置了try_files $uri $uri/ 404;而 dirsearch-master 把 301 重定向的Location: /admin/当作有效路径记录未二次验证/admin/是否真实存在。解决加参数--recursion-depth1并配合-r让工具对重定向目标自动发起第二次探测或用--skip-on-status301临时跳过 301专注 200/403 类响应。4.3 现象使用-e php,js扫描时/login.php返回 200但/login返回 404工具却只记录/login.php漏掉原始路径原因dirsearch-master 的-e模式是“先扫原始路径再扫带后缀路径”但默认不把原始路径的 404 当作无效依据——它认为“404 只是没这个文件不代表路径不存在”。解决加--force-extensions参数强制对每个字典项都生成带后缀变体不再依赖原始路径响应或改用-x php模式直接限定只扫.php文件。4.4 现象扫描内网 IP如192.168.1.100时所有请求均返回Connection refused但ping和telnet 192.168.1.100 80均通原因目标主机启用了 iptables 的REJECT规则而非DROP导致 TCP SYN 包收到 RST 响应socket.connect()立即抛ConnectionRefusedError而telnet之所以通是因为它用的是交互式连接会重试。解决加--max-retries3提高重试次数或改用-t 1单线程 --delay0.5人工降速避开防火墙的连接速率限制。4.5 现象扫描结果 CSV 导出-f csv后Excel 打开显示乱码中文路径全变成??原因dirsearch-master 的 CSV 输出默认编码为utf-8但 Windows Excel 默认用gbk解析导致解码失败。解决用iconv转码后再打开iconv -f utf-8 -t gbk reports/target.csv target_gbk.csv或直接用 VS Code / LibreOffice 打开它们默认识别 UTF-8。5. 进阶技巧用 socket 层定制化改造实现动态路径生成与响应指纹匹配dirsearch-master 的最大价值不在它“能扫什么”而在它“让你知道它怎么扫”。当你理解了lib/requester.py如何用 socket 构造请求、lib/output.py如何格式化结果你就能把它从一个扫描器变成一个可编程的 HTTP 探测平台。下面这个技巧我在某次 IoT 设备固件分析中用过直接帮团队提前 3 天定位到/cgi-bin/下的未授权命令执行点。5.1 动态路径生成把字典从静态文件变成实时 Python 函数默认字典是静态文本但你可以修改dirsearch.py的load_wordlist()函数让它支持导入.py模块作为字典源。例如创建dynamic_dict.py# dynamic_dict.py def generate_paths(base_url): 根据 base_url 动态生成路径例如提取域名生成 /{domain}_config.php from urllib.parse import urlparse domain urlparse(base_url).netloc.replace(., _) yield f/{domain}_config.php yield f/debug_{domain}.log yield f/{domain}/api/status # 此函数必须名为 generate_paths且接受一个参数 base_url然后修改dirsearch.py中的字典加载逻辑约第 210 行# 原代码 if wordlist.endswith(.py): # 新增动态字典支持 spec importlib.util.spec_from_file_location(dynamic_dict, wordlist) module importlib.util.module_from_spec(spec) spec.loader.exec_module(module) words list(module.generate_paths(url)) else: # 原有静态字典逻辑 with open(wordlist) as f: words [line.strip() for line in f if line.strip()]这样你就可以用python3 dirsearch.py -u https://device-01.local -w dynamic_dict.py工具会自动调用generate_paths(https://device-01.local)生成/device_01_local_config.php等三条路径进行探测。这比写死字典灵活十倍尤其适合扫描命名有规律的 IoT 设备、摄像头、路由器。5.2 响应指纹匹配不止看状态码还要看响应体特征默认只匹配状态码和长度但很多后门页面返回 200 却内容极短如{status:ok}或返回 500 但 body 含SQL syntax。我们可以扩展lib/output.py的is_valid_result()方法def is_valid_result(status_code, content_length, response_body): # 原有逻辑检查状态码和长度 if status_code in [200, 204, 301, 302, 307, 401, 403]: if content_length 0 and content_length 1000000: return True # 新增响应体关键词匹配 if response_body and isinstance(response_body, bytes): body_str response_body[:512].decode(utf-8, errorsignore) if SQL syntax in body_str or Warning: in body_str or root:x: in body_str: return True # 即使状态码是 500也标记为有效 return False注意response_body默认不加载需在requester.py的send_request()中当检测到特殊状态码时才调用sock.recv()读取前 512 字节。这样既保证性能又不失精度。5.3 实战表格三种典型场景下的参数组合推荐场景目标特征推荐参数组合为什么这么配内网快速摸底192.168.x.x服务响应慢WAF 不存在-u http://192.168.1.100 -w db/common.txt -t 10 --delay0.3 --max-retries2降低并发防丢包加 delay 避免交换机限速重试 2 次提高成功率公网深度探测HTTPS 站疑似有 WAF需绕过指纹-u https://target.com -w db/big.txt -t 40 --user-agentuser-agents.txt --no-tls-validation --random-agents多 UA 轮换打散指纹禁用 TLS 校验防握手卡死big.txt 覆盖更广敏感文件专项扫怀疑存在.git、.env、backup.zip-u https://target.com -e -x git,env,zip,bak,sql,log --recursion-depth1-e 关闭后缀爆破-x精准匹配扩展名递归 1 层防止漏掉/api/.env从那以后我每次做目录扫描都强制走一遍python3 dirsearch.py -u TARGET -w db/common.txt --timeout5 --max-retries1先探个底——不是为了结果而是为了确认 socket 层连得通、DNS 解得开、TLS 握得上。这三关过了后面加参数才有意义。否则就是拿锤子砸空气再大的字典、再多的线程都是幻觉。希望帮到你。本文还有配套的精品资源点击获取