mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00
feat: 增强目标解析功能支持host:port格式
- 修复目标地址验证逻辑,支持host:port格式的直接输入 - 优化端口扫描流程,对明确指定的host:port跳过不必要的端口扫描 - 改进主机地址解析,智能识别和处理host:port格式 - 统一端口扫描结果显示,避免显示不一致问题 - 增强用户体验,支持 -h 127.0.0.1:135 等便捷格式
This commit is contained in:
parent
cc4f55374a
commit
2703ddd9ed
@ -197,17 +197,42 @@ func (tp *TargetParser) parseHosts(input *TargetInput) ([]string, []error, []str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去重和验证
|
// 去重和验证,同时分离host:port格式
|
||||||
hosts = tp.removeDuplicateStrings(hosts)
|
hosts = tp.removeDuplicateStrings(hosts)
|
||||||
validHosts := make([]string, 0, len(hosts))
|
validHosts := make([]string, 0, len(hosts))
|
||||||
|
hostPorts := make([]string, 0)
|
||||||
|
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
|
// 检查是否为host:port格式
|
||||||
|
if strings.Contains(host, ":") {
|
||||||
|
if h, portStr, err := net.SplitHostPort(host); err == nil {
|
||||||
|
// 验证端口号
|
||||||
|
if port, portErr := strconv.Atoi(portStr); portErr == nil && port >= MinPort && port <= MaxPort {
|
||||||
|
// 验证主机部分
|
||||||
|
if valid, hostErr := tp.validateHost(h); valid {
|
||||||
|
// 这是有效的host:port组合,添加到hostPorts
|
||||||
|
hostPorts = append(hostPorts, host)
|
||||||
|
continue
|
||||||
|
} else if hostErr != nil {
|
||||||
|
warnings = append(warnings, fmt.Sprintf("无效主机端口组合: %s - %s", host, hostErr.Error()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 作为普通主机验证
|
||||||
if valid, err := tp.validateHost(host); valid {
|
if valid, err := tp.validateHost(host); valid {
|
||||||
validHosts = append(validHosts, host)
|
validHosts = append(validHosts, host)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
warnings = append(warnings, fmt.Sprintf("无效主机: %s - %s", host, err.Error()))
|
warnings = append(warnings, fmt.Sprintf("无效主机: %s - %s", host, err.Error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将找到的hostPorts合并到输入结果中(通过修改input结构)
|
||||||
|
if len(hostPorts) > 0 {
|
||||||
|
input.HostPort = append(input.HostPort, hostPorts...)
|
||||||
|
}
|
||||||
|
|
||||||
// 检查目标数量限制
|
// 检查目标数量限制
|
||||||
if len(validHosts) > tp.options.MaxTargets {
|
if len(validHosts) > tp.options.MaxTargets {
|
||||||
@ -404,8 +429,26 @@ func (tp *TargetParser) parseHostList(hostStr string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
hosts = append(hosts, rangeHosts...)
|
hosts = append(hosts, rangeHosts...)
|
||||||
default:
|
default:
|
||||||
// 单个IP或域名
|
// 检查是否为host:port格式
|
||||||
hosts = append(hosts, item)
|
if strings.Contains(item, ":") {
|
||||||
|
if _, portStr, err := net.SplitHostPort(item); err == nil {
|
||||||
|
// 验证端口号
|
||||||
|
if port, portErr := strconv.Atoi(portStr); portErr == nil && port >= MinPort && port <= MaxPort {
|
||||||
|
// 这是有效的host:port格式,但在这里仍然作为主机处理
|
||||||
|
// 在后续的processHostPorts函数中会被正确处理
|
||||||
|
hosts = append(hosts, item)
|
||||||
|
} else {
|
||||||
|
// 端口无效,作为普通主机处理
|
||||||
|
hosts = append(hosts, item)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 不是有效的host:port格式,作为普通主机处理
|
||||||
|
hosts = append(hosts, item)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 单个IP或域名
|
||||||
|
hosts = append(hosts, item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,6 +738,19 @@ func (tp *TargetParser) validateHost(host string) (bool, error) {
|
|||||||
return false, fmt.Errorf("主机地址为空")
|
return false, fmt.Errorf("主机地址为空")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否为host:port格式
|
||||||
|
if strings.Contains(host, ":") {
|
||||||
|
// 可能是host:port格式,尝试分离
|
||||||
|
if h, portStr, err := net.SplitHostPort(host); err == nil {
|
||||||
|
// 验证端口号
|
||||||
|
if port, portErr := strconv.Atoi(portStr); portErr == nil && port >= MinPort && port <= MaxPort {
|
||||||
|
// 递归验证主机部分(不包含端口)
|
||||||
|
return tp.validateHost(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果不是有效的host:port格式,继续按普通主机地址处理
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否为IP地址
|
// 检查是否为IP地址
|
||||||
if ip := net.ParseIP(host); ip != nil {
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
return tp.validateIP(ip)
|
return tp.validateIP(ip)
|
||||||
|
@ -60,6 +60,15 @@ func (p *PortDiscoveryService) shouldPerformLivenessCheck(hosts []string) bool {
|
|||||||
func (p *PortDiscoveryService) discoverAlivePorts(hosts []string) []string {
|
func (p *PortDiscoveryService) discoverAlivePorts(hosts []string) []string {
|
||||||
var alivePorts []string
|
var alivePorts []string
|
||||||
|
|
||||||
|
// 如果已经有明确指定的host:port,则优先使用并跳过常规端口扫描
|
||||||
|
if len(common.HostPort) > 0 {
|
||||||
|
alivePorts = append(alivePorts, common.HostPort...)
|
||||||
|
alivePorts = common.RemoveDuplicate(alivePorts)
|
||||||
|
common.LogBase(i18n.GetText("scan_alive_ports_count", len(alivePorts)))
|
||||||
|
common.HostPort = nil
|
||||||
|
return alivePorts
|
||||||
|
}
|
||||||
|
|
||||||
// 根据扫描模式选择端口扫描方式
|
// 根据扫描模式选择端口扫描方式
|
||||||
if len(hosts) > 0 {
|
if len(hosts) > 0 {
|
||||||
alivePorts = EnhancedPortScan(hosts, common.Ports, common.Timeout)
|
alivePorts = EnhancedPortScan(hosts, common.Ports, common.Timeout)
|
||||||
@ -73,14 +82,6 @@ func (p *PortDiscoveryService) discoverAlivePorts(hosts []string) []string {
|
|||||||
common.LogBase(i18n.GetText("scan_alive_ports_count", len(alivePorts)))
|
common.LogBase(i18n.GetText("scan_alive_ports_count", len(alivePorts)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并额外指定的端口
|
|
||||||
if len(common.HostPort) > 0 {
|
|
||||||
alivePorts = append(alivePorts, common.HostPort...)
|
|
||||||
alivePorts = common.RemoveDuplicate(alivePorts)
|
|
||||||
common.HostPort = nil
|
|
||||||
common.LogBase(i18n.GetText("scan_alive_ports_count", len(alivePorts)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return alivePorts
|
return alivePorts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user