商丘微网站,如何创建一家自己的公司,房地产网页,系统管理在哪里目录
前言
NetBIOS
什么是 NetBIOS#xff1f;
NetBIOS 核心服务
NetBIOS 到底干什么用#xff1f;
1. 名字解析#xff08;主要功能#xff09;
2. 服务发现
3. 会话管理
探测原理
存活判断的标准
代码设计思路
两阶段扫描架构
状态机设计
模块1: NetBIOS探…目录前言NetBIOS什么是 NetBIOSNetBIOS 核心服务NetBIOS 到底干什么用1. 名字解析主要功能2. 服务发现3. 会话管理探测原理存活判断的标准代码设计思路两阶段扫描架构状态机设计模块1: NetBIOS探测模块模块2: 协议验证模块代码分析构造探测数据建立连接并发送探测数据接受并分析响应源代码其它前言判断存活的标准是服务开启端口开启下面进行详细讲解这种探测方式不太常用。NetBIOS什么是 NetBIOS网络基本输入/输出系统NetBIOSNetwork Basic Input/Output System是1983年由IBM开发的网络协议为局域网应用程序提供统一的命令集。虽然现在逐渐被DNS取代但在Windows网络中仍然广泛使用。NetBIOS 核心服务端口协议服务名称功能137/UDPNetBIOS名称服务NBNS主机名解析、名称注册查询138/UDPNetBIOS数据报服务NBDS网络广播、消息传递139/TCPNetBIOS会话服务NBSS文件/打印机共享连接NetBIOS 到底干什么用1.名字解析主要功能你想联系财务部电脑但不知道它的IP地址 → 问NetBIOS财务部电脑的IP是多少 → NetBIOS回答192.168.1.1052.服务发现你想知道网络里有哪些电脑共享了打印机 → 问NetBIOS谁共享了打印机 → NetBIOS回答技术部电脑、前台电脑3.会话管理你要访问技术部电脑的共享文件夹 → NetBIOS帮你建立稳定连接探测原理基于NetBIOS名称服务协议协议: NetBIOS Name Service (NBNS)端口: UDP 137机制: 通过发送特定的NetBIOS状态查询包根据响应判断主机存活状态存活判断的标准udp的137端口开启且netbios服务开启代码设计思路两阶段扫描架构阶段1: 主机发现 (TCP端口扫描) → 阶段2: NetBIOS服务探测 (UDP 137端口)设计理念先找到存活主机再针对性地探测服务避免对不存在的主机进行无谓的UDP探测。状态机设计定义了清晰的三种状态alive: 收到有效的NetBIOS响应filtered: 主机存活但NetBIOS无响应端口被过滤dead: 主机不存活或NetBIOS服务关闭模块1: NetBIOS探测模块// 设计思路UDP协议状态探测 输入: 存活主机IP 输出: NetBIOS状态结果 策略: 发送标准NetBIOS查询包根据响应判断服务状态模块2: 协议验证模块// 设计思路协议格式验证 输入: 原始网络数据 输出: 是否为有效NetBIOS响应 策略: 检查数据包长度和标志位(QR位)代码分析构造探测数据func createNetBIOSQuery() []byte { return []byte{ 0x12, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4B, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21, 0x00, 0x01, } }这是一个NetBIOS名称服务状态查询包这个查询包的作用是查询类型: NetBIOS节点状态查询 (NBSTAT)目标: 请求目标主机返回其NetBIOS名称表响应内容: 包括主机名、服务类型、MAC地址等当这个包发送到目标的137端口时如果主机存在且运行NetBIOS服务会返回节点状态信息如果主机不存在或服务关闭会超时或无响应响应包包含详细的NetBIOS名称表和MAC地址建立连接并发送探测数据func netbios_scan_survival(ipaddres []string) { // 阶段1: NetBIOS扫描只对存活主机 fmt.Println(阶段1: NetBIOS扫描...) sem : make(chan struct{}, 50) for _, ip : range aliveHosts { wg.Add(1) go func(ip string) { defer wg.Done() sem - struct{}{} defer func() { -sem }() result : netbiosProbe(ip) mu.Lock() if result.Status ! dead { results append(results, result) } mu.Unlock() }(ip) } wg.Wait() ...... } // NetBIOS探测 - 只对已知存活的主机进行 func netbiosProbe(ip string) NetBIOSResult { result : NetBIOSResult{ IP: ip, Status: dead, Port137: 关闭, } // UDP 137端口探测 conn, err : net.DialTimeout(udp, fmt.Sprintf(%s:%d, ip, 137), 3*time.Second) if err ! nil { return result } defer conn.Close() conn.SetDeadline(time.Now().Add(3 * time.Second)) // 发送查询 query : createNetBIOSQuery() if _, err : conn.Write(query); err ! nil { return result } ...... return result }接受并分析响应// NetBIOS探测 - 只对已知存活的主机进行 func netbiosProbe(ip string) NetBIOSResult { result : NetBIOSResult{ IP: ip, Status: dead, Port137: 关闭, } ...... // 接收响应 buffer : make([]byte, 1024) n, err : conn.Read(buffer) if err ! nil { if netErr, ok : err.(net.Error); ok netErr.Timeout() { // 已知存活的主机 UDP超时 open|filtered result.Status filtered result.Port137 开放或被过滤 } return result } // 收到有效响应 if n 0 validateNetBIOSResponse(buffer[:n]) { result.Status alive result.Port137 开放 } return result } // 验证 NetBIOS 响应 func validateNetBIOSResponse(data []byte) bool { if len(data) 12 { return false } // 检查响应标志位 (第3字节的最高位) flags : binary.BigEndian.Uint16(data[2:4]) isResponse : (flags 0x8000) ! 0 // 检查答案数量 answerCount : binary.BigEndian.Uint16(data[6:8]) //之前的代码没有新添加的 return isResponse answerCount 0 }长度检查if len(data) 12 { return false }原因: NetBINS响应包头部至少12字节作用: 过滤掉太短的无意义数据包提取标志位flags : binary.BigEndian.Uint16(data[2:4])位置: 数据包的第3-4字节0-based索引2:4格式: 大端序16位无符号整数含义: 提取NetBIOS响应标志字段源代码直接给出完整源代码https://github.com/yty0v0/ReconQuiver/blob/main/internal/discovery/netbios_host/netbios.go其它在我写完针对多协议端口扫描和主机探测的工具后希望通过文章整理用到的知识点非常欢迎各位大佬指正文章内容的错误和工具的问题。这里附上工具链接 https://github.com/yty0v0/ReconQuiver