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] // VNC插件不提供利用功能,仅进行服务识别和弱密码检测 if successCreds.Password == "" { common.LogSuccess(i18n.GetText("vnc_unauth_success", fmt.Sprintf("%s:%s", info.Host, info.Ports))) } else { common.LogSuccess(i18n.GetText("vnc_weak_pwd_success", fmt.Sprintf("%s:%s", info.Host, info.Ports), successCreds.Password)) } } else { result.Extra["vulnerable"] = false result.Extra["auth_result"] = "认证失败" } common.LogSuccess(i18n.GetText("plugin_scan_complete", "VNC", target)) return result, nil } // autoExploit方法已移除 - VNC插件不提供利用功能 // 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) } // GetExploitMethods 获取利用方法 func (p *VNCPlugin) GetExploitMethods() []base.ExploitMethod { return p.exploiter.GetExploitMethods() } // IsExploitSupported 检查利用支持 func (p *VNCPlugin) IsExploitSupported(method base.ExploitType) bool { return p.exploiter.IsExploitSupported(method) } // 已移除未使用的 performServiceIdentification 方法 // 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) } // 插件注册函数 func init() { RegisterVNCPlugin() }