package vnc import ( "context" "fmt" "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/common/i18n" "github.com/shadow1ng/fscan/plugins/base" ) // VNCPlugin VNC插件 type VNCPlugin struct { *base.ServicePlugin connector *VNCConnector exploiter *VNCExploiter } // NewVNCPlugin 创建VNC插件 func NewVNCPlugin() *VNCPlugin { metadata := &base.PluginMetadata{ Name: "vnc", Version: "1.0.0", Author: "fscan-team", Description: "VNC远程桌面协议检测和利用插件", Category: "service", Tags: []string{"vnc", "remote-desktop", "service", "unauth"}, Protocols: []string{"vnc"}, Ports: []int{5900, 5901, 5902, 5903, 5904, 5905, 5906, 5907, 5908, 5909}, } connector := NewVNCConnector() exploiter := NewVNCExploiter() plugin := &VNCPlugin{ ServicePlugin: base.NewServicePlugin(metadata, connector), connector: connector, exploiter: exploiter, } return plugin } // Scan 执行VNC扫描 func (p *VNCPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { target := fmt.Sprintf("%s:%s", info.Host, info.Ports) common.LogDebug(i18n.GetText("plugin_scan_start", "VNC", target)) // 1. 尝试连接VNC服务 conn, err := p.connector.Connect(ctx, info) if err != nil { return &base.ScanResult{ Success: false, Service: "VNC", Banner: "", Error: fmt.Errorf("VNC服务不可访问: %v", err), }, nil } connectionInfo := conn.(map[string]interface{}) version := connectionInfo["version"].(string) // 2. 尝试获取默认凭据 defaultCreds := p.connector.GetDefaultCredentials() var successCreds *base.Credential var authResults []string // 3. 尝试认证 for _, cred := range defaultCreds { err := p.connector.Authenticate(ctx, conn, cred) if err == nil { successCreds = cred if cred.Password == "" { authResults = append(authResults, "无认证访问") } else { authResults = append(authResults, fmt.Sprintf("弱密码: %s", cred.Password)) } break } else { common.LogDebug(fmt.Sprintf("VNC认证失败 [%s]: %v", cred.Password, err)) } } // 4. 构建扫描结果 result := &base.ScanResult{ Success: true, Service: "VNC", Banner: fmt.Sprintf("VNC服务 %s", version), Extra: map[string]interface{}{ "version": version, "port": info.Ports, "target": target, "auth_tested": len(defaultCreds), }, } if successCreds != nil { result.Extra["vulnerable"] = true result.Extra["credentials"] = map[string]string{ "username": successCreds.Username, "password": successCreds.Password, } result.Extra["auth_result"] = authResults[0] // 执行自动利用 p.autoExploit(ctx, info, successCreds) } else { result.Extra["vulnerable"] = false result.Extra["auth_result"] = "认证失败" } common.LogSuccess(i18n.GetText("plugin_scan_complete", "VNC", target)) return result, nil } // autoExploit 自动利用功能 func (p *VNCPlugin) autoExploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) { target := fmt.Sprintf("%s:%s", info.Host, info.Ports) common.LogDebug(i18n.GetText("plugin_exploit_start", "VNC", target)) // 执行利用操作 result, err := p.exploiter.Exploit(ctx, info, creds) if err != nil { common.LogError(i18n.GetText("plugin_exploit_failed", "VNC", err)) return } if result.Success { common.LogSuccess(i18n.GetText("plugin_exploit_success", "VNC", target)) // 输出利用结果 if result.Data != nil { if accessType, exists := result.Data["access_type"]; exists { common.LogInfo(fmt.Sprintf("VNC访问类型: %s", accessType)) } if version, exists := result.Data["version"]; exists { common.LogInfo(fmt.Sprintf("VNC版本: %s", version)) } if riskLevel, exists := result.Data["risk_level"]; exists { common.LogInfo(fmt.Sprintf("风险等级: %s", riskLevel)) } } } else { common.LogError(fmt.Sprintf("VNC利用失败: %v", result.Error)) } } // Exploit 使用exploiter执行利用 func (p *VNCPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { return p.exploiter.Exploit(ctx, info, creds) } // IsExploitSupported 检查是否支持指定的利用方法 func (p *VNCPlugin) IsExploitSupported(method base.ExploitType) bool { return p.exploiter.IsExploitSupported(method) } // performServiceIdentification 执行VNC服务识别(-nobr模式) func (p *VNCPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { // 尝试连接到VNC服务进行识别 conn, err := p.connector.Connect(ctx, info) if err != nil { return &base.ScanResult{ Success: false, Service: "Unknown", Banner: "", Error: fmt.Errorf("服务不可访问"), }, nil } connectionInfo := conn.(map[string]interface{}) version := connectionInfo["version"].(string) return &base.ScanResult{ Success: true, Service: "VNC", Banner: fmt.Sprintf("VNC服务 %s", version), Extra: map[string]interface{}{ "version": version, "identified": true, "protocol": "VNC", }, }, nil } // RegisterVNCPlugin 注册VNC插件 func RegisterVNCPlugin() { factory := base.NewSimplePluginFactory( &base.PluginMetadata{ Name: "vnc", Version: "1.0.0", Author: "fscan-team", Description: "VNC远程桌面协议检测和利用插件", Category: "service", Tags: []string{"vnc", "remote-desktop", "service", "unauth"}, Protocols: []string{"vnc"}, Ports: []int{5900, 5901, 5902, 5903, 5904, 5905, 5906, 5907, 5908, 5909}, }, func() base.Plugin { return NewVNCPlugin() }, ) base.GlobalPluginRegistry.Register("vnc", factory) } // GetInfo 获取插件信息 func (p *VNCPlugin) GetInfo() string { return fmt.Sprintf(`VNC远程桌面协议插件 支持端口: %v 功能: 服务识别、无认证检测、弱密码检测 作者: fscan-team 版本: 1.0.0`, p.GetMetadata().Ports) } // 插件注册函数 func init() { RegisterVNCPlugin() }