refactor: Scanner Scan函数重构

This commit is contained in:
ZacharyZcR 2024-12-18 15:18:58 +08:00
parent 624ab9bab0
commit 02dfcebcc5

View File

@ -11,71 +11,103 @@ import (
)
func Scan(info common.HostInfo) {
fmt.Println("start infoscan")
Hosts, err := common.ParseIP(info.Host, common.HostFile, common.NoHosts)
if err != nil {
fmt.Println("len(hosts)==0", err)
fmt.Println("[*] 开始信息扫描...")
// 本地信息收集模块
if common.Scantype == "localinfo" {
ch := make(chan struct{}, common.Threads)
wg := sync.WaitGroup{}
AddScan("1000006", info, &ch, &wg)
wg.Wait()
common.LogWG.Wait()
close(common.Results)
fmt.Printf("[✓] 扫描完成 %v/%v\n", common.End, common.Num)
return
}
// 解析目标主机IP
Hosts, err := common.ParseIP(info.Host, common.HostFile, common.NoHosts)
if err != nil {
fmt.Printf("[!] 解析主机错误: %v\n", err)
return
}
// 初始化配置
lib.Inithttp()
var ch = make(chan struct{}, common.Threads)
var wg = sync.WaitGroup{}
ch := make(chan struct{}, common.Threads)
wg := sync.WaitGroup{}
web := strconv.Itoa(common.PORTList["web"])
ms17010 := strconv.Itoa(common.PORTList["ms17010"])
var AlivePorts, severports []string
if len(Hosts) > 0 || len(common.HostPort) > 0 {
if common.NoPing == false && len(Hosts) > 1 || common.Scantype == "icmp" {
// ICMP存活性检测
if (common.NoPing == false && len(Hosts) > 1) || common.Scantype == "icmp" {
Hosts = CheckLive(Hosts, common.Ping)
fmt.Println("[*] Icmp alive hosts len is:", len(Hosts))
}
if common.Scantype == "icmp" {
common.LogWG.Wait()
return
}
var AlivePorts []string
if common.Scantype == "webonly" || common.Scantype == "webpoc" {
AlivePorts = NoPortScan(Hosts, common.Ports)
} else if common.Scantype == "hostname" {
common.Ports = "139"
AlivePorts = NoPortScan(Hosts, common.Ports)
} else if len(Hosts) > 0 {
AlivePorts = PortScan(Hosts, common.Ports, common.Timeout)
fmt.Println("[*] alive ports len is:", len(AlivePorts))
if common.Scantype == "portscan" {
fmt.Printf("[+] ICMP存活主机数量: %d\n", len(Hosts))
if common.Scantype == "icmp" {
common.LogWG.Wait()
return
}
}
// 端口扫描策略
switch common.Scantype {
case "webonly", "webpoc":
AlivePorts = NoPortScan(Hosts, common.Ports)
case "hostname":
common.Ports = "139"
AlivePorts = NoPortScan(Hosts, common.Ports)
default:
if len(Hosts) > 0 {
AlivePorts = PortScan(Hosts, common.Ports, common.Timeout)
fmt.Printf("[+] 存活端口数量: %d\n", len(AlivePorts))
if common.Scantype == "portscan" {
common.LogWG.Wait()
return
}
}
}
// 处理自定义端口
if len(common.HostPort) > 0 {
AlivePorts = append(AlivePorts, common.HostPort...)
AlivePorts = common.RemoveDuplicate(AlivePorts)
common.HostPort = nil
fmt.Println("[*] AlivePorts len is:", len(AlivePorts))
fmt.Printf("[+] 总计存活端口: %d\n", len(AlivePorts))
}
var severports []string //severports := []string{"21","22","135"."445","1433","3306","5432","6379","9200","11211","27017"...}
// 构建服务端口列表
for _, port := range common.PORTList {
severports = append(severports, strconv.Itoa(port))
}
fmt.Println("start vulscan")
// 开始漏洞扫描
fmt.Println("[*] 开始漏洞扫描...")
for _, targetIP := range AlivePorts {
info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1]
hostParts := strings.Split(targetIP, ":")
if len(hostParts) != 2 {
fmt.Printf("[!] 无效的目标地址格式: %s\n", targetIP)
continue
}
info.Host, info.Ports = hostParts[0], hostParts[1]
if common.Scantype == "all" || common.Scantype == "main" {
switch {
case info.Ports == "135":
AddScan(info.Ports, info, &ch, &wg) //findnet
AddScan(info.Ports, info, &ch, &wg)
if common.IsWmi {
AddScan("1000005", info, &ch, &wg) //wmiexec
AddScan("1000005", info, &ch, &wg)
}
case info.Ports == "445":
AddScan(ms17010, info, &ch, &wg) //ms17010
//AddScan(info.Ports, info, ch, &wg) //smb
//AddScan("1000002", info, ch, &wg) //smbghost
AddScan(ms17010, info, &ch, &wg)
case info.Ports == "9000":
AddScan(web, info, &ch, &wg) //http
AddScan(info.Ports, info, &ch, &wg) //fcgiscan
AddScan(web, info, &ch, &wg)
AddScan(info.Ports, info, &ch, &wg)
case IsContain(severports, info.Ports):
AddScan(info.Ports, info, &ch, &wg) //plugins scan
AddScan(info.Ports, info, &ch, &wg)
default:
AddScan(web, info, &ch, &wg) //webtitle
AddScan(web, info, &ch, &wg)
}
} else {
scantype := strconv.Itoa(common.PORTList[common.Scantype])
@ -83,45 +115,69 @@ func Scan(info common.HostInfo) {
}
}
}
// URL扫描
for _, url := range common.Urls {
info.Url = url
AddScan(web, info, &ch, &wg)
}
// 等待所有任务完成
wg.Wait()
common.LogWG.Wait()
close(common.Results)
fmt.Printf("已完成 %v/%v\n", common.End, common.Num)
fmt.Printf("[✓] 扫描已完成: %v/%v\n", common.End, common.Num)
}
// Mutex用于保护共享资源的并发访问
var Mutex = &sync.Mutex{}
// AddScan 添加扫描任务到并发队列
func AddScan(scantype string, info common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) {
// 获取信号量,控制并发数
*ch <- struct{}{}
// 添加等待组计数
wg.Add(1)
// 启动goroutine执行扫描任务
go func() {
defer func() {
wg.Done() // 完成任务后减少等待组计数
<-*ch // 释放信号量
}()
// 增加总任务数
Mutex.Lock()
common.Num += 1
Mutex.Unlock()
// 执行扫描
ScanFunc(&scantype, &info)
// 增加已完成任务数
Mutex.Lock()
common.End += 1
Mutex.Unlock()
wg.Done()
<-*ch
}()
}
// ScanFunc 通过反射调用对应的扫描插件
func ScanFunc(name *string, info *common.HostInfo) {
// 异常恢复处理
defer func() {
if err := recover(); err != nil {
fmt.Printf("[-] %v:%v scan error: %v\n", info.Host, info.Ports, err)
fmt.Printf("[!] 扫描错误 %v:%v - %v\n", info.Host, info.Ports, err)
}
}()
// 通过反射获取插件函数
f := reflect.ValueOf(PluginList[*name])
// 构造参数并调用插件函数
in := []reflect.Value{reflect.ValueOf(info)}
f.Call(in)
}
// IsContain 检查切片中是否包含指定元素
func IsContain(items []string, item string) bool {
for _, eachItem := range items {
if eachItem == item {