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