Python安全开发之简易目录扫描器(含详细注释)

核心代码

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
  
相关推荐
qq_283720051 小时前
Qt QML 中为 CheckBox 设置鸿蒙字体(HarmonyOS Sans)——适配 Qt 5.6.x 与 Qt 5.12+
开发语言·qt·harmonyos
团子和二花1 小时前
openclaw平替之nanobot源码解析(七):Gateway与多渠道集成
python·gateway·agent·智能体·openclaw·nanobot
星幻元宇VR1 小时前
VR环保学习机|科技助力绿色教育新模式
大数据·科技·学习·安全·vr·虚拟现实
Be1k02 小时前
推荐一款语雀知识库批量导出工具
python·gui·工具·语雀·批量导出·原创
左左右右左右摇晃2 小时前
Java并发——死锁
java·开发语言·spring
小白橘颂2 小时前
【C语言】基础概念梳理(一)
c语言·开发语言·stm32·单片机·mcu·物联网·51单片机
沫离痕2 小时前
AI机器人客服-Dify接入
开发语言·javascript·ecmascript
Jianghong Jian2 小时前
Hashcat:强大的密码恢复与安全测试工具
测试工具·安全·密码学
半瓶榴莲奶^_^2 小时前
java模式
java·开发语言