From 626d8f79bb1cbbb33b3f04af3d276c82027c7e34 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Sat, 13 Jun 2026 22:35:48 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D3=E4=B8=AA=E5=AE=9E?= =?UTF-8?q?=E6=B5=8B=E5=8F=91=E7=8E=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. -pwd 支持逗号分隔多个密码 之前 -pwd "123,456,root" 被当作单个密码,SSH root:123 无法匹配 现在逗号分隔为独立密码,空格保留(可能是密码的一部分) 2. -nobr 禁用爆破时仍检测 Redis 未授权访问 未授权访问是服务探测不是爆破,不应被 -nobr 跳过 将未授权检测移到 DisableBrute 判断之前 3. 指定端口时跳过 UDP 插件调度 -p 80 只扫 HTTP 时不需要 SNMP/BACnet/DNS 等 UDP 探测 仅在默认端口扫描时才分发 UDP 插件 效果: -p 80 从 9 秒降到 3 秒 --- common/config_builder.go | 9 +++++++-- common/config_builder_test.go | 5 +++-- core/service_scanner.go | 5 ++++- plugins/services/redis.go | 12 ++++++------ 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/common/config_builder.go b/common/config_builder.go index 26ce43b..97e6a94 100644 --- a/common/config_builder.go +++ b/common/config_builder.go @@ -129,9 +129,14 @@ func parseUsernames(fv *FlagVars) ([]string, error) { func parsePasswords(fv *FlagVars) ([]string, error) { var passwords []string - // 命令行密码 + // 命令行密码(支持逗号分隔多个值,保留空格作为密码的一部分) if fv.Password != "" { - passwords = append(passwords, fv.Password) + for _, p := range strings.Split(fv.Password, ",") { + p = strings.TrimSpace(p) + if p != "" { + passwords = append(passwords, p) + } + } } // 从文件读取 diff --git a/common/config_builder_test.go b/common/config_builder_test.go index a90186c..729b3d9 100644 --- a/common/config_builder_test.go +++ b/common/config_builder_test.go @@ -9,7 +9,7 @@ import ( func TestParsePasswordsKeepsPrimaryPasswordLiteral(t *testing.T) { fv := &FlagVars{ - Password: "root admin", + Password: "root admin,pass0", AddPasswords: "pass1 pass2,pass3\tpass4", } @@ -17,7 +17,8 @@ func TestParsePasswordsKeepsPrimaryPasswordLiteral(t *testing.T) { if err != nil { t.Fatalf("parsePasswords error = %v", err) } - want := []string{"root admin", "pass1", "pass2", "pass3", "pass4"} + // -pwd 逗号分隔,空格保留;-pwda 逗号/空格/tab 分隔 + want := []string{"root admin", "pass0", "pass1", "pass2", "pass3", "pass4"} if !reflect.DeepEqual(got, want) { t.Fatalf("parsePasswords() = %#v, want %#v", got, want) } diff --git a/core/service_scanner.go b/core/service_scanner.go index d683590..460dc2e 100644 --- a/core/service_scanner.go +++ b/core/service_scanner.go @@ -186,7 +186,10 @@ func (s *ServiceScanStrategy) performHostScan(ctx context.Context, session *comm ep.TuneConfig(config, session) } - s.dispatchUDPPlugins(ctx, session, hosts, info, config, ch, wg) + // 仅在默认端口扫描时调度 UDP 插件(用户指定 -p 时跳过,避免不相关的 UDP 探测拖慢扫描) + if config.Target.Ports == "" || config.Target.Ports == "all" { + s.dispatchUDPPlugins(ctx, session, hosts, info, config, ch, wg) + } s.scanHostBatch(ctx, session, hosts, info, pluginsToRun, isCustomMode, ch, wg) } diff --git a/plugins/services/redis.go b/plugins/services/redis.go index 9836621..8cd0035 100644 --- a/plugins/services/redis.go +++ b/plugins/services/redis.go @@ -37,12 +37,7 @@ func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, session * config := session.Config target := info.Target() - // 如果禁用暴力破解,只做服务识别 - if config.DisableBrute { - return p.identifyService(ctx, info, session) - } - - // 首先检查未授权访问 + // 首先检查未授权访问(无论是否禁用爆破都要检测) if result := p.testUnauthorizedAccess(ctx, info, session); result != nil && result.Success { session.LogVuln(i18n.Tr("redis_unauth_success", target)) //nolint:govet @@ -53,6 +48,11 @@ func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, session * return result } + // 禁用爆破时不继续密码测试 + if config.DisableBrute { + return p.identifyService(ctx, info, session) + } + // 生成测试凭据 credentials := GenerateCredentials("redis", config)