-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.py
More file actions
375 lines (308 loc) · 12.2 KB
/
main.py
File metadata and controls
375 lines (308 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
全面漏洞扫描工具 - 主程序入口
集成网络扫描、Web漏洞检测、目录爆破、子域名枚举等功能
"""
import argparse
import sys
import json
from pathlib import Path
from datetime import datetime
# 导入主扫描器
from modules.scanner import VulnerabilityScannerMain, ScanResult
def print_banner():
"""打印程序横幅"""
banner = """
╔══════════════════════════════════════════════════════════════╗
║ 全面漏洞扫描工具 v1.0.0 ║
║ Mochen ║
╠══════════════════════════════════════════════════════════════╣
║ 功能: ║
║ • 端口扫描 (TCP/UDP) ║
║ • Web漏洞检测 (SQL注入/XSS/命令注入) ║
║ • 目录爆破 (隐藏文件/目录发现) ║
║ • 子域名枚举 (DNS记录查询) ║
║ • 多格式报告 (HTML/JSON/CSV/Excel) ║
╚══════════════════════════════════════════════════════════════╝
"""
print(banner)
def load_targets_from_file(filepath: str) -> list:
"""
从文件加载目标列表
Args:
filepath: 文件路径
Returns:
list: 目标列表
"""
targets = []
try:
with open(filepath, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
targets.append(line)
print(f"✅ 从文件加载 {len(targets)} 个目标")
except FileNotFoundError:
print(f"❌ 文件不存在: {filepath}")
sys.exit(1)
except Exception as e:
print(f"❌ 读取文件失败: {e}")
sys.exit(1)
return targets
def parse_scan_types(scan_arg: str) -> list:
"""
解析扫描类型参数
Args:
scan_arg: 扫描类型参数
Returns:
list: 扫描类型列表
"""
if scan_arg == "all":
return ["port", "directory", "vulnerability", "subdomain"]
elif scan_arg == "network":
return ["port", "subdomain"]
elif scan_arg == "web":
return ["directory", "vulnerability"]
else:
return [scan_arg]
def main():
"""主函数"""
parser = argparse.ArgumentParser(
description="全面漏洞扫描工具",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
使用示例:
# 扫描单个目标的所有漏洞
python main.py --target example.com --scan all
# 只扫描Web漏洞
python main.py --target example.com --scan web
# 扫描多个目标
python main.py --targets targets.txt --scan all
# 自定义配置文件
python main.py --target example.com --config myconfig.yaml
# 生成JSON报告
python main.py --target example.com --scan all --format json
# 指定输出路径
python main.py --target example.com --output ./myreport.html
# 设置并发线程数
python main.py --target example.com --threads 100
"""
)
# 目标参数组
target_group = parser.add_mutually_exclusive_group(required=True)
target_group.add_argument("--target", type=str, help="单个扫描目标 (IP/域名/URL)")
target_group.add_argument("--targets", type=str, help="包含多个目标的文件路径")
# 扫描参数
parser.add_argument("--scan", type=str, default="all",
choices=["all", "network", "web", "port", "directory",
"vulnerability", "subdomain"],
help="扫描类型 (默认: all)")
# 输出参数
parser.add_argument("--output", type=str, help="报告输出路径")
parser.add_argument("--format", type=str, default="html",
choices=["html", "json", "csv", "excel"],
help="报告格式 (默认: html)")
# 配置参数
parser.add_argument("--config", type=str, default="config/config.yaml",
help="配置文件路径 (默认: config/config.yaml)")
# 性能参数
parser.add_argument("--threads", type=int, help="并发线程数")
parser.add_argument("--timeout", type=int, help="超时时间(秒)")
# 其他参数
parser.add_argument("--verbose", "-v", action="store_true",
help="详细输出模式")
parser.add_argument("--quiet", "-q", action="store_true",
help="安静模式,只输出错误")
parser.add_argument("--no-banner", action="store_true",
help="不显示横幅")
args = parser.parse_args()
# 显示横幅
if not args.no_banner:
print_banner()
# 准备目标列表
if args.target:
targets = [args.target]
print(f"🎯 扫描目标: {args.target}")
else:
targets = load_targets_from_file(args.targets)
print(f"🎯 扫描 {len(targets)} 个目标")
# 解析扫描类型
scan_types = parse_scan_types(args.scan)
print(f"🔍 扫描类型: {', '.join(scan_types)}")
# 创建扫描器
try:
scanner = VulnerabilityScannerMain(args.config)
print("✅ 扫描器初始化完成")
# 应用性能参数
if args.threads:
scanner.config["scanning"]["threads"] = args.threads
print(f"⚡ 设置并发线程数: {args.threads}")
if args.timeout:
scanner.config["scanning"]["timeout"] = args.timeout
print(f"⏱️ 设置超时时间: {args.timeout}秒")
except Exception as e:
print(f"❌ 扫描器初始化失败: {e}")
sys.exit(1)
# 执行扫描
print("\n" + "="*60)
print("开始扫描...")
print("="*60)
start_time = datetime.now()
try:
if len(targets) == 1:
# 单个目标扫描
result = scanner.scan(targets[0], scan_types)
results = [result]
else:
# 多个目标并发扫描
max_workers = args.threads if args.threads else scanner.config["scanning"].get("threads", 50)
results = scanner.scan_multiple(targets, scan_types, max_workers)
except KeyboardInterrupt:
print("\n⚠️ 扫描被用户中断")
sys.exit(0)
except Exception as e:
print(f"❌ 扫描过程中发生错误: {e}")
sys.exit(1)
end_time = datetime.now()
elapsed = (end_time - start_time).total_seconds()
print("\n" + "="*60)
print("扫描完成!")
print("="*60)
print(f"⏱️ 总耗时: {elapsed:.2f}秒")
# 生成报告
successful_scans = 0
total_findings = 0
for result in results:
if result.status == "completed":
successful_scans += 1
stats = result.calculate_stats()
total_findings += stats["total_findings"]
# 生成报告
try:
report_path = scanner.generate_report(result, args.format, args.output)
print(f"📄 报告已生成: {report_path}")
except Exception as e:
print(f"⚠️ 生成报告失败: {e}")
# 显示摘要
print("\n📊 扫描摘要:")
print("-" * 40)
print(f"总扫描数: {len(results)}")
print(f"成功: {successful_scans}")
print(f"失败: {len(results) - successful_scans}")
print(f"总发现数: {total_findings}")
if successful_scans > 0:
# 生成汇总报告(如果有多个成功扫描)
if successful_scans > 1:
try:
summary_path = f"reports/summary_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
successful_results = [r for r in results if r.status == "completed"]
# 使用报告生成器创建汇总报告
from modules.utils.output_reporter import OutputReporter
reporter = OutputReporter(scanner.config)
summary_path = reporter.generate_summary_report(
[r.to_dict() for r in successful_results],
"html"
)
print(f"📊 汇总报告: {summary_path}")
except Exception as e:
print(f"⚠️ 生成汇总报告失败: {e}")
# 显示风险分布
print("\n⚠️ 风险分布:")
print("-" * 40)
severity_counts = {
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"info": 0
}
for result in results:
if result.status == "completed":
stats = result.calculate_stats()
for severity in severity_counts:
severity_counts[severity] += stats.get(severity, 0)
for severity, count in severity_counts.items():
if count > 0:
print(f" {severity.upper():<10}: {count}")
print("\n" + "="*60)
print("扫描结束。请查看生成的报告获取详细信息。")
print("="*60)
# 错误报告
errors_found = False
for result in results:
if result.errors:
errors_found = True
print(f"\n❌ 目标 {result.target} 的错误:")
for error in result.errors:
print(f" - {error}")
if errors_found:
print("\n💡 建议检查网络连接和配置文件,然后重试。")
# 退出代码
if successful_scans == 0:
sys.exit(1) # 没有成功扫描
elif total_findings == 0:
sys.exit(0) # 成功但未发现漏洞
else:
sys.exit(0) # 成功并发现漏洞
def test_mode():
"""测试模式,用于快速验证功能"""
print("🔧 进入测试模式...")
# 创建测试配置
test_config = {
"scanning": {
"timeout": 5,
"threads": 10,
"user_agent": "VulnerabilityScanner/Test"
},
"network": {
"default_ports": "80,443,8080"
},
"web": {
"directories_wordlist": "config/wordlists/directories.txt",
"extensions": [".php", ".html", ".txt"]
},
"dns": {
"subdomains_wordlist": "config/wordlists/subdomains.txt",
"dns_servers": ["8.8.8.8"]
},
"output": {
"report_dir": "reports",
"default_format": "html"
}
}
# 测试目标
test_target = "127.0.0.1"
print(f"🎯 测试目标: {test_target}")
print("🔍 测试端口扫描...")
try:
# 测试端口扫描器
from modules.network.port_scanner import PortScanner
port_scanner = PortScanner(test_config)
# 只扫描常见端口
findings = port_scanner.scan_with_socket(test_target, [80, 443, 8080, 22])
if findings:
print(f"✅ 发现 {len(findings)} 个开放端口")
for finding in findings[:3]: # 只显示前3个
print(f" - 端口 {finding['details']['port']}/{finding['details']['protocol']}")
else:
print("ℹ️ 未发现开放端口")
print("\n🎉 测试完成!")
except Exception as e:
print(f"❌ 测试失败: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
# 检查是否处于测试模式
if len(sys.argv) == 1:
# 没有参数时显示帮助
print_banner()
print("\n使用方法: python main.py --help 查看帮助")
print("测试模式: python main.py --test")
sys.exit(0)
elif len(sys.argv) == 2 and sys.argv[1] == "--test":
# 测试模式
test_mode()
else:
# 正常模式
main()