扫描器解析日记之目标探测
字数 1142 2025-08-20 18:17:59

扫描器目标探测模块解析与实现

1. 目标探测概述

目标探测是扫描器的核心功能之一,主要用于识别网络中存活的主机和开放的端口。本文以fscan、GoGo和dddd三款扫描器为例,详细分析其目标探测模块的实现原理和技术细节。

2. fscan目标探测实现

2.1 IP地址解析

fscan的IP解析逻辑位于ParseIP函数中,主要处理以下几种格式的输入:

func ParseIP(host string, filename string, nohosts ...string) (hosts []string, err error) {
    if filename == "" && strings.Contains(host, ":") {
        // 处理带端口的IP格式:192.168.0.0/16:80
        hostport := strings.Split(host, ":")
        if len(hostport) == 2 {
            host = hostport[0]
            hosts = ParseIPs(host)
            Ports = hostport[1]
        }
    } else {
        hosts = ParseIPs(host)
        if filename != "" {
            var filehost []string
            filehost, _ = Readipfile(filename)
            hosts = append(hosts, filehost...)
        }
    }
    // 去重处理
    hosts = RemoveDuplicate(hosts)
    return
}

2.2 存活探测实现

fscan提供了两种存活探测方式:

2.2.1 ICMP探测

func CheckLive(hostslist []string, Ping bool) []string {
    chanHosts := make(chan string, len(hostslist))
    go func() {
        for ip := range chanHosts {
            if _, ok := ExistHosts[ip]; !ok && IsContain(hostslist, ip) {
                ExistHosts[ip] = struct{}{}
                AliveHosts = append(AliveHosts, ip)
            }
            livewg.Done()
        }
    }()
    // ...
}

2.2.2 TCP端口探测

func PortConnect(addr Addr, respondingHosts chan<- string, adjustedTimeout int64, wg *sync.WaitGroup) {
    host, port := addr.ip, addr.port
    conn, err := common.WrapperTcpWithTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), 
        time.Duration(adjustedTimeout)*time.Second)
    if err == nil {
        defer conn.Close()
        address := host + ":" + strconv.Itoa(port)
        respondingHosts <- address
    }
}

2.3 大网段扫描优化

fscan对大网段(/8)扫描进行了优化,避免扫描过多IP:

func parseIP8(ip string) []string {
    var AllIP []string
    for _, i := range CIDRToIP(ip) {
        AllIP = append(AllIP, i.String())
    }
    return AllIP
}

func CIDRToIP(cidr string) (IPs []net.IP) {
    _, network, _ := net.ParseCIDR(cidr)
    first := FirstIP(network)
    last := LastIP(network)
    return pairsToIP(first, last)
}

3. GoGo目标探测实现

3.1 端口扫描分发

GoGo通过Dispatch函数根据端口号分发不同的扫描逻辑:

func Dispatch(result *pkg.Result) {
    switch result.Port {
    case "137", "nbt":
        nbtScan(result)
    case "135", "wmi":
        wmiScan(result)
    case "oxid":
        oxidScan(result)
    case "icmp", "ping":
        icmpScan(result)
    case "snmp", "161":
        snmpScan(result)
    case "445", "smb":
        smbScan(result)
    // ...其他端口处理
    default:
        initScan(result)
    }
}

3.2 基础TCP扫描

func initScan(result *pkg.Result) {
    conn, err := pkg.NewSocket("tcp", target, RunOpt.Delay)
    if err != nil {
        result.Err = err
        return
    }
    defer conn.Close()
    result.Open = true
    
    bs, err := conn.Read(RunOpt.Delay)
    if err != nil {
        senddataStr := fmt.Sprintf("GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", result.Uri, target)
        bs, err = conn.Request([]byte(senddataStr), DefaultMaxSize)
    }
    pkg.CollectSocketResponse(result, bs)
}

4. dddd目标探测实现

4.1 多阶段探测

dddd采用多阶段探测策略:

// ICMP探测存活
if !structs.GlobalConfig.NoICMPPing {
    ICMPAlive = common.CheckLive(ips, false)
}

// TCP探测存活
if structs.GlobalConfig.TCPPing {
    tcpAliveIPPort := common.PortScanTCP(uncheck, "80,443,3389,445,22",
        structs.GlobalConfig.NoPortString,
        structs.GlobalConfig.TCPPortScanTimeout)
    for _, tIPPort := range tcpAliveIPPort {
        t := strings.Split(tIPPort, ":")
        TCPAlive = append(TCPAlive, t[0])
    }
}

4.2 SYN扫描集成

dddd集成了masscan进行SYN扫描:

// 调用masscan进行SYN端口扫描
masscanArgs := []string{
    "--ports", ports,
    "--rate", strconv.Itoa(structs.GlobalConfig.Rate),
    "-oG", outputFile,
}
masscanArgs = append(masscanArgs, ips...)

5. 技术对比与总结

特性 fscan GoGo dddd
IP解析 支持CIDR、范围、文件输入 支持标准格式 支持多种格式
存活探测 ICMP/TCP 多协议探测 ICMP/TCP/SYN
大网段优化 随机采样 无特别优化 无特别优化
端口扫描 基础TCP连接 协议识别+定制扫描 SYN扫描集成
代理支持 支持SOCKS5 支持HTTP/SOCKS 支持多种代理

6. 最佳实践建议

  1. IP解析优化

    • 实现CIDR到IP列表的高效转换
    • 对大网段(/8)采用采样策略
    • 支持多种输入格式(文件、范围、CIDR)
  2. 存活探测策略

    • 优先使用ICMP探测
    • 对ICMP无响应主机尝试TCP探测
    • 关键端口(80,443,22,3389等)作为补充
  3. 扫描性能优化

    • 使用goroutine和channel实现并发
    • 合理设置超时时间
    • 实现结果去重和状态管理
  4. 协议识别

    • 对常见端口实现定制化探测
    • 自动识别HTTP/HTTPS服务
    • 支持特殊协议(如WMI、SNMP等)

7. 参考实现

// 综合扫描器示例
func AdvancedScan(targets []string) {
    // 阶段1:ICMP存活探测
    aliveHosts := ICMPProbe(targets)
    
    // 阶段2:TCP端口扫描
    openPorts := TCPScan(aliveHosts, "80,443,22,3389,445")
    
    // 阶段3:服务识别
    for host, ports := range openPorts {
        for _, port := range ports {
            switch port {
            case 80, 443:
                result := HTTPProbe(host, port)
            case 445:
                result := SMBProbe(host)
            // 其他端口处理...
            }
        }
    }
}

8. 参考文献

  1. fscan源码: https://github.com/shadow1ng/fscan
  2. GoGo文档: https://chainreactors.github.io/wiki/gogo
  3. dddd源码: https://github.com/SleepingBag945/dddd
  4. 网络扫描技术详解: https://xz.aliyun.com/t/15318
扫描器目标探测模块解析与实现 1. 目标探测概述 目标探测是扫描器的核心功能之一,主要用于识别网络中存活的主机和开放的端口。本文以fscan、GoGo和dddd三款扫描器为例,详细分析其目标探测模块的实现原理和技术细节。 2. fscan目标探测实现 2.1 IP地址解析 fscan的IP解析逻辑位于 ParseIP 函数中,主要处理以下几种格式的输入: 2.2 存活探测实现 fscan提供了两种存活探测方式: 2.2.1 ICMP探测 2.2.2 TCP端口探测 2.3 大网段扫描优化 fscan对大网段(/8)扫描进行了优化,避免扫描过多IP: 3. GoGo目标探测实现 3.1 端口扫描分发 GoGo通过 Dispatch 函数根据端口号分发不同的扫描逻辑: 3.2 基础TCP扫描 4. dddd目标探测实现 4.1 多阶段探测 dddd采用多阶段探测策略: 4.2 SYN扫描集成 dddd集成了masscan进行SYN扫描: 5. 技术对比与总结 | 特性 | fscan | GoGo | dddd | |------|-------|------|------| | IP解析 | 支持CIDR、范围、文件输入 | 支持标准格式 | 支持多种格式 | | 存活探测 | ICMP/TCP | 多协议探测 | ICMP/TCP/SYN | | 大网段优化 | 随机采样 | 无特别优化 | 无特别优化 | | 端口扫描 | 基础TCP连接 | 协议识别+定制扫描 | SYN扫描集成 | | 代理支持 | 支持SOCKS5 | 支持HTTP/SOCKS | 支持多种代理 | 6. 最佳实践建议 IP解析优化 : 实现CIDR到IP列表的高效转换 对大网段(/8)采用采样策略 支持多种输入格式(文件、范围、CIDR) 存活探测策略 : 优先使用ICMP探测 对ICMP无响应主机尝试TCP探测 关键端口(80,443,22,3389等)作为补充 扫描性能优化 : 使用goroutine和channel实现并发 合理设置超时时间 实现结果去重和状态管理 协议识别 : 对常见端口实现定制化探测 自动识别HTTP/HTTPS服务 支持特殊协议(如WMI、SNMP等) 7. 参考实现 8. 参考文献 fscan源码: https://github.com/shadow1ng/fscan GoGo文档: https://chainreactors.github.io/wiki/gogo dddd源码: https://github.com/SleepingBag945/dddd 网络扫描技术详解: https://xz.aliyun.com/t/15318