diff --git a/README.md b/README.md index 440e107..69b40f0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,241 @@ -# XSS_Scanner -这是一个全面的Web应用安全扫描工具,专注于检测XSS(跨站脚本)漏洞,同时也能够发现其他类型的Web安全漏洞。该工具支持多种扫描模式、不同级别的有效载荷和详细的漏洞报告。 +# 深度XSS漏洞扫描器 + +这是一个全面的Web应用安全扫描工具,专注于检测XSS(跨站脚本)漏洞,同时也能够发现其他类型的Web安全漏洞。该工具支持多种扫描模式、不同级别的有效载荷和详细的漏洞报告。 + +## 功能特点 + +- **多种漏洞检测**: + - XSS(反射型、存储型、DOM型) + - CSRF(跨站请求伪造) + - SQL注入 + - LFI(本地文件包含) + - RFI(远程文件包含) + - SSRF(服务器端请求伪造) + - XXE(XML外部实体注入) + +- **全面的扫描能力**: + - 网站爬虫功能,自动发现可测试的URL + - 表单和参数自动检测 + - 支持DOM分析 + - 支持不同测试级别(快速、标准、深度) + - 支持多线程扫描 + +- **网页技术识别**: + - 自动识别目标网站使用的编程语言(PHP、ASP.NET、Java、Python等) + - 检测前端框架(React、Vue、Angular、jQuery等) + - 识别Web服务器类型(Apache、Nginx、IIS等) + - 识别CMS系统(WordPress、Joomla、Drupal等) + - 框架版本指纹识别 + +- **高级WAF绕过功能**: + - 自动检测目标是否启用Web应用防火墙(WAF) + - 识别WAF类型(如Cloudflare、ModSecurity、AWS WAF等) + - 自动调整有效载荷以绕过WAF检测 + - 多种绕过技术(编码变异、分段注入、定时执行等) + - 自适应绕过策略,根据WAF反应调整攻击向量 + +- **高级功能**: + - 有效载荷自动绕过WAF + - 支持自定义有效载荷 + - 基于浏览器的漏洞验证 + - 支持漏洞利用 + - 支持代理和认证 + +- **详细报告**: + - 多种报告格式(HTML、JSON、XML、TXT) + - 详细的漏洞信息和修复建议 + - 风险评级 + - 网站技术栈分析报告 + +## 安装 + +### 要求 +- Python 3.7+ +- Chrome浏览器(如需浏览器测试) + +### 安装步骤 + +1. 克隆仓库: +```bash +git clone https://github.com/yourusername/xss-scanner.git +cd xss-scanner +``` + +2. 安装依赖: +```bash +pip install -r requirements.txt +``` + +3. 安装ChromeDriver(如需浏览器测试): +```bash +# Windows使用以下命令: +pip install webdriver-manager + +# Linux可能需要安装Chrome: +# sudo apt-get install google-chrome-stable +``` + +## 使用方法 + +### 基本用法 + +```bash +python main.py -u https://example.com +``` + +### 更多示例 + +**扫描单个URL**: +```bash +python main.py -u https://example.com +``` + +**扫描多个URL**: +```bash +python main.py -f targets.txt +``` + +**深度扫描**: +```bash +python main.py -u https://example.com --scan-level 3 +``` + +**只扫描XSS漏洞**: +```bash +python main.py -u https://example.com --scan-type xss +``` + +**使用浏览器进行DOM XSS检测**: +```bash +python main.py -u https://example.com --browser +``` + +**利用发现的漏洞**: +```bash +python main.py -u https://example.com --exploit +``` + +**生成HTML报告**: +```bash +python main.py -u https://example.com -o report.html --format html +``` + +**使用代理**: +```bash +python main.py -u https://example.com --proxy http://127.0.0.1:8080 +``` + +### 命令行参数 + +``` +必选参数: + -u, --url URL 目标URL + -f, --file FILE 包含目标URL的文件 + +可选参数: + -d, --depth DEPTH 爬虫深度 (默认: 2) + -t, --threads THREADS 线程数 (默认: 5) + --timeout TIMEOUT 请求超时时间 (默认: 10秒) + --user-agent USER_AGENT 自定义User-Agent + --cookie COOKIE 请求Cookie + --headers HEADERS 自定义HTTP头 + --proxy PROXY HTTP代理 + --scan-level {1,2,3} 扫描级别: 1-快速, 2-标准, 3-深度 (默认: 2) + --scan-type {all,xss,csrf,sqli,lfi,rfi,ssrf,xxe} + 扫描类型 (默认: all) + --payload-level {1,2,3} Payload复杂度: 1-基础, 2-标准, 3-高级 (默认: 2) + -o, --output OUTPUT 输出报告文件 + --format {txt,html,json,xml} + 报告格式 (默认: html) + -v, --verbose 显示详细输出 + --no-color 禁用彩色输出 + +高级选项: + --browser 使用真实浏览器进行扫描 + --exploit 尝试利用发现的漏洞 + --custom-payloads FILE 自定义Payload文件 + --exclude REGEX 排除URL模式 (正则表达式) + --include REGEX 仅包含URL模式 (正则表达式) + --auth USER:PASS 基本认证 +``` + +## XSS漏洞案例 + +扫描器能够检测以下XSS攻击场景: + +1. **网页留言板获取cookie**:检测表单提交中的XSS漏洞,可能导致cookie泄露 +2. **CMS管理后台伪造钓鱼网站**:检测URL参数中的XSS漏洞,可能用于伪造管理界面 +3. **图片处XSS攻击**:检测图片参数和属性中的XSS漏洞 +4. **SVG-XSS**:检测SVG文件中的XML注入和XSS漏洞 +5. **PDF-XSS**:检测PDF参数中的XSS漏洞 +6. **浏览器翻译-XSS**:检测浏览器翻译功能中的XSS漏洞 +7. **Flash-XSS**:检测Flash参数中的XSS漏洞 +8. **XSS配合MSf钓鱼**:检测可能用于钓鱼的XSS漏洞 +9. **XSS漏洞配合CSRF漏洞**:检测可能与CSRF组合的XSS漏洞 +10. **XSS漏洞配合越权漏洞**:检测可能导致权限提升的XSS漏洞 + +## 进阶用法 + +### 自定义有效载荷 + +创建一个文本文件,每行包含一个XSS有效载荷,然后使用`--custom-payloads`参数: + +```bash +python main.py -u https://example.com --custom-payloads my_payloads.txt +``` + +### 漏洞利用 + +使用`--exploit`参数启用漏洞利用功能: + +```bash +python main.py -u https://example.com --exploit +``` + +当发现漏洞时,扫描器将尝试进一步利用该漏洞,例如: +- XSS漏洞:尝试窃取cookie或会话信息 +- SQL注入:尝试提取数据库信息 +- 文件包含:尝试读取敏感文件 + +### 限制扫描范围 + +使用正则表达式包含或排除特定URL: + +```bash +# 只扫描/admin/路径下的URL +python main.py -u https://example.com --include "^https://example.com/admin/.*" + +# 排除静态资源 +python main.py -u https://example.com --exclude "\.(jpg|css|js|png|gif)$" +``` + +## 安全和免责声明 + +此工具仅供安全研究和授权渗透测试使用。未经明确许可,对系统进行扫描可能违反法律。使用者需要: + +1. 只在自己拥有的系统上或获得明确授权的系统上使用 +2. 了解并遵守当地的网络安全法律和规定 +3. 负责任地披露发现的安全漏洞 + +## 贡献 + +欢迎贡献代码、报告bug或提出功能建议。请通过以下方式参与: + +1. Fork仓库 +2. 创建功能分支 (`git checkout -b feature/amazing-feature`) +3. 提交更改 (`git commit -m 'Add some amazing feature'`) +4. 推送到分支 (`git push origin feature/amazing-feature`) +5. 创建Pull Request + +## 许可证 + +本项目采用MIT许可证 - 详情请查看[LICENSE](LICENSE)文件。 + +## 联系方式 + +- 项目链接: [https://github.com/yourusername/xss-scanner](https://github.com/yourusername/xss-scanner) +- 联系邮箱: [1013199991@qq.com](1013199991@qq.com) + +--- + +**注意**:此工具是为安全专业人员设计的,使用前请确保遵守所有适用的法律和法规。 \ No newline at end of file diff --git a/xss_scanner.py b/xss_scanner.py new file mode 100644 index 0000000..a07c48e --- /dev/null +++ b/xss_scanner.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +XSS深度漏洞扫描器 - 主入口脚本 +""" + +import os +import sys + +# 添加当前目录到Python路径 +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +# 导入主模块 +from xss_scanner.main import main + +if __name__ == "__main__": + # 调用主函数 + main() \ No newline at end of file diff --git a/xss_scanner/__init__.py b/xss_scanner/__init__.py new file mode 100644 index 0000000..c060e15 --- /dev/null +++ b/xss_scanner/__init__.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +XSS深度漏洞扫描器 - 包初始化 +""" + +__version__ = '1.0.0' +__author__ = '高级渗透工程师' +__description__ = '一个全面的Web应用安全扫描工具,专注于检测XSS漏洞,同时也能够发现其他类型的Web安全漏洞。' \ No newline at end of file diff --git a/xss_scanner/__pycache__/__init__.cpython-313.pyc b/xss_scanner/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..0890bf8 Binary files /dev/null and b/xss_scanner/__pycache__/__init__.cpython-313.pyc differ diff --git a/xss_scanner/__pycache__/main.cpython-313.pyc b/xss_scanner/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..996fc90 Binary files /dev/null and b/xss_scanner/__pycache__/main.cpython-313.pyc differ diff --git a/xss_scanner/core/__init__.py b/xss_scanner/core/__init__.py new file mode 100644 index 0000000..7c9de28 --- /dev/null +++ b/xss_scanner/core/__init__.py @@ -0,0 +1 @@ +"""XSS扫描器 - 核心包""" \ No newline at end of file diff --git a/xss_scanner/core/__pycache__/__init__.cpython-313.pyc b/xss_scanner/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..4bb5f77 Binary files /dev/null and b/xss_scanner/core/__pycache__/__init__.cpython-313.pyc differ diff --git a/xss_scanner/core/__pycache__/config.cpython-313.pyc b/xss_scanner/core/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000..534e84c Binary files /dev/null and b/xss_scanner/core/__pycache__/config.cpython-313.pyc differ diff --git a/xss_scanner/core/__pycache__/logger.cpython-313.pyc b/xss_scanner/core/__pycache__/logger.cpython-313.pyc new file mode 100644 index 0000000..429047f Binary files /dev/null and b/xss_scanner/core/__pycache__/logger.cpython-313.pyc differ diff --git a/xss_scanner/core/__pycache__/scanner_engine.cpython-313.pyc b/xss_scanner/core/__pycache__/scanner_engine.cpython-313.pyc new file mode 100644 index 0000000..a7e930f Binary files /dev/null and b/xss_scanner/core/__pycache__/scanner_engine.cpython-313.pyc differ diff --git a/xss_scanner/core/config.py b/xss_scanner/core/config.py new file mode 100644 index 0000000..7981899 --- /dev/null +++ b/xss_scanner/core/config.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +配置模块,负责管理扫描器的配置参数 +""" + +import os +import json +import logging +from urllib.parse import urlparse + +logger = logging.getLogger('xss_scanner') + +class Config: + """配置类,管理扫描器的所有配置选项""" + + def __init__(self): + """初始化默认配置""" + # 常规选项 + self.url = None + self.depth = 2 + self.threads = 5 + self.timeout = 10 + self.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" + self.cookies = {} + self.headers = {} + self.proxy = None + self.scan_level = 2 + self.scan_type = 'all' + self.payload_level = 2 + self.output_file = None + self.output_format = 'html' + self.verbose = False + self.no_color = False + + # 高级选项 + self.use_browser = False + self.exploit = False + self.custom_payloads = None + self.exclude_pattern = None + self.include_pattern = None + self.auth = None + + # 内部使用 + self.base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + self.payloads_dir = os.path.join(self.base_dir, 'payloads') + + def load_from_args(self, args): + """ + 从命令行参数加载配置 + + Args: + args: 解析后的命令行参数 + """ + # 常规选项 + if args.url: + self.url = args.url + + if args.depth: + self.depth = args.depth + + if args.threads: + self.threads = args.threads + + if args.timeout: + self.timeout = args.timeout + + if args.user_agent: + self.user_agent = args.user_agent + + if args.cookie: + self._parse_cookies(args.cookie) + + if args.headers: + self._parse_headers(args.headers) + + if args.proxy: + self.proxy = args.proxy + + if args.scan_level: + self.scan_level = args.scan_level + + if args.scan_type: + self.scan_type = args.scan_type + + if args.payload_level: + self.payload_level = args.payload_level + + if args.output: + self.output_file = args.output + + if args.format: + self.output_format = args.format + + self.verbose = args.verbose + self.no_color = args.no_color + + # 高级选项 + self.use_browser = args.browser if hasattr(args, 'browser') else False + self.exploit = args.exploit if hasattr(args, 'exploit') else False + + if hasattr(args, 'custom_payloads') and args.custom_payloads: + self.custom_payloads = args.custom_payloads + + if hasattr(args, 'exclude') and args.exclude: + self.exclude_pattern = args.exclude + + if hasattr(args, 'include') and args.include: + self.include_pattern = args.include + + if hasattr(args, 'auth') and args.auth: + self._parse_auth(args.auth) + + def load_from_file(self, config_file): + """ + 从配置文件加载配置 + + Args: + config_file: 配置文件路径 + """ + if not os.path.exists(config_file): + logger.error(f"配置文件不存在: {config_file}") + return False + + try: + with open(config_file, 'r') as f: + config_data = json.load(f) + + # 常规选项 + if 'url' in config_data: + self.url = config_data['url'] + + if 'depth' in config_data: + self.depth = config_data['depth'] + + if 'threads' in config_data: + self.threads = config_data['threads'] + + if 'timeout' in config_data: + self.timeout = config_data['timeout'] + + if 'user_agent' in config_data: + self.user_agent = config_data['user_agent'] + + if 'cookies' in config_data: + self.cookies = config_data['cookies'] + + if 'headers' in config_data: + self.headers = config_data['headers'] + + if 'proxy' in config_data: + self.proxy = config_data['proxy'] + + if 'scan_level' in config_data: + self.scan_level = config_data['scan_level'] + + if 'scan_type' in config_data: + self.scan_type = config_data['scan_type'] + + if 'payload_level' in config_data: + self.payload_level = config_data['payload_level'] + + if 'output_file' in config_data: + self.output_file = config_data['output_file'] + + if 'output_format' in config_data: + self.output_format = config_data['output_format'] + + if 'verbose' in config_data: + self.verbose = config_data['verbose'] + + if 'no_color' in config_data: + self.no_color = config_data['no_color'] + + # 高级选项 + if 'use_browser' in config_data: + self.use_browser = config_data['use_browser'] + + if 'exploit' in config_data: + self.exploit = config_data['exploit'] + + if 'custom_payloads' in config_data: + self.custom_payloads = config_data['custom_payloads'] + + if 'exclude_pattern' in config_data: + self.exclude_pattern = config_data['exclude_pattern'] + + if 'include_pattern' in config_data: + self.include_pattern = config_data['include_pattern'] + + if 'auth' in config_data: + self.auth = config_data['auth'] + + return True + except Exception as e: + logger.error(f"加载配置文件失败: {str(e)}") + return False + + def save_to_file(self, config_file): + """ + 保存配置到文件 + + Args: + config_file: 配置文件路径 + """ + config_data = { + 'url': self.url, + 'depth': self.depth, + 'threads': self.threads, + 'timeout': self.timeout, + 'user_agent': self.user_agent, + 'cookies': self.cookies, + 'headers': self.headers, + 'proxy': self.proxy, + 'scan_level': self.scan_level, + 'scan_type': self.scan_type, + 'payload_level': self.payload_level, + 'output_file': self.output_file, + 'output_format': self.output_format, + 'verbose': self.verbose, + 'no_color': self.no_color, + 'use_browser': self.use_browser, + 'exploit': self.exploit, + 'custom_payloads': self.custom_payloads, + 'exclude_pattern': self.exclude_pattern, + 'include_pattern': self.include_pattern, + 'auth': self.auth + } + + try: + with open(config_file, 'w') as f: + json.dump(config_data, f, indent=4) + return True + except Exception as e: + logger.error(f"保存配置文件失败: {str(e)}") + return False + + def _parse_cookies(self, cookie_str): + """ + 解析Cookie字符串 + + Args: + cookie_str: Cookie字符串,格式:name1=value1; name2=value2 + """ + if not cookie_str: + return + + try: + self.cookies = {} + for cookie in cookie_str.split(';'): + if '=' in cookie: + name, value = cookie.strip().split('=', 1) + self.cookies[name] = value + except Exception as e: + logger.error(f"解析Cookie失败: {str(e)}") + + def _parse_headers(self, headers_str): + """ + 解析HTTP头字符串 + + Args: + headers_str: HTTP头字符串,格式:Header1:Value1;Header2:Value2 + """ + if not headers_str: + return + + try: + self.headers = {} + for header in headers_str.split(';'): + if ':' in header: + name, value = header.strip().split(':', 1) + self.headers[name] = value + except Exception as e: + logger.error(f"解析HTTP头失败: {str(e)}") + + def _parse_auth(self, auth_str): + """ + 解析基本认证字符串 + + Args: + auth_str: 基本认证字符串,格式:username:password + """ + if not auth_str: + return + + try: + if ':' in auth_str: + username, password = auth_str.split(':', 1) + self.auth = { + 'username': username, + 'password': password + } + except Exception as e: + logger.error(f"解析基本认证失败: {str(e)}") + + def get_payloads_file(self, payload_type): + """ + 获取指定类型的Payload文件路径 + + Args: + payload_type: Payload类型,如xss、sqli等 + + Returns: + str: Payload文件路径 + """ + # 如果指定了自定义Payload文件,则使用自定义文件 + if self.custom_payloads and os.path.exists(self.custom_payloads): + return self.custom_payloads + + # 使用默认的Payload文件 + payload_file = f"{payload_type}_level{self.payload_level}.txt" + payload_path = os.path.join(self.payloads_dir, payload_type, payload_file) + + if not os.path.exists(payload_path): + logger.warning(f"Payload文件不存在: {payload_path},使用默认Payload文件") + payload_path = os.path.join(self.payloads_dir, payload_type, f"{payload_type}_level1.txt") + + return payload_path \ No newline at end of file diff --git a/xss_scanner/core/logger.py b/xss_scanner/core/logger.py new file mode 100644 index 0000000..cbc6f2c --- /dev/null +++ b/xss_scanner/core/logger.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +日志模块,负责管理日志输出 +""" + +import os +import logging +import sys +from datetime import datetime + +class ColoredFormatter(logging.Formatter): + """彩色日志格式化器""" + + # 定义颜色代码 + COLORS = { + 'DEBUG': '\033[94m', # 蓝色 + 'INFO': '\033[92m', # 绿色 + 'WARNING': '\033[93m', # 黄色 + 'ERROR': '\033[91m', # 红色 + 'CRITICAL': '\033[91m\033[1m', # 红色加粗 + 'RESET': '\033[0m' # 重置 + } + + def __init__(self, fmt=None, datefmt=None, style='%', use_color=True): + """ + 初始化格式化器 + + Args: + fmt: 日志格式 + datefmt: 日期格式 + style: 格式风格 + use_color: 是否使用彩色输出 + """ + super().__init__(fmt, datefmt, style) + self.use_color = use_color and sys.platform != 'win32' or os.name == 'posix' + + def format(self, record): + """ + 格式化日志记录 + + Args: + record: 日志记录 + + Returns: + str: 格式化后的日志 + """ + levelname = record.levelname + + # 使用原始格式化方法格式化日志 + message = super().format(record) + + # 如果启用了彩色输出,则添加颜色 + if self.use_color and levelname in self.COLORS: + message = f"{self.COLORS[levelname]}{message}{self.COLORS['RESET']}" + + return message + + +def setup_logger(log_level=logging.INFO, no_color=False): + """ + 设置日志系统 + + Args: + log_level: 日志级别 + no_color: 是否禁用彩色输出 + + Returns: + logging.Logger: 日志记录器 + """ + # 创建日志记录器 + logger = logging.getLogger('xss_scanner') + logger.setLevel(log_level) + + # 清除之前的处理器 + for handler in logger.handlers: + logger.removeHandler(handler) + + # 创建控制台处理器 + console_handler = logging.StreamHandler() + console_handler.setLevel(log_level) + + # 设置日志格式 + log_format = '[%(asctime)s] [%(levelname)s] %(message)s' + date_format = '%Y-%m-%d %H:%M:%S' + + # 创建格式化器 + formatter = ColoredFormatter( + fmt=log_format, + datefmt=date_format, + use_color=not no_color + ) + + # 设置处理器的格式化器 + console_handler.setFormatter(formatter) + + # 将处理器添加到记录器 + logger.addHandler(console_handler) + + return logger + + +def setup_file_logger(log_file, log_level=logging.INFO): + """ + 设置文件日志 + + Args: + log_file: 日志文件路径 + log_level: 日志级别 + + Returns: + logging.Logger: 日志记录器 + """ + # 创建日志记录器 + logger = logging.getLogger('xss_scanner') + + # 创建文件处理器 + try: + file_handler = logging.FileHandler(log_file, encoding='utf-8') + file_handler.setLevel(log_level) + + # 设置日志格式 + log_format = '[%(asctime)s] [%(levelname)s] %(message)s' + date_format = '%Y-%m-%d %H:%M:%S' + + # 创建格式化器 + formatter = logging.Formatter(fmt=log_format, datefmt=date_format) + + # 设置处理器的格式化器 + file_handler.setFormatter(formatter) + + # 将处理器添加到记录器 + logger.addHandler(file_handler) + except Exception as e: + logger.error(f"设置文件日志失败: {str(e)}") + + return logger \ No newline at end of file diff --git a/xss_scanner/core/scanner_engine.py b/xss_scanner/core/scanner_engine.py new file mode 100644 index 0000000..b77077c --- /dev/null +++ b/xss_scanner/core/scanner_engine.py @@ -0,0 +1,239 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +扫描引擎核心模块 +负责协调各种类型的扫描器和管理扫描过程 +""" + +import time +import logging +import threading +import queue +from concurrent.futures import ThreadPoolExecutor +from urllib.parse import urlparse, urljoin + +from xss_scanner.utils.crawler import Crawler +from xss_scanner.utils.http_client import HttpClient +from xss_scanner.scanners.xss_scanner import XSSScanner +from xss_scanner.scanners.csrf_scanner import CSRFScanner +from xss_scanner.scanners.sql_injection_scanner import SQLInjectionScanner +from xss_scanner.scanners.lfi_scanner import LFIScanner +from xss_scanner.scanners.rfi_scanner import RFIScanner +from xss_scanner.scanners.ssrf_scanner import SSRFScanner +from xss_scanner.scanners.xxe_scanner import XXEScanner + +logger = logging.getLogger('xss_scanner') + +class ScannerEngine: + """扫描引擎核心类,负责协调不同类型的扫描器""" + + def __init__(self, config): + """ + 初始化扫描引擎 + + Args: + config: 配置对象,包含扫描参数 + """ + self.config = config + self.http_client = HttpClient( + timeout=config.timeout, + user_agent=config.user_agent, + proxy=config.proxy, + cookies=config.cookies, + headers=config.headers + ) + self.crawler = Crawler( + http_client=self.http_client, + max_depth=config.depth, + threads=config.threads, + exclude_pattern=config.exclude_pattern, + include_pattern=config.include_pattern + ) + + # 初始化各种扫描器 + self.scanners = [] + self.initialize_scanners() + + # 线程池 + self.thread_pool = ThreadPoolExecutor(max_workers=config.threads) + + # 存储扫描结果 + self.results = { + 'target': None, + 'start_time': None, + 'end_time': None, + 'scan_info': { + 'scan_level': config.scan_level, + 'scan_type': config.scan_type, + 'threads': config.threads, + 'depth': config.depth + }, + 'vulnerabilities': [], + 'statistics': { + 'pages_scanned': 0, + 'forms_tested': 0, + 'parameters_tested': 0, + 'vulnerabilities_found': 0 + } + } + + def initialize_scanners(self): + """初始化所有扫描器""" + # 添加XSS扫描器 + self.scanners.append(XSSScanner( + http_client=self.http_client, + payload_level=self.config.payload_level, + use_browser=self.config.use_browser + )) + + # 根据配置添加其他类型的扫描器 + if self.config.scan_type in ['all', 'csrf']: + self.scanners.append(CSRFScanner(self.http_client)) + + if self.config.scan_type in ['all', 'sqli']: + self.scanners.append(SQLInjectionScanner(self.http_client)) + + if self.config.scan_type in ['all', 'lfi']: + self.scanners.append(LFIScanner(self.http_client)) + + if self.config.scan_type in ['all', 'rfi']: + self.scanners.append(RFIScanner(self.http_client)) + + if self.config.scan_type in ['all', 'ssrf']: + self.scanners.append(SSRFScanner(self.http_client)) + + if self.config.scan_type in ['all', 'xxe']: + self.scanners.append(XXEScanner(self.http_client)) + + def scan(self, target_url): + """ + 对目标进行扫描 + + Args: + target_url: 目标URL + + Returns: + dict: 扫描结果 + """ + self.results['target'] = target_url + self.results['start_time'] = time.time() + + # 爬取目标站点 + logger.info(f"开始爬取目标站点: {target_url}") + pages = self.crawler.crawl(target_url) + self.results['statistics']['pages_scanned'] = len(pages) + logger.info(f"爬取完成,发现 {len(pages)} 个页面") + + # 对每个页面进行扫描 + for page in pages: + logger.debug(f"扫描页面: {page['url']}") + + # 对页面中的表单进行测试 + for form in page.get('forms', []): + self.results['statistics']['forms_tested'] += 1 + self._scan_form(page['url'], form) + + # 对URL参数进行测试 + if page.get('params', []): + self._scan_params(page['url'], page['params']) + self.results['statistics']['parameters_tested'] += len(page['params']) + + # 如果配置了漏洞利用,则尝试利用发现的漏洞 + if self.config.exploit and self.results['vulnerabilities']: + self._exploit_vulnerabilities() + + self.results['end_time'] = time.time() + self.results['statistics']['vulnerabilities_found'] = len(self.results['vulnerabilities']) + + return self.results + + def _scan_form(self, url, form): + """ + 扫描表单 + + Args: + url: 页面URL + form: 表单信息 + """ + logger.debug(f"扫描表单: {form.get('id', 'unknown')}") + + # 对表单中的每个输入字段进行测试 + for field in form.get('fields', []): + if field['type'] in ['text', 'search', 'url', 'email', 'password', 'tel', 'number']: + for scanner in self.scanners: + # 跳过不适用于表单的扫描器 + if not scanner.can_scan_form(): + continue + + result = scanner.scan_form(url, form, field) + if result: + self.results['vulnerabilities'].append(result) + logger.warning(f"在表单中发现漏洞: {result['type']} - {result['description']}") + + def _scan_params(self, url, params): + """ + 扫描URL参数 + + Args: + url: 页面URL + params: URL参数列表 + """ + logger.debug(f"扫描URL参数: {', '.join(params)}") + + for param in params: + for scanner in self.scanners: + # 跳过不适用于URL参数的扫描器 + if not scanner.can_scan_params(): + continue + + result = scanner.scan_parameter(url, param) + if result: + self.results['vulnerabilities'].append(result) + logger.warning(f"在URL参数中发现漏洞: {result['type']} - {result['description']}") + + def _exploit_vulnerabilities(self): + """尝试利用发现的漏洞""" + logger.info("尝试利用发现的漏洞...") + + for vuln in self.results['vulnerabilities']: + # 根据漏洞类型选择合适的利用模块 + exploit_module = self._get_exploit_module(vuln['type']) + if exploit_module: + exploit_result = exploit_module.exploit(vuln) + if exploit_result: + vuln['exploit_result'] = exploit_result + logger.warning(f"成功利用漏洞: {vuln['type']} - {exploit_result['description']}") + + def _get_exploit_module(self, vuln_type): + """ + 根据漏洞类型获取对应的利用模块 + + Args: + vuln_type: 漏洞类型 + + Returns: + 对应的利用模块实例 + """ + if vuln_type == 'XSS': + from xss_scanner.exploits.xss_exploit import XSSExploit + return XSSExploit(self.http_client) + elif vuln_type == 'CSRF': + from xss_scanner.exploits.csrf_exploit import CSRFExploit + return CSRFExploit(self.http_client) + elif vuln_type == 'SQL_INJECTION': + from xss_scanner.exploits.sqli_exploit import SQLInjectionExploit + return SQLInjectionExploit(self.http_client) + elif vuln_type == 'LFI': + from xss_scanner.exploits.lfi_exploit import LFIExploit + return LFIExploit(self.http_client) + elif vuln_type == 'RFI': + from xss_scanner.exploits.rfi_exploit import RFIExploit + return RFIExploit(self.http_client) + elif vuln_type == 'SSRF': + from xss_scanner.exploits.ssrf_exploit import SSRFExploit + return SSRFExploit(self.http_client) + elif vuln_type == 'XXE': + from xss_scanner.exploits.xxe_exploit import XXEExploit + return XXEExploit(self.http_client) + return None \ No newline at end of file diff --git a/xss_scanner/exploits/xss_exploit.py b/xss_scanner/exploits/xss_exploit.py new file mode 100644 index 0000000..9921193 --- /dev/null +++ b/xss_scanner/exploits/xss_exploit.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +XSS漏洞利用模块,负责利用发现的XSS漏洞 +""" + +import logging +import random +import string +import base64 +from urllib.parse import urlencode, urlparse, parse_qsl + +logger = logging.getLogger('xss_scanner') + +class XSSExploit: + """XSS漏洞利用类,负责利用XSS漏洞执行特定操作""" + + def __init__(self, http_client): + """ + 初始化XSS漏洞利用模块 + + Args: + http_client: HTTP客户端对象 + """ + self.http_client = http_client + self.exploit_id = self._generate_random_string(8) + + # 常用的XSS利用载荷 + self.cookie_steal_payload = f"""""" + + self.keylogger_payload = f"""""" + + self.session_hijack_payload = f"""""" + + self.phishing_payload = f"""
请重新登录以继续
+ + +