From 235e2aee6096cce1c235e28f590a8a076f04267e Mon Sep 17 00:00:00 2001 From: ZacharyZcR <2903735704@qq.com> Date: Sat, 4 Jan 2025 17:00:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E4=BF=AE=E5=A4=8DSMB2=E7=9A=84=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E8=B7=B3=E5=87=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/Config.go | 2 ++ Common/Flag.go | 3 +++ Common/Parse.go | 24 +++++++++++++++++---- Core/Scanner.go | 56 ++++++++++++++++-------------------------------- Plugins/SMB.go | 3 +++ Plugins/SMB2.go | 11 ++++++++-- 6 files changed, 56 insertions(+), 43 deletions(-) diff --git a/Common/Config.go b/Common/Config.go index 00d54f9..6b39511 100644 --- a/Common/Config.go +++ b/Common/Config.go @@ -901,6 +901,8 @@ var ( HttpProxy string // 原Proxy Socks5Proxy string + LocalMode bool // -local 本地模式 + // POC配置 PocPath string Pocinfo PocInfo diff --git a/Common/Flag.go b/Common/Flag.go index a3ef824..1557e12 100644 --- a/Common/Flag.go +++ b/Common/Flag.go @@ -215,6 +215,9 @@ func Flag(Info *HostInfo) { flag.StringVar(&HttpProxy, "proxy", "", "设置HTTP代理服务器") flag.StringVar(&Socks5Proxy, "socks5", "", "设置Socks5代理(用于TCP连接,将影响超时设置)") + // 本地扫描配置 + flag.BoolVar(&LocalMode, "local", false, "启用本地信息收集模式") + // POC配置 flag.StringVar(&PocPath, "pocpath", "", "指定自定义POC文件路径") flag.StringVar(&Pocinfo.PocName, "pocname", "", "指定要使用的POC名称,如: -pocname weblogic") diff --git a/Common/Parse.go b/Common/Parse.go index c26def7..7f3ba70 100644 --- a/Common/Parse.go +++ b/Common/Parse.go @@ -3,6 +3,7 @@ package Common import ( "bufio" "encoding/hex" + "flag" "fmt" "net/url" "os" @@ -204,12 +205,27 @@ func Readfile(filename string) ([]string, error) { // ParseInput 解析和验证输入参数配置 func ParseInput(Info *HostInfo) error { - // 所有目标参数为空时表示本地扫描模式 - if Info.Host == "" && HostsFile == "" && TargetURL == "" && URLsFile == "" { - LogInfo("未指定扫描目标,将以本地模式运行") + // 检查互斥的扫描模式 + modes := 0 + if Info.Host != "" || HostsFile != "" { + modes++ + } + if TargetURL != "" || URLsFile != "" { + modes++ + } + if LocalMode { + modes++ } - // 配置基本参数 + if modes == 0 { + // 无参数时显示帮助 + flag.Usage() + return fmt.Errorf("请指定扫描参数") + } else if modes > 1 { + return fmt.Errorf("参数 -h、-u、-local 不能同时使用") + } + + // 处理爆破线程配置 if BruteThreads <= 0 { BruteThreads = 1 LogInfo(fmt.Sprintf("暴力破解线程数: %d", BruteThreads)) diff --git a/Core/Scanner.go b/Core/Scanner.go index ce6f382..69e6131 100644 --- a/Core/Scanner.go +++ b/Core/Scanner.go @@ -26,64 +26,46 @@ func Scan(info Common.HostInfo) { // 初始化HTTP客户端 lib.Inithttp() - // 处理特殊情况 - if info.Host == "" && len(Common.URLs) == 0 { - // Host为空且没有URLs,设置Local模式 - LocalScan = true - Common.ScanMode = Common.ModeLocal - Common.LogInfo("未检测到目标,自动切换为本地扫描模式") - } else if len(Common.URLs) > 0 { - // 存在URLs时设置为Web模式 - WebScan = true - Common.ScanMode = Common.ModeWeb - Common.LogInfo("检测到URL列表,自动切换为Web扫描模式") - } - - Common.ParseScanMode(Common.ScanMode) - ch := make(chan struct{}, Common.ThreadNum) wg := sync.WaitGroup{} - // 本地信息收集模式 - if LocalScan { + // 根据不同模式执行扫描 + switch { + case Common.LocalMode: + // 本地信息收集模式 + Common.LogInfo("执行本地信息收集") executeScans([]Common.HostInfo{info}, &ch, &wg) - finishScan(&wg) - return - } - // Web模式直接处理URLs - if WebScan { + case len(Common.URLs) > 0: + // Web模式 var targetInfos []Common.HostInfo for _, url := range Common.URLs { urlInfo := info - // 确保URL包含协议前缀 if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { url = "http://" + url } urlInfo.Url = url targetInfos = append(targetInfos, urlInfo) } - if len(targetInfos) > 0 { - Common.LogInfo("开始Web扫描") - executeScans(targetInfos, &ch, &wg) - finishScan(&wg) - } - return - } + Common.LogInfo("开始Web扫描") + executeScans(targetInfos, &ch, &wg) - // 常规模式:初始化并解析目标 - var hosts []string - var err error - if info.Host != "" { - hosts, err = Common.ParseIP(info.Host, Common.HostsFile, Common.ExcludeHosts) + default: + // 主机扫描模式 + if info.Host == "" { + Common.LogError("未指定扫描目标") + return + } + + hosts, err := Common.ParseIP(info.Host, Common.HostsFile, Common.ExcludeHosts) if err != nil { Common.LogError(fmt.Sprintf("解析主机错误: %v", err)) return } + Common.LogInfo("开始主机扫描") + executeScan(hosts, info, &ch, &wg) } - // 执行目标扫描 - executeScan(hosts, info, &ch, &wg) finishScan(&wg) } diff --git a/Plugins/SMB.go b/Plugins/SMB.go index 54fcba5..e10ad21 100644 --- a/Plugins/SMB.go +++ b/Plugins/SMB.go @@ -68,6 +68,9 @@ func SmblConn(info *Common.HostInfo, user string, pass string, signal chan struc return false, fmt.Errorf("认证失败") } + // 添加 debug 输出原始错误信息 + Common.LogDebug(fmt.Sprintf("SMB original error: %v", err)) + // 清理错误信息中的换行符和多余空格 errMsg := strings.TrimSpace(strings.ReplaceAll(err.Error(), "\n", " ")) if strings.Contains(errMsg, "NT Status Error") { diff --git a/Plugins/SMB2.go b/Plugins/SMB2.go index 3cd6189..4c0f576 100644 --- a/Plugins/SMB2.go +++ b/Plugins/SMB2.go @@ -35,8 +35,14 @@ func smbPasswordScan(info *Common.HostInfo) error { // 遍历每个用户 for _, user := range Common.Userdict["smb"] { + accountLocked := false // 添加账户锁定标志 + // 遍历该用户的所有密码 for _, pass := range Common.Passwords { + if accountLocked { // 如果账户被锁定,跳过剩余密码 + break + } + pass = strings.ReplaceAll(pass, "{user}", user) // 重试循环 @@ -56,8 +62,9 @@ func smbPasswordScan(info *Common.HostInfo) error { logFailedAuth(info, user, pass, []byte{}, err) // 检查是否账户锁定 - if strings.Contains(err.Error(), "user account has been automatically locked") { - // 账户锁定,跳过该用户的剩余密码 + if strings.Contains(err.Error(), "account has been automatically locked") || + strings.Contains(err.Error(), "account has been locked") { + accountLocked = true // 设置锁定标志 break }