fscan/plugins/services/vnc/plugin.go
ZacharyZcR 4a3f281b6b refactor: 统一Plugins目录大小写为小写
- 将所有Plugins路径重命名为plugins
- 修复Git索引与实际文件系统大小写不一致问题
- 确保跨平台兼容性和路径一致性
2025-08-12 13:08:06 +08:00

220 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}