From cc4f55374a429a25142b2e76b4fb4a3bcc9f4194 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Tue, 12 Aug 2025 17:03:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DWeb=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复URL正则表达式支持IP地址格式 - 修复URL解析后正确设置到HostInfo.Url字段 - 修复Web扫描目标Host和Port字段的提取 - 修复Web插件适用性检查逻辑,允许Web扫描策略直接执行Web插件 - 完善URL到目标信息的转换,包含协议默认端口处理 --- Common/Parse.go | 4 +++ Common/parsers/constants.go | 2 +- core/BaseScanStrategy.go | 7 ++++- core/WebScanner.go | 55 ++++++++++++++++++++++++++++++++----- 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Common/Parse.go b/Common/Parse.go index eeb104f..ad8d2e3 100644 --- a/Common/Parse.go +++ b/Common/Parse.go @@ -272,6 +272,10 @@ func updateGlobalVariables(config *parsers.ParsedConfig, info *HostInfo) error { if len(config.Targets.URLs) > 0 { URLs = config.Targets.URLs + // 如果info.Url为空且只有一个URL,将其设置到info.Url + if info.Url == "" && len(config.Targets.URLs) == 1 { + info.Url = config.Targets.URLs[0] + } } if len(config.Targets.Ports) > 0 { diff --git a/Common/parsers/constants.go b/Common/parsers/constants.go index b99b172..42f1e4a 100644 --- a/Common/parsers/constants.go +++ b/Common/parsers/constants.go @@ -140,7 +140,7 @@ const ( // 正则表达式模式 IPv4RegexPattern = `^(\d{1,3}\.){3}\d{1,3}$` PortRangeRegexPattern = `^(\d+)(-(\d+))?$` - URLValidationRegexPattern = `^https?://[^\s/$.?#].[^\s]*$` + URLValidationRegexPattern = `^https?://[^\s]+$` DomainRegexPattern = `^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$` CookieRegexPattern = `^[^=;\s]+(=[^;\s]*)?(\s*;\s*[^=;\s]+(=[^;\s]*)?)*$` diff --git a/core/BaseScanStrategy.go b/core/BaseScanStrategy.go index 96d534b..f5183c9 100644 --- a/core/BaseScanStrategy.go +++ b/core/BaseScanStrategy.go @@ -164,8 +164,13 @@ func (b *BaseScanStrategy) IsPluginApplicableByName(pluginName string, targetHos return false } - // 对于Web插件,即使没有端口限制,也必须通过智能检测才能执行 + // 对于Web插件的特殊处理 if metadata.Category == "web" { + // Web扫描策略下直接允许Web插件执行(用户明确指定了Web目标) + if b.filterType == FilterWeb { + return true + } + // 其他策略下必须通过智能检测才能执行 return false } diff --git a/core/WebScanner.go b/core/WebScanner.go index 97f9932..dc0faef 100644 --- a/core/WebScanner.go +++ b/core/WebScanner.go @@ -1,6 +1,8 @@ package core import ( + "fmt" + "net/url" "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/common/i18n" "strings" @@ -54,16 +56,55 @@ func (s *WebScanStrategy) Execute(info common.HostInfo, ch *chan struct{}, wg *s func (s *WebScanStrategy) PrepareTargets(baseInfo common.HostInfo) []common.HostInfo { var targetInfos []common.HostInfo - for _, url := range common.URLs { - urlInfo := baseInfo - // 确保URL包含协议头 - if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { - url = "http://" + url + // 首先从common.URLs获取目标 + for _, urlStr := range common.URLs { + urlInfo := s.createTargetFromURL(baseInfo, urlStr) + if urlInfo != nil { + targetInfos = append(targetInfos, *urlInfo) + } + } + + // 如果common.URLs为空但baseInfo.Url有值,使用baseInfo.Url + if len(targetInfos) == 0 && baseInfo.Url != "" { + urlInfo := s.createTargetFromURL(baseInfo, baseInfo.Url) + if urlInfo != nil { + targetInfos = append(targetInfos, *urlInfo) } - urlInfo.Url = url - targetInfos = append(targetInfos, urlInfo) } return targetInfos } +// createTargetFromURL 从URL创建目标信息 +func (s *WebScanStrategy) createTargetFromURL(baseInfo common.HostInfo, urlStr string) *common.HostInfo { + // 确保URL包含协议头 + if !strings.HasPrefix(urlStr, "http://") && !strings.HasPrefix(urlStr, "https://") { + urlStr = "http://" + urlStr + } + + // 解析URL获取Host和Port信息 + parsedURL, err := url.Parse(urlStr) + if err != nil { + common.LogError(fmt.Sprintf("解析URL失败: %s - %v", urlStr, err)) + return nil + } + + urlInfo := baseInfo + urlInfo.Url = urlStr + urlInfo.Host = parsedURL.Hostname() + + // 设置端口 + port := parsedURL.Port() + if port == "" { + // 根据协议设置默认端口 + if parsedURL.Scheme == "https" { + port = "443" + } else { + port = "80" + } + } + urlInfo.Ports = port + + return &urlInfo +} +