package Plugins import ( "context" "fmt" "time" smbcommon "github.com/shadow1ng/fscan/plugins/legacy/smb/common" "github.com/shadow1ng/fscan/plugins/legacy/smb/smb2" "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/common/output" ) // SmbScan2 执行SMB2服务的认证扫描(重构版本) func SmbScan2(info *common.HostInfo) error { if common.DisableBrute { return nil } // 创建目标信息 target := &smbcommon.TargetInfo{ Host: info.Host, Port: 445, Domain: common.Domain, } // 设置全局超时上下文 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(common.GlobalTimeout)*time.Second) defer cancel() // 根据是否提供哈希选择认证模式 var credMgr smbcommon.CredentialManager if len(common.HashBytes) > 0 { credMgr = smbcommon.NewHashCredentialManager() common.LogDebug(fmt.Sprintf("开始SMB2哈希认证扫描 (总用户数: %d, 总哈希数: %d)", len(common.Userdict["smb"]), len(common.HashBytes))) } else { credMgr = smbcommon.NewPasswordCredentialManager() common.LogDebug(fmt.Sprintf("开始SMB2密码认证扫描 (总用户数: %d, 总密码数: %d)", len(common.Userdict["smb"]), len(common.Passwords))) } // 创建连接器和扫描器 connector := smb2.NewSmb2Connector() scanner := smbcommon.NewScanner() // 配置扫描参数 config := &smbcommon.ScanConfig{ MaxConcurrent: common.ModuleThreadNum, Timeout: time.Duration(common.Timeout) * time.Second, GlobalTimeout: time.Duration(common.GlobalTimeout) * time.Second, } // 执行扫描 result, err := scanner.Scan(ctx, target, connector, credMgr, config) if err != nil { return err } // 处理扫描结果 if result != nil && result.Success { logSuccessfulAuth(info, result.Credential, result.Shares) if len(result.Shares) > 0 { logShareInfo(info, result.Credential, result.Shares) } } return nil } // logSuccessfulAuth 记录成功的认证 func logSuccessfulAuth(info *common.HostInfo, cred smbcommon.Credential, shares []string) { credential := cred.Password if cred.IsHash && len(cred.Hash) > 0 { credential = common.HashValue } // 保存认证成功结果 result := &output.ScanResult{ Time: time.Now(), Type: output.TypeVuln, Target: info.Host, Status: "success", Details: map[string]interface{}{ "port": info.Ports, "service": "smb2", "username": cred.Username, "domain": common.Domain, "type": "weak-auth", "credential": credential, "auth_type": map[bool]string{true: "hash", false: "password"}[cred.IsHash], "shares": shares, }, } common.SaveResult(result) // 控制台输出 var msg string if common.Domain != "" { msg = fmt.Sprintf("SMB2认证成功 %s:%s %s\\%s", info.Host, info.Ports, common.Domain, cred.Username) } else { msg = fmt.Sprintf("SMB2认证成功 %s:%s %s", info.Host, info.Ports, cred.Username) } if cred.IsHash && len(cred.Hash) > 0 { msg += fmt.Sprintf(" Hash:%s", common.HashValue) } else { msg += fmt.Sprintf(" Pass:%s", cred.Password) } common.LogSuccess(msg) } // logShareInfo 记录SMB共享信息 func logShareInfo(info *common.HostInfo, cred smbcommon.Credential, shares []string) { credential := cred.Password if cred.IsHash && len(cred.Hash) > 0 { credential = common.HashValue } // 保存共享信息结果 result := &output.ScanResult{ Time: time.Now(), Type: output.TypeVuln, Target: info.Host, Status: "shares-found", Details: map[string]interface{}{ "port": info.Ports, "service": "smb2", "username": cred.Username, "domain": common.Domain, "shares": shares, "credential": credential, "auth_type": map[bool]string{true: "hash", false: "password"}[cred.IsHash], }, } common.SaveResult(result) // 控制台输出 var msg string if common.Domain != "" { msg = fmt.Sprintf("SMB2共享信息 %s:%s %s\\%s", info.Host, info.Ports, common.Domain, cred.Username) } else { msg = fmt.Sprintf("SMB2共享信息 %s:%s %s", info.Host, info.Ports, cred.Username) } if cred.IsHash && len(cred.Hash) > 0 { msg += fmt.Sprintf(" Hash:%s", common.HashValue) } else { msg += fmt.Sprintf(" Pass:%s", cred.Password) } msg += fmt.Sprintf(" 共享:%v", shares) common.LogBase(msg) }