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
  
相关推荐
2601_96230047几秒前
基于Python与Tkinter的ADB Monkey自动化测试脚本开发
python·adb·tkinter·android测试·gui自动化
jimmyleeee8 分钟前
GEN AI安全:威胁全景---从训练到运行的攻防实战
人工智能·安全
SamChan9010 分钟前
PDF翻译后的格式完整性校验:用Python自动比对译文与原文档的表格与段落结构
开发语言·python·ai·pdf·机器翻译
2601_9620779811 分钟前
Python是一门什么样的语言?
python·编程语言·解释器·编译型·解释型
用户0190275816113 分钟前
不用 SDK 也能取 A 股数据:AlphaFeed REST API 用 cURL/HTTP 直连教程
python
DolphinScheduler社区16 分钟前
Apache DolphinScheduler 8 月报:权限安全加固,调度补火上线,性能与稳定性持续提升
大数据·安全·开源·apache·任务调度·海豚调度
君顾121 分钟前
外卖CPS系统开发实战指南:从架构设计到部署全流程解析
java·开发语言·外卖
旋生万物32 分钟前
素数都排在等角螺线上?用螺旋数论给黎曼猜想画一张“几何画像“(附Python)
python·ai编程·数论·黎曼猜想·素数分布
用户3721574261351 小时前
使用 Python 压缩 PDF 文件:减小图片、字体和文档内容体积
python