fix: 修复3个实测发现的问题

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 秒
This commit is contained in:
ZacharyZcR
2026-06-13 22:35:48 +08:00
parent 272b0e28c8
commit 8fb66e8e2f
4 changed files with 20 additions and 11 deletions
+7 -2
View File
@@ -129,9 +129,14 @@ func parseUsernames(fv *FlagVars) ([]string, error) {
func parsePasswords(fv *FlagVars) ([]string, error) { func parsePasswords(fv *FlagVars) ([]string, error) {
var passwords []string var passwords []string
// 命令行密码 // 命令行密码(支持逗号分隔多个值,保留空格作为密码的一部分)
if fv.Password != "" { 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)
}
}
} }
// 从文件读取 // 从文件读取
+3 -2
View File
@@ -9,7 +9,7 @@ import (
func TestParsePasswordsKeepsPrimaryPasswordLiteral(t *testing.T) { func TestParsePasswordsKeepsPrimaryPasswordLiteral(t *testing.T) {
fv := &FlagVars{ fv := &FlagVars{
Password: "root admin", Password: "root admin,pass0",
AddPasswords: "pass1 pass2,pass3\tpass4", AddPasswords: "pass1 pass2,pass3\tpass4",
} }
@@ -17,7 +17,8 @@ func TestParsePasswordsKeepsPrimaryPasswordLiteral(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("parsePasswords error = %v", err) 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) { if !reflect.DeepEqual(got, want) {
t.Fatalf("parsePasswords() = %#v, want %#v", got, want) t.Fatalf("parsePasswords() = %#v, want %#v", got, want)
} }
+4 -1
View File
@@ -186,7 +186,10 @@ func (s *ServiceScanStrategy) performHostScan(ctx context.Context, session *comm
ep.TuneConfig(config, session) 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) s.scanHostBatch(ctx, session, hosts, info, pluginsToRun, isCustomMode, ch, wg)
} }
+6 -6
View File
@@ -37,12 +37,7 @@ func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, session *
config := session.Config config := session.Config
target := info.Target() target := info.Target()
// 如果禁用暴力破解,只做服务识别 // 首先检查未授权访问(无论是否禁用爆破都要检测)
if config.DisableBrute {
return p.identifyService(ctx, info, session)
}
// 首先检查未授权访问
if result := p.testUnauthorizedAccess(ctx, info, session); result != nil && result.Success { if result := p.testUnauthorizedAccess(ctx, info, session); result != nil && result.Success {
session.LogVuln(i18n.Tr("redis_unauth_success", target)) //nolint:govet 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 return result
} }
// 禁用爆破时不继续密码测试
if config.DisableBrute {
return p.identifyService(ctx, info, session)
}
// 生成测试凭据 // 生成测试凭据
credentials := GenerateCredentials("redis", config) credentials := GenerateCredentials("redis", config)