核心代码
python
import requests # 导入requests库,用于发送HTTP请求,比urllib更简洁易用
import argparse # 用于解析命令行参数
import threading # 导入线程模块,用于创建锁对象
from concurrent.futures import ThreadPoolExecutor # 导入线程池,用于管理多个线程并发执行
import time # 导入时间模块,用于获取当前时间
from urllib.parse import urljoin # 从urllib库导入urljoin函数,用于智能拼接URL
# 创建一个线程锁对象,用于在多线程环境中控制打印输出,避免多个线程同时打印造成混乱
print_lock = threading.Lock()
def dir_scan(url, path, user_agent):
"""
目录扫描函数:检查指定URL路径是否存在
参数:
url: 目标基础URL
path: 要测试的路径
user_agent: 用户代理字符串,用于伪装浏览器请求
功能:
使用HEAD请求检测路径是否存在,避免下载完整内容,提高扫描效率
"""
# 使用urljoin安全地拼接基础URL和相对路径
# urljoin能正确处理各种情况,如基础URL末尾是否有斜杠,路径是否有前导斜杠等
url = urljoin(url, path)
# 设置HTTP请求头,伪装成真实的浏览器访问
headers = {"User-Agent": user_agent}
try:
# 发送HEAD请求(只获取响应头,不下载响应体)
# allow_redirects=True表示自动跟随重定向
# timeout=5设置5秒超时,避免长时间等待无响应的服务器
response = requests.head(url, headers=headers, allow_redirects=True, timeout=5)
# 获取HTTP状态码
status_code = response.status_code
# 检查常见表示资源存在的状态码
# 200: OK,资源存在
# 301/302: 重定向,资源存在但被移动
# 401: 需要身份验证,资源存在
# 403: 禁止访问,资源存在但权限不足
if status_code in [200, 301, 302, 401, 403]:
# 使用线程锁确保打印操作的原子性,避免输出混乱
with print_lock:
print(f"[+] Found: {url},[status_code: {status_code}]")
except requests.exceptions.RequestException:
# 捕获所有requests库可能抛出的异常(如连接超时、DNS解析失败等)
# 使用pass忽略异常,继续尝试下一个路径
pass
def main():
"""
主函数:解析命令行参数并启动目录扫描
"""
# 创建命令行参数解析器
parser = argparse.ArgumentParser(description="DirScan")
# 添加必需的参数
parser.add_argument("-u", "--url", help="目标URL")
parser.add_argument("-w", "--wordlist", required=True, help="字典文件")
# 添加可选参数,默认值为5个线程
parser.add_argument("-t", "--threads", default=5, type=int, help="线程数")
# 解析命令行参数
args = parser.parse_args()
# 获取解析后的参数值
base_url = args.url
wordlist_path = args.wordlist
num_threads = args.threads
# 设置用户代理字符串,伪装成Chrome浏览器
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
# 打印扫描信息
print("-" * 60)
print(f"[*] Target URL: {base_url}")
print(f"[*] Wordlist: {wordlist_path}")
print(f"[*] Threads: {num_threads}")
print(f"[*] Start Time: {time.strftime('%Y-%m-%d %H:%M:%S')}")
print("-" * 60)
# 尝试读取字典文件
try:
with open(wordlist_path, "r", errors="ignore") as f:
# 读取文件所有行,去除空白字符,并过滤空行
paths = [line.strip() for line in f if line.strip()]
print(f"[+] Total paths: {len(paths)}")
except FileNotFoundError:
print(f"[-] Error: File '{wordlist_path}' not found.")
return
# 使用线程池并发执行目录扫描
# max_workers设置最大线程数
with ThreadPoolExecutor(max_workers=num_threads) as executor:
# 使用map方法将dir_scan函数应用到paths列表中的每个路径
# lambda函数用于传递额外的参数(base_url和user_agent)
executor.map(lambda path: dir_scan(base_url, path, user_agent), paths)
# 打印扫描完成信息
print("-" * 60)
print(f"[*] Finished at: {time.strftime('%Y-%m-%d %H:%M:%S')}")
print("scan complete")
print("-" * 60)
if __name__ == "__main__":
main()
requests库
用途: Python中最流行的HTTP客户端库,用于发送各种HTTP请求
特点: API简洁易用,功能强大,支持会话、cookies、文件上传等
常用方法:
- requests.get(): 发送GET请求
- requests.post(): 发送POST请求
- requests.head(): 发送HEAD请求(只获取响应头)
- requests.put(): 发送PUT请求
- requests.delete(): 发送DELETE请求
urllib库
用途: Python标准库中的URL处理模块
组成:
- urllib.request: 用于打开和读取URL
- urllib.parse: 用于解析URL
- urllib.error: 包含由urllib.request引发的异常
- urllib.robotparser: 用于解析robots.txt文件
特点: 是Python内置库,无需安装,但API相对复杂
urljoin函数
用途: 安全地拼接基础URL和相对路径
优势:
- 自动处理各种边界情况
- 正确处理基础URL末尾的斜杠
- 正确处理相对路径的前导斜杠
- 处理相对路径中的..和.符号
示例:
python
from urllib.parse import urljoin
# 各种情况都能正确处理
urljoin('http://example.com/base/', 'path') # -> http://example.com/base/path
urljoin('http://example.com/base', 'path') # -> http://example.com/path
urljoin('http://example.com/base/', '/path') # -> http://example.com/path