fscan/Plugins/services/vnc/connector.go
ZacharyZcR 6fda09f183 feat: 实现VNC远程桌面协议专业扫描插件
- 新增VNC服务连接器,支持mitchellh/go-vnc库
- 实现基于密码的VNC认证机制
- 支持VNC常用端口(5900-5903)扫描
- 集成弱密码检测功能
- 添加VNC服务识别能力
- 配置Docker测试环境
- 更新插件注册表和国际化消息

测试验证: ✓ VNC弱密码检测正常工作
2025-08-09 16:02:05 +08:00

111 lines
2.4 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"
"net"
"time"
"github.com/mitchellh/go-vnc"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/common/i18n"
"github.com/shadow1ng/fscan/plugins/base"
)
// VNCConnector VNC服务连接器
type VNCConnector struct{}
// NewVNCConnector 创建新的VNC连接器
func NewVNCConnector() *VNCConnector {
return &VNCConnector{}
}
// Connect 连接到VNC服务
func (c *VNCConnector) Connect(ctx context.Context, info *common.HostInfo) (interface{}, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
timeout := time.Duration(common.Timeout) * time.Second
// 使用带上下文的TCP连接
conn, err := common.WrapperTcpWithTimeout("tcp", target, timeout)
if err != nil {
return nil, fmt.Errorf(i18n.GetText("vnc_connection_failed"), err)
}
// 设置读写超时
if err := conn.SetDeadline(time.Now().Add(timeout)); err != nil {
conn.Close()
return nil, fmt.Errorf("failed to set connection deadline: %v", err)
}
return conn, nil
}
// Authenticate 认证VNC服务
func (c *VNCConnector) Authenticate(ctx context.Context, conn interface{}, cred *base.Credential) error {
netConn, ok := conn.(net.Conn)
if !ok {
return fmt.Errorf("invalid connection type")
}
// 检查上下文是否已取消
select {
case <-ctx.Done():
return ctx.Err()
default:
}
// VNC只使用密码认证忽略用户名
password := cred.Password
if password == "" && cred.Username != "" {
// 如果密码为空但用户名不为空,尝试使用用户名作为密码
password = cred.Username
}
// 创建完成通道
doneChan := make(chan error, 1)
// 在协程中处理VNC认证
go func() {
// 配置VNC客户端
config := &vnc.ClientConfig{
Auth: []vnc.ClientAuth{
&vnc.PasswordAuth{
Password: password,
},
},
}
// 尝试VNC认证
client, err := vnc.Client(netConn, config)
if err != nil {
select {
case <-ctx.Done():
case doneChan <- err:
}
return
}
// 认证成功,立即关闭客户端
client.Close()
select {
case <-ctx.Done():
case doneChan <- nil:
}
}()
// 等待认证结果或上下文取消
select {
case err := <-doneChan:
return err
case <-ctx.Done():
return ctx.Err()
}
}
// Close 关闭连接
func (c *VNCConnector) Close(conn interface{}) error {
if closer, ok := conn.(interface{ Close() error }); ok && closer != nil {
return closer.Close()
}
return nil
}