refactor(grdp): 精简RDP库,删除认证检测不需要的代码

- 删除 VNC 协议支持 (protocol/rfb, client/rfb.go)
- 删除完整客户端框架 (client/)
- 删除 RemoteApp 等插件 (plugin/)
- 删除 RLE 图形解压 (core/rle.go)
- 删除绘图指令处理 (pdu/orders.go, pdu/gdi.go)
- 精简 screen.go,移除截图和完整会话功能
- 移除未使用的 RGB 转换函数

grdp 代码从 13,044 行精简至 7,581 行,削减 42%
This commit is contained in:
ZacharyZcR
2026-01-21 20:54:28 +08:00
parent 849c28ede2
commit 26cf7dbb37
16 changed files with 5 additions and 5468 deletions
-174
View File
@@ -1,174 +0,0 @@
// client.go
package client
import (
"log"
"os"
"github.com/shadow1ng/fscan/mylib/grdp/glog"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/pdu"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/rfb"
)
const (
CLIP_OFF = 0
CLIP_IN = 0x1
CLIP_OUT = 0x2
)
const (
TC_RDP = 0
TC_VNC = 1
)
type Control interface {
Login(host, user, passwd string, width, height int) error
KeyUp(sc int, name string)
KeyDown(sc int, name string)
MouseMove(x, y int)
MouseWheel(scroll, x, y int)
MouseUp(button int, x, y int)
MouseDown(button int, x, y int)
On(event string, msg interface{})
Close()
}
func init() {
glog.SetLevel(glog.INFO)
logger := log.New(os.Stdout, "", 0)
glog.SetLogger(logger)
}
type Client struct {
host string
user string
passwd string
ctl Control
tc int
setting *Setting
}
func NewClient(host, user, passwd string, t int, s *Setting) *Client {
if s == nil {
s = NewSetting()
}
c := &Client{
host: host,
user: user,
passwd: passwd,
tc: t,
setting: s,
}
switch t {
case TC_VNC:
c.ctl = newVncClient(s)
default:
c.ctl = newRdpClient(s)
}
s.SetLogLevel()
return c
}
func (c *Client) Login() error {
return c.ctl.Login(c.host, c.user, c.passwd, c.setting.Width, c.setting.Height)
}
func (c *Client) KeyUp(sc int, name string) {
c.ctl.KeyUp(sc, name)
}
func (c *Client) KeyDown(sc int, name string) {
c.ctl.KeyDown(sc, name)
}
func (c *Client) MouseMove(x, y int) {
c.ctl.MouseMove(x, y)
}
func (c *Client) MouseWheel(scroll, x, y int) {
c.ctl.MouseWheel(scroll, x, y)
}
func (c *Client) MouseUp(button, x, y int) {
c.ctl.MouseUp(button, x, y)
}
func (c *Client) MouseDown(button, x, y int) {
c.ctl.MouseDown(button, x, y)
}
func (c *Client) OnError(f func(e error)) {
c.ctl.On("error", f)
}
func (c *Client) OnClose(f func()) {
c.ctl.On("close", f)
}
func (c *Client) OnSuccess(f func()) {
c.ctl.On("success", f)
}
func (c *Client) OnReady(f func()) {
c.ctl.On("ready", f)
}
func (c *Client) OnBitmap(f func([]Bitmap)) {
f1 := func(data interface{}) {
bs := make([]Bitmap, 0, 50)
if c.tc == TC_VNC {
br := data.(*rfb.BitRect)
for _, v := range br.Rects {
b := Bitmap{int(v.Rect.X), int(v.Rect.Y), int(v.Rect.X + v.Rect.Width), int(v.Rect.Y + v.Rect.Height),
int(v.Rect.Width), int(v.Rect.Height),
Bpp(uint16(br.Pf.BitsPerPixel)), false, v.Data}
bs = append(bs, b)
}
} else {
for _, v := range data.([]pdu.BitmapData) {
IsCompress := v.IsCompress()
stream := v.BitmapDataStream
if IsCompress {
stream = bitmapDecompress(&v)
IsCompress = false
}
b := Bitmap{int(v.DestLeft), int(v.DestTop), int(v.DestRight), int(v.DestBottom),
int(v.Width), int(v.Height), Bpp(v.BitsPerPixel), IsCompress, stream}
bs = append(bs, b)
}
}
f(bs)
}
c.ctl.On("bitmap", f1)
}
type Bitmap struct {
DestLeft int `json:"destLeft"`
DestTop int `json:"destTop"`
DestRight int `json:"destRight"`
DestBottom int `json:"destBottom"`
Width int `json:"width"`
Height int `json:"height"`
BitsPerPixel int `json:"bitsPerPixel"`
IsCompress bool `json:"isCompress"`
Data []byte `json:"data"`
}
func Bpp(bp uint16) int {
return int(bp / 8)
}
type Setting struct {
Width int
Height int
Protocol string
LogLevel glog.LEVEL
}
func NewSetting() *Setting {
return &Setting{
Width: 1024,
Height: 768,
LogLevel: glog.INFO,
}
}
func (s *Setting) SetLogLevel() {
glog.SetLevel(s.LogLevel)
}
func (s *Setting) SetRequestedProtocol(p uint32) {}
func (s *Setting) SetClipboard(c int) {}
-156
View File
@@ -1,156 +0,0 @@
package client
import (
"fmt"
"net"
"strings"
"time"
"github.com/shadow1ng/fscan/mylib/grdp/core"
"github.com/shadow1ng/fscan/mylib/grdp/plugin"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/nla"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/pdu"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/sec"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/t125"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/tpkt"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/x224"
)
type RdpClient struct {
tpkt *tpkt.TPKT
x224 *x224.X224
mcs *t125.MCSClient
sec *sec.Client
pdu *pdu.Client
channels *plugin.Channels
}
func newRdpClient(s *Setting) *RdpClient {
return &RdpClient{}
}
func bitmapDecompress(bitmap *pdu.BitmapData) []byte {
return core.Decompress(bitmap.BitmapDataStream, int(bitmap.Width), int(bitmap.Height), Bpp(bitmap.BitsPerPixel))
}
func split(user string) (domain string, uname string) {
if strings.Index(user, "\\") != -1 {
t := strings.Split(user, "\\")
domain = t[0]
uname = t[len(t)-1]
} else if strings.Index(user, "/") != -1 {
t := strings.Split(user, "/")
domain = t[0]
uname = t[len(t)-1]
} else {
uname = user
}
return
}
func (c *RdpClient) Login(host, user, pwd string, width, height int) error {
conn, err := net.DialTimeout("tcp", host, 3*time.Second)
if err != nil {
return fmt.Errorf("[dial err] %v", err)
}
domain, user := split(user)
c.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd))
c.x224 = x224.New(c.tpkt)
c.mcs = t125.NewMCSClient(c.x224)
c.sec = sec.NewClient(c.mcs)
c.pdu = pdu.NewClient(c.sec)
c.channels = plugin.NewChannels(c.sec)
//c.mcs.SetClientDesktop(uint16(width), uint16(height))
c.sec.SetUser(user)
c.sec.SetPwd(pwd)
c.sec.SetDomain(domain)
c.tpkt.SetFastPathListener(c.sec)
c.sec.SetFastPathListener(c.pdu)
c.sec.SetChannelSender(c.mcs)
c.channels.SetChannelSender(c.sec)
//c.x224.SetRequestedProtocol(x224.PROTOCOL_RDP)
//c.x224.SetRequestedProtocol(x224.PROTOCOL_SSL)
err = c.x224.Connect()
if err != nil {
return fmt.Errorf("[x224 connect err] %v", err)
}
return nil
}
func (c *RdpClient) On(event string, f interface{}) {
c.pdu.On(event, f)
}
func (c *RdpClient) KeyUp(sc int, name string) {
p := &pdu.ScancodeKeyEvent{}
p.KeyCode = uint16(sc)
p.KeyboardFlags |= pdu.KBDFLAGS_RELEASE
c.pdu.SendInputEvents(pdu.INPUT_EVENT_SCANCODE, []pdu.InputEventsInterface{p})
}
func (c *RdpClient) KeyDown(sc int, name string) {
p := &pdu.ScancodeKeyEvent{}
p.KeyCode = uint16(sc)
c.pdu.SendInputEvents(pdu.INPUT_EVENT_SCANCODE, []pdu.InputEventsInterface{p})
}
func (c *RdpClient) MouseMove(x, y int) {
p := &pdu.PointerEvent{}
p.PointerFlags |= pdu.PTRFLAGS_MOVE
p.XPos = uint16(x)
p.YPos = uint16(y)
c.pdu.SendInputEvents(pdu.INPUT_EVENT_MOUSE, []pdu.InputEventsInterface{p})
}
func (c *RdpClient) MouseWheel(scroll, x, y int) {
p := &pdu.PointerEvent{}
p.PointerFlags |= pdu.PTRFLAGS_WHEEL
p.XPos = uint16(x)
p.YPos = uint16(y)
c.pdu.SendInputEvents(pdu.INPUT_EVENT_SCANCODE, []pdu.InputEventsInterface{p})
}
func (c *RdpClient) MouseUp(button int, x, y int) {
p := &pdu.PointerEvent{}
switch button {
case 0:
p.PointerFlags |= pdu.PTRFLAGS_BUTTON1
case 2:
p.PointerFlags |= pdu.PTRFLAGS_BUTTON2
case 1:
p.PointerFlags |= pdu.PTRFLAGS_BUTTON3
default:
p.PointerFlags |= pdu.PTRFLAGS_MOVE
}
p.XPos = uint16(x)
p.YPos = uint16(y)
c.pdu.SendInputEvents(pdu.INPUT_EVENT_MOUSE, []pdu.InputEventsInterface{p})
}
func (c *RdpClient) MouseDown(button int, x, y int) {
p := &pdu.PointerEvent{}
p.PointerFlags |= pdu.PTRFLAGS_DOWN
switch button {
case 0:
p.PointerFlags |= pdu.PTRFLAGS_BUTTON1
case 2:
p.PointerFlags |= pdu.PTRFLAGS_BUTTON2
case 1:
p.PointerFlags |= pdu.PTRFLAGS_BUTTON3
default:
p.PointerFlags |= pdu.PTRFLAGS_MOVE
}
p.XPos = uint16(x)
p.YPos = uint16(y)
c.pdu.SendInputEvents(pdu.INPUT_EVENT_MOUSE, []pdu.InputEventsInterface{p})
}
func (c *RdpClient) Close() {
if c != nil && c.tpkt != nil {
c.tpkt.Close()
}
}
-103
View File
@@ -1,103 +0,0 @@
// rfb.go
package client
import (
"fmt"
"net"
"time"
"github.com/shadow1ng/fscan/mylib/grdp/protocol/rfb"
)
type VncClient struct {
vnc *rfb.RFB
}
func newVncClient(s *Setting) *VncClient {
return &VncClient{}
}
func (c *VncClient) Login(host, user, pwd string, width, height int) error {
conn, err := net.DialTimeout("tcp", host, 3*time.Second)
if err != nil {
return fmt.Errorf("[dial err] %v", err)
}
c.vnc = rfb.NewRFB(rfb.NewRFBConn(conn, pwd))
err = c.vnc.Connect()
if err != nil {
return fmt.Errorf("[vnc connect err] %v", err)
}
return nil
}
func (c *VncClient) On(event string, f interface{}) {
c.vnc.On(event, f)
}
func (c *VncClient) KeyUp(sc int, name string) {
k := &rfb.KeyEvent{}
k.Key = uint32(sc)
c.vnc.SendKeyEvent(k)
}
func (c *VncClient) KeyDown(sc int, name string) {
k := &rfb.KeyEvent{}
k.DownFlag = 1
k.Key = uint32(sc)
c.vnc.SendKeyEvent(k)
}
func (c *VncClient) MouseMove(x, y int) {
p := &rfb.PointerEvent{}
time.Sleep(8 * time.Millisecond)
p.XPos = uint16(x)
p.YPos = uint16(y)
c.vnc.SendPointEvent(p)
}
func (c *VncClient) MouseWheel(scroll, x, y int) {
}
func (c *VncClient) MouseUp(button int, x, y int) {
p := &rfb.PointerEvent{}
switch button {
case 0:
p.Mask = 1
case 2:
p.Mask = 1<<3 - 1
case 1:
p.Mask = 1<<2 - 1
default:
p.Mask = 0
}
p.XPos = uint16(x)
p.YPos = uint16(y)
c.vnc.SendPointEvent(p)
}
func (c *VncClient) MouseDown(button int, x, y int) {
p := &rfb.PointerEvent{}
switch button {
case 0:
p.Mask = 1
case 2:
p.Mask = 1<<3 - 1
case 1:
p.Mask = 1<<2 - 1
default:
p.Mask = 0
}
p.XPos = uint16(x)
p.YPos = uint16(y)
c.MouseMove(x, y)
c.vnc.SendPointEvent(p)
}
func (c *VncClient) Close() {
if c.vnc != nil {
c.vnc.Close()
}
}
-22
View File
@@ -130,25 +130,3 @@ func Uint16BE(d0, d1 uint8) uint16 {
return binary.BigEndian.Uint16(b)
}
func RGB565ToRGB(data uint16) (r, g, b uint8) {
r = uint8((data & 0xF800) >> 8)
r |= r >> 5
g = uint8((data & 0x07E0) >> 3)
g |= g >> 6
b = uint8((data & 0x001F) << 3)
b |= b >> 5
return
}
func RGB555ToRGB(data uint16) (r, g, b uint8) {
r = uint8((data & 0x7C00) >> 7)
r |= r >> 5
g = uint8((data & 0x03E0) >> 2)
g |= g >> 5
b = uint8((data & 0x001F) << 3)
b |= b >> 5
return
}
File diff suppressed because it is too large Load Diff
+3 -438
View File
@@ -1,8 +1,6 @@
package login
import (
"bufio"
"bytes"
"errors"
"fmt"
"github.com/shadow1ng/fscan/mylib/grdp/core"
@@ -15,12 +13,7 @@ import (
"github.com/shadow1ng/fscan/mylib/grdp/protocol/x224"
"golang.org/x/net/context"
"golang.org/x/net/proxy"
"image"
"image/color"
"image/draw"
"image/jpeg"
"log"
"math/rand"
"net"
"net/url"
"os"
@@ -34,39 +27,6 @@ var (
OutputDir string
)
func init() {
}
func RdpConn(host, domain, user, password string, timeout int64, rdpProtocol uint32) (bool, error) {
g := NewClient(host, LogLever)
status, err, reconnectProtocol := g.ScreenShot(domain, user, password, timeout, rdpProtocol)
if status == true {
return true, err
} else {
if reconnectProtocol != rdpProtocol {
glog.Info("reconnect with protocol:", reconnectProtocol)
return RdpConn(host, domain, user, password, timeout, reconnectProtocol)
} else {
return status, err
}
}
}
func RdpCrack(host, domain, user, password string, timeout int64, rdpProtocol uint32) (bool, error) {
g := NewClient(host, LogLever)
status, err, reconnectProtocol := g.Crack(domain, user, password, timeout, rdpProtocol)
if status == true {
return true, err
} else {
if reconnectProtocol != rdpProtocol {
glog.Info("reconnect with protocol:", reconnectProtocol)
return RdpCrack(host, domain, user, password, timeout, reconnectProtocol)
} else {
return status, err
}
}
}
// NlaAuth 仅进行NLA认证验证,不建立RDP会话,不会挤掉已登录用户
// 返回: (认证成功, 错误信息)
func NlaAuth(host, domain, user, password string, timeout int64) (bool, error) {
@@ -99,14 +59,13 @@ func WrapperTcpWithTimeout(network, address string, timeout time.Duration) (net.
net_ip = net.ParseIP("0.0.0.0")
}
local_addr := &net.TCPAddr{
IP: net_ip, // 替换为你想要使用的本地IP地址
IP: net_ip,
}
d := &net.Dialer{Timeout: timeout, LocalAddr: local_addr}
return WrapperTCP(network, address, d)
}
func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error) {
//get conn
var conn net.Conn
if Socks5Proxy == "" {
var err error
@@ -121,10 +80,8 @@ func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error)
}
conn, err = dailer.Dial(network, address)
if err != nil {
// fmt.Println(err)
return nil, err
}
}
timeout := forward.Timeout
@@ -136,7 +93,6 @@ func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error)
}
return conn, nil
}
func Socks5Dailer(forward *net.Dialer) (proxy.Dialer, error) {
@@ -166,60 +122,6 @@ func Socks5Dailer(forward *net.Dialer) (proxy.Dialer, error) {
return dailer, nil
}
type Bitmap struct {
DestLeft int `json:"destLeft"`
DestTop int `json:"destTop"`
DestRight int `json:"destRight"`
DestBottom int `json:"destBottom"`
Width int `json:"width"`
Height int `json:"height"`
BitsPerPixel int `json:"bitsPerPixel"`
IsCompress bool `json:"isCompress"`
Data []byte `json:"data"`
}
func Bpp(BitsPerPixel uint16) (pixel int) {
switch BitsPerPixel {
case 15:
pixel = 1
case 16:
pixel = 2
case 24:
pixel = 3
case 32:
pixel = 4
default:
glog.Error("-------------------------------------Bpp func. invalid bitmap data format")
}
return
}
func BitmapDecompress(bitmap *pdu.BitmapData) []byte {
return core.Decompress(bitmap.BitmapDataStream, int(bitmap.Width), int(bitmap.Height), Bpp(bitmap.BitsPerPixel))
}
func ToRGBA(pixel int, i int, data []byte) (r, g, b, a uint8) {
a = 255
switch pixel {
case 1:
rgb555 := core.Uint16BE(data[i], data[i+1])
r, g, b = core.RGB555ToRGB(rgb555)
case 2:
rgb565 := core.Uint16BE(data[i], data[i+1])
r, g, b = core.RGB565ToRGB(rgb565)
case 3, 4:
fallthrough
default:
r, g, b = data[i+2], data[i+1], data[i]
}
return
}
// NlaAuthOnly 仅进行NLA认证验证凭据,不建立RDP会话
// 这样不会挤掉已登录的用户
func (g *Client) NlaAuthOnly(domain, user, pwd string, timeout int64) (bool, error) {
@@ -307,7 +209,7 @@ func (g *Client) ProbeOSInfo(host, domain, user, pwd string, timeout int64, rdpP
g.pdu.Emit("done")
})
g.x224.SetRequestedProtocol(rdpProtocol) //x224.PROTOCOL_SSL , x224.PROTOCOL_RDP , x224.PROTOCOL_HYBRID , x224.PROTOCOL_HYBRID_EX
g.x224.SetRequestedProtocol(rdpProtocol)
g.x224.On("reconnect", func(protocol uint32) {
info["reconn"] = protocol
g.pdu.Emit("close")
@@ -353,7 +255,7 @@ func (g *Client) ProbeOSInfo(host, domain, user, pwd string, timeout int64, rdpP
loop:
for {
select {
case <-time.After(time.Second * time.Duration(timeout)): //
case <-time.After(time.Second * time.Duration(timeout)):
break loop
case <-exitFlag:
break loop
@@ -365,340 +267,3 @@ loop:
glog.Debug("循环结束,总时间过去了:", time.Since(start))
return info
}
func (g *Client) ScreenShot(domain, user, pwd string, timeout int64, rdpProtocol uint32) (status bool, err error, reconnProtocol uint32) {
//glog.SetLevel(glog.ERROR)
reconnProtocol = rdpProtocol
pic_length := 1280 //1280
pic_width := 800 //800
needReconnect := false
isScreenOK := false
refresh := make(chan bool)
exitFlag := make(chan bool)
start := time.Now()
now := start
screenImage := image.NewRGBA(image.Rect(0, 0, pic_length, pic_width))
targetSlice := strings.Split(g.Host, ":")
ip := targetSlice[0]
port := targetSlice[1]
status = false
conn, err := WrapperTcpWithTimeout("tcp", g.Host, time.Duration(timeout)*time.Second)
if err != nil {
return status, fmt.Errorf("[dial err] %v", err), reconnProtocol
}
defer conn.Close()
glog.Info(conn.LocalAddr().String())
g.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd))
g.x224 = x224.New(g.tpkt)
g.mcs = t125.NewMCSClient(g.x224)
g.sec = sec.NewClient(g.mcs)
g.pdu = pdu.NewClient(g.sec)
g.sec.SetUser(user)
g.sec.SetPwd(pwd)
g.sec.SetDomain(domain)
//g.sec.SetClientAutoReconnect()
g.tpkt.SetFastPathListener(g.sec)
g.sec.SetFastPathListener(g.pdu)
g.pdu.SetFastPathSender(g.tpkt)
g.sec.SetChannelSender(g.mcs)
g.tpkt.On("os_info", func(info map[string]any) {
glog.Debug("[+] callback, get os info ........................")
for k, v := range info {
glog.Debugf("%s: %s\n", k, v)
}
})
g.x224.SetRequestedProtocol(rdpProtocol) //x224.PROTOCOL_SSL , x224.PROTOCOL_RDP , x224.PROTOCOL_HYBRID , x224.PROTOCOL_HYBRID_EX
g.x224.On("reconnect", func(protocol uint32) {
needReconnect = true
reconnProtocol = protocol
glog.Info("need reconnect with protocol:", protocol)
g.pdu.Emit("close")
exitFlag <- true
})
g.x224.On("more_timeout", func() {
timeout += 18 //如果是PROTOCOL_RDP协议,可以适当延长超时时间
})
err = g.x224.Connect()
if err != nil {
return status, fmt.Errorf("[x224 connect err] %v", err), reconnProtocol
}
glog.Info("wait connect ok")
g.pdu.On("error", func(e error) {
err = e
glog.Error("error", e)
g.pdu.Emit("done")
})
g.pdu.On("close", func() {
err = errors.New("close")
glog.Info("on close")
g.pdu.Emit("done")
})
g.pdu.On("success", func() {
glog.Debugf("===============login success %s===============", ip)
status = true
err = nil
g.pdu.Emit("done")
})
g.pdu.On("ready", func() {
err = nil
glog.Debug("on ready")
//g.pdu.Emit("done")
})
g.pdu.On("bitmap", func(rectangles []pdu.BitmapData) {
now = time.Now()
// 发送一个鼠标事件,作用是与服务器保持联系不要断开
rand.New(rand.NewSource(time.Now().UnixNano()))
randomNumber := rand.Intn(1000) + 10 // 10到1000之间的随机数
mouseX := 60 + randomNumber
mouseY := 10 + randomNumber
pevent := &pdu.PointerEvent{}
pevent.PointerFlags |= pdu.PTRFLAGS_MOVE
pevent.XPos = uint16(mouseX)
pevent.YPos = uint16(mouseY)
g.pdu.SendInputEvents(pdu.INPUT_EVENT_MOUSE, []pdu.InputEventsInterface{pevent})
glog.Debug("on update bitmap:", len(rectangles))
bs := make([]Bitmap, 0)
for _, v := range rectangles {
IsCompress := v.IsCompress()
data := v.BitmapDataStream
if IsCompress {
data = BitmapDecompress(&v)
IsCompress = false
}
b := Bitmap{int(v.DestLeft), int(v.DestTop), int(v.DestRight), int(v.DestBottom),
int(v.Width), int(v.Height), Bpp(v.BitsPerPixel), IsCompress, data}
bs = append(bs, b)
}
var (
pixel int
i int
r, g, b, a uint8
)
for _, bm := range bs {
i = 0
pixel = bm.BitsPerPixel
m := image.NewRGBA(image.Rect(0, 0, bm.Width, bm.Height))
for y := 0; y < bm.Height; y++ {
for x := 0; x < bm.Width; x++ {
r, g, b, a = ToRGBA(pixel, i, bm.Data)
c := color.RGBA{R: r, G: g, B: b, A: a}
i += pixel
m.Set(x, y, c)
}
}
draw.Draw(screenImage, screenImage.Bounds().Add(image.Pt(bm.DestLeft, bm.DestTop)), m, m.Bounds().Min, draw.Src)
}
// Encode to jpeg.
//var imageBuf bytes.Buffer
//err = jpeg.Encode(&imageBuf, screenImage, nil)
//
//if err != nil {
// glog.Info("trans bitmap to jpeg err:", err)
//}
// Write to file.
//fo, err := os.Create(fmt.Sprintf("img/%s-%d.jpg", ip, index))
//if err != nil {
// panic(err)
//}
//index += 1
//fw := bufio.NewWriter(fo)
//fw.Write(imageBuf.Bytes())
isScreenOK = true
refresh <- true
})
g.pdu.On("done", func() {
glog.Debug("done信号触发")
exitFlag <- true
})
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout*6)*time.Second)
defer cancel()
loop:
for {
select {
case <-time.After(time.Second * time.Duration(timeout*3)): //
glog.Debug("本次获取bitmap超时了, 距离上次获取到图像过去了:", time.Since(now))
break loop
case <-refresh:
continue loop
case <-exitFlag:
break loop
case <-ctx.Done():
glog.Debug("总超时已达到,退出")
break loop
}
}
glog.Debug("循环结束,总时间过去了:", time.Since(start))
// 认证结果由 success 事件回调设置,不在此处覆盖
if needReconnect {
return status, err, reconnProtocol
} else if isScreenOK {
glog.Info("get screen ok")
// Encode to jpeg.
var imageBuf bytes.Buffer
encodeErr := jpeg.Encode(&imageBuf, screenImage, nil)
if encodeErr != nil {
glog.Error("Failed to encode screenshot:", encodeErr)
return status, err, reconnProtocol
}
// Write to file.
saveDate := time.Now().Format("2006_01_02_15_04_05")
fo, writeErr := os.Create(fmt.Sprintf("%s/%s_%s_%s.jpg", OutputDir, ip, port, saveDate))
if writeErr != nil {
glog.Error("Can not create rdp screenshot file:", writeErr)
} else {
defer fo.Close()
fw := bufio.NewWriter(fo)
_, writeErr := fw.Write(imageBuf.Bytes())
if writeErr != nil {
glog.Error("Can not write rdp screenshot file:", writeErr)
} else {
fw.Flush()
}
}
}
return status, err, reconnProtocol
}
func (g *Client) Crack(domain, user, pwd string, timeout int64, rdpProtocol uint32) (status bool, err error, reconnProtocol uint32) {
//glog.SetLevel(glog.ERROR)
reconnProtocol = rdpProtocol
refresh := make(chan bool)
exitFlag := make(chan bool)
start := time.Now()
now := start
targetSlice := strings.Split(g.Host, ":")
ip := targetSlice[0]
status = false
conn, err := WrapperTcpWithTimeout("tcp", g.Host, time.Duration(timeout)*time.Second)
if err != nil {
return status, fmt.Errorf("[dial err] %v", err), reconnProtocol
}
defer conn.Close()
glog.Info(conn.LocalAddr().String())
g.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd))
g.x224 = x224.New(g.tpkt)
g.mcs = t125.NewMCSClient(g.x224)
g.sec = sec.NewClient(g.mcs)
g.pdu = pdu.NewClient(g.sec)
g.sec.SetUser(user)
g.sec.SetPwd(pwd)
g.sec.SetDomain(domain)
//g.sec.SetClientAutoReconnect()
g.tpkt.SetFastPathListener(g.sec)
g.sec.SetFastPathListener(g.pdu)
g.pdu.SetFastPathSender(g.tpkt)
g.sec.SetChannelSender(g.mcs)
g.tpkt.On("os_info", func(info map[string]any) {
glog.Debug("[+] callback, get os info ........................")
for k, v := range info {
glog.Debugf("%s: %s\n", k, v)
}
})
g.x224.SetRequestedProtocol(rdpProtocol) //x224.PROTOCOL_SSL , x224.PROTOCOL_RDP , x224.PROTOCOL_HYBRID , x224.PROTOCOL_HYBRID_EX
g.x224.On("reconnect", func(protocol uint32) {
reconnProtocol = protocol
glog.Info("need reconnect with protocol:", protocol)
g.pdu.Emit("close")
exitFlag <- true
})
g.x224.On("more_timeout", func() {
timeout += 18 //如果是PROTOCOL_RDP协议,可以适当延长超时时间
})
err = g.x224.Connect()
if err != nil {
return status, fmt.Errorf("[x224 connect err] %v", err), reconnProtocol
}
glog.Info("wait connect ok")
g.pdu.On("error", func(e error) {
err = e
glog.Error("error", e)
g.pdu.Emit("done")
})
g.pdu.On("close", func() {
err = errors.New("close")
glog.Info("on close")
g.pdu.Emit("done")
})
g.pdu.On("success", func() {
glog.Debugf("===============login success %s===============", ip)
status = true
err = nil
g.pdu.Emit("done")
})
g.pdu.On("ready", func() {
err = nil
glog.Debug("on ready")
//g.pdu.Emit("done")
})
g.pdu.On("bitmap", func(rectangles []pdu.BitmapData) {
now = time.Now()
// 发送一个鼠标事件,作用是与服务器保持联系不要断开
rand.New(rand.NewSource(time.Now().UnixNano()))
randomNumber := rand.Intn(1000) + 10 // 10到1000之间的随机数
mouseX := 60 + randomNumber
mouseY := 10 + randomNumber
pevent := &pdu.PointerEvent{}
pevent.PointerFlags |= pdu.PTRFLAGS_MOVE
pevent.XPos = uint16(mouseX)
pevent.YPos = uint16(mouseY)
g.pdu.SendInputEvents(pdu.INPUT_EVENT_MOUSE, []pdu.InputEventsInterface{pevent})
glog.Debug("on update bitmap:", len(rectangles))
refresh <- true
})
g.pdu.On("done", func() {
glog.Debug("done信号触发")
exitFlag <- true
})
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout*6)*time.Second)
defer cancel()
loop:
for {
select {
case <-time.After(time.Second * time.Duration(timeout*3)): //
glog.Debug("本次获取bitmap超时了, 距离上次获取到图像过去了:", time.Since(now))
break loop
case <-refresh:
continue loop
case <-exitFlag:
break loop
case <-ctx.Done():
glog.Debug("总超时已达到,退出")
break loop
}
}
glog.Debug("循环结束,总时间过去了:", time.Since(start))
// 认证结果由 success 事件回调设置,不在此处覆盖
return status, err, reconnProtocol
}
-328
View File
@@ -1,328 +0,0 @@
// +build ignore
// addins.go
package plugin
import (
"strings"
"sync/atomic"
"syscall"
"unsafe"
)
var (
openHandleSeq uint32
freerdpClient2 = syscall.NewLazyDLL("freerdp-client2.dll")
winpr2 = syscall.NewLazyDLL("winpr2.dll")
freerdp2 = syscall.NewLazyDLL("freerdp2.dll")
)
var (
virtualChannelEntry = freerdpClient2.NewProc("VirtualChannelEntry")
virtualChannelEntryEx = freerdpClient2.NewProc("VirtualChannelEntryEx")
)
func VirtualChannelEntryEx(ex *ChannelEntryPointsEx, pInitHandle interface{}) (err error) {
r0, _, ec := virtualChannelEntryEx.Call(uintptr(unsafe.Pointer(ex)),
uintptr(unsafe.Pointer(&pInitHandle)))
if r0 == 0 {
err = error(ec)
}
return
}
func ChannelsClientLoadEx(cs *rdpChannels) {
var client ChannelClientData
client.entryEx = VIRTUALCHANNELENTRYEX(VirtualChannelEntryEx)
cs.clientDataList = append(cs.clientDataList, client)
cs.clientDataCount++
var init ChannelInitData
init.channels = cs
init.openDataMap = make(map[uint32]*ChannelOpenData)
cs.initDataList = append(cs.initDataList, init)
cs.initDataCount++
ex := NewChannelEntryPointsEx()
ex.PVirtualChannelInitEx = VIRTUALCHANNELINITEX(RdpVirtualChannelInitEx)
ex.PVirtualChannelOpenEx = VIRTUALCHANNELOPENEX(RdpVirtualChannelOpenEx)
ex.PVirtualChannelCloseEx = VIRTUALCHANNELCLOSEEX(RdpVirtualChannelCloseEx)
ex.PVirtualChannelWriteEx = VIRTUALCHANNELWRITEEX(RdpVirtualChannelWriteEx)
client.entryEx(ex, uintptr(unsafe.Pointer(&init)))
}
type ChannelClientData struct {
//PVIRTUALCHANNELENTRY entry;
entryEx VIRTUALCHANNELENTRYEX
// pChannelInitEventProc *CHANNEL_INIT_EVENT_FN
pChannelInitEventProcEx CHANNEL_INIT_EVENT_EX_FN
pInitHandle interface{}
lpUserParam interface{}
}
type ChannelOpenData struct {
name string
OpenHandle uint32
options uint32
flags int
pInterface interface{}
channels *rdpChannels
lpUserParam interface{}
//pChannelOpenEventProc *CHANNEL_OPEN_EVENT_FN
pChannelOpenEventProcEx *CHANNEL_OPEN_EVENT_EX_FN
}
type ChannelInitData struct {
channels *rdpChannels
pInterface interface{}
openDataMap map[uint32]*ChannelOpenData
}
type rdpChannels struct {
clientDataCount int
clientDataList []ChannelClientData
openDataCount int
openDataList []ChannelOpenData
initDataCount int
initDataList []ChannelInitData
/* control for entry into MyVirtualChannelInit */
can_call_init bool
/* true once freerdp_channels_post_connect is called */
connected bool
/* used for locating the channels for a given instance */
//freerdp* instance;
//wMessageQueue* queue;
//DrdynvcClientContext* drdynvc;
//CRITICAL_SECTION channelsLock;
}
type ChannelOpenEvent struct {
Data interface{}
DataLength uint32
UserData interface{}
pChannelOpenData *ChannelOpenData
}
func RdpVirtualChannelInitEx(lpUserParam interface{}, clientContext interface{},
pInitHandle interface{}, pChannel []ChannelDef,
channelCount int, versionRequested uint32,
pChannelInitEventProcEx CHANNEL_INIT_EVENT_EX_FN) uint {
var (
//rdpSettings* settings;
pChannelInitData *ChannelInitData
pChannelClientData *ChannelClientData
channels *rdpChannels
)
if pInitHandle == nil {
return CHANNEL_RC_BAD_INIT_HANDLE
}
if pChannel == nil {
return CHANNEL_RC_BAD_CHANNEL
}
if (channelCount <= 0) || pChannelInitEventProcEx == nil {
return CHANNEL_RC_INITIALIZATION_ERROR
}
pChannelInitData = pInitHandle.(*ChannelInitData)
//WINPR_ASSERT(pChannelInitData);
channels = pChannelInitData.channels
//WINPR_ASSERT(channels);
if !channels.can_call_init {
return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY
}
if (channels.openDataCount + channelCount) > 30 {
return CHANNEL_RC_TOO_MANY_CHANNELS
}
if channels.connected {
return CHANNEL_RC_ALREADY_CONNECTED
}
if versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000 {
}
for i := range pChannel {
pChannelDef := &pChannel[i]
if getChannelOpenDataByName(channels, pChannelDef.Name) == nil {
return CHANNEL_RC_BAD_CHANNEL
}
}
pChannelClientData = &channels.clientDataList[channels.clientDataCount]
pChannelClientData.pChannelInitEventProcEx = pChannelInitEventProcEx
pChannelClientData.pInitHandle = pInitHandle
pChannelClientData.lpUserParam = lpUserParam
channels.clientDataCount++
//WINPR_ASSERT(channels->instance);
//WINPR_ASSERT(channels->instance->context);
//settings = channels.instance.context.settings
//WINPR_ASSERT(settings);
for i := range pChannel {
pChannelDef := &pChannel[i]
var pChannelOpenData ChannelOpenData
//WINPR_ASSERT(pChannelOpenData)
pChannelOpenData.OpenHandle = atomic.AddUint32(&openHandleSeq, 1)
pChannelOpenData.channels = channels
pChannelOpenData.lpUserParam = lpUserParam
if _, ok := pChannelInitData.openDataMap[pChannelOpenData.OpenHandle]; ok {
return CHANNEL_RC_INITIALIZATION_ERROR
}
pChannelInitData.pInterface = clientContext
pChannelOpenData.flags = 1
pChannelOpenData.name = pChannelDef.Name
pChannelOpenData.options = pChannelDef.Options
pChannelInitData.openDataMap[pChannelOpenData.OpenHandle] = &pChannelOpenData
channels.openDataList = append(channels.openDataList, pChannelOpenData)
channels.openDataCount++
/*
if settings.ChannelCount < 30 {
channel := freerdp_settings_get_pointer_array_writable(
settings, FreeRDP_ChannelDefArray, settings.ChannelCount)
channel.name = pChannelDef.Name
channel.options = pChannelDef.Options
settings.ChannelCount++
}*/
channels.openDataCount++
}
return CHANNEL_RC_OK
}
func getChannelOpenDataByName(channel *rdpChannels, name string) *ChannelOpenData {
for _, v := range channel.openDataList {
if strings.EqualFold(name, v.name) {
return &v
}
}
return nil
}
func RdpVirtualChannelOpenEx(pInitHandle interface{}, pOpenHandle *uint32, pChannelName string,
pChannelOpenEventProcEx *CHANNEL_OPEN_EVENT_EX_FN) uint {
pChannelInitData := pInitHandle.(*ChannelInitData)
channels := pChannelInitData.channels
pInterface := pChannelInitData.pInterface
if pOpenHandle == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
if pChannelOpenEventProcEx == nil {
return CHANNEL_RC_BAD_PROC
}
if !channels.connected {
return CHANNEL_RC_NOT_CONNECTED
}
pChannelOpenData := getChannelOpenDataByName(channels, pChannelName)
if pChannelOpenData == nil {
return CHANNEL_RC_UNKNOWN_CHANNEL_NAME
}
if pChannelOpenData.flags == 2 {
return CHANNEL_RC_ALREADY_OPEN
}
pChannelOpenData.flags = 2 /* open */
pChannelOpenData.pInterface = pInterface
pChannelOpenData.pChannelOpenEventProcEx = pChannelOpenEventProcEx
*pOpenHandle = pChannelOpenData.OpenHandle
return CHANNEL_RC_OK
}
func RdpVirtualChannelCloseEx(pInitHandle interface{}, openHandle uint32) uint {
if pInitHandle == nil {
return CHANNEL_RC_BAD_INIT_HANDLE
}
pChannelInitData := pInitHandle.(*ChannelInitData)
pChannelOpenData := pChannelInitData.openDataMap[openHandle]
if pChannelOpenData == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
if pChannelOpenData.flags != 2 {
return CHANNEL_RC_NOT_OPEN
}
pChannelOpenData.flags = 0
return CHANNEL_RC_OK
}
func RdpVirtualChannelWriteEx(pInitHandle interface{}, openHandle uint32,
pData interface{}, dataLength uint32,
pUserData interface{}) uint {
//wMessage message;
if pInitHandle == nil {
return CHANNEL_RC_BAD_INIT_HANDLE
}
pChannelInitData := pInitHandle.(*ChannelInitData)
channels := pChannelInitData.channels
if channels == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
pChannelOpenData := pChannelInitData.openDataMap[openHandle]
if pChannelOpenData == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
if !channels.connected {
return CHANNEL_RC_NOT_CONNECTED
}
if pData == nil {
return CHANNEL_RC_NULL_DATA
}
if dataLength == 0 {
return CHANNEL_RC_ZERO_LENGTH
}
if pChannelOpenData.flags != 2 {
return CHANNEL_RC_NOT_OPEN
}
pChannelOpenEvent := new(ChannelOpenEvent)
if pChannelOpenEvent == nil {
return CHANNEL_RC_NO_MEMORY
}
pChannelOpenEvent.Data = pData
pChannelOpenEvent.DataLength = dataLength
pChannelOpenEvent.UserData = pUserData
pChannelOpenEvent.pChannelOpenData = pChannelOpenData
/*message.context = channels;
message.id = 0;
message.wParam = pChannelOpenEvent;
message.lParam = NULL;
message.Free = channel_queue_message_free;
if (!MessageQueue_Dispatch(channels->queue, &message))
{
free(pChannelOpenEvent);
return CHANNEL_RC_NO_MEMORY;
}*/
return CHANNEL_RC_OK
}
-304
View File
@@ -1,304 +0,0 @@
package plugin
import "C"
import (
"bytes"
"fmt"
"unsafe"
"github.com/shadow1ng/fscan/mylib/grdp/glog"
"github.com/shadow1ng/fscan/mylib/grdp/core"
"github.com/shadow1ng/fscan/mylib/grdp/emission"
)
const (
CHANNEL_RC_OK = 0
CHANNEL_RC_ALREADY_INITIALIZED = 1
CHANNEL_RC_NOT_INITIALIZED = 2
CHANNEL_RC_ALREADY_CONNECTED = 3
CHANNEL_RC_NOT_CONNECTED = 4
CHANNEL_RC_TOO_MANY_CHANNELS = 5
CHANNEL_RC_BAD_CHANNEL = 6
CHANNEL_RC_BAD_CHANNEL_HANDLE = 7
CHANNEL_RC_NO_BUFFER = 8
CHANNEL_RC_BAD_INIT_HANDLE = 9
CHANNEL_RC_NOT_OPEN = 10
CHANNEL_RC_BAD_PROC = 11
CHANNEL_RC_NO_MEMORY = 12
CHANNEL_RC_UNKNOWN_CHANNEL_NAME = 13
CHANNEL_RC_ALREADY_OPEN = 14
CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY = 15
CHANNEL_RC_NULL_DATA = 16
CHANNEL_RC_ZERO_LENGTH = 17
CHANNEL_RC_INVALID_INSTANCE = 18
CHANNEL_RC_UNSUPPORTED_VERSION = 19
CHANNEL_RC_INITIALIZATION_ERROR = 20
)
const (
VIRTUAL_CHANNEL_VERSION_WIN2000 = 1
)
const (
CHANNEL_EVENT_INITIALIZED = 0
CHANNEL_EVENT_CONNECTED = 1
CHANNEL_EVENT_V1_CONNECTED = 2
CHANNEL_EVENT_DISCONNECTED = 3
CHANNEL_EVENT_TERMINATED = 4
CHANNEL_EVENT_REMOTE_CONTROL_START = 5
CHANNEL_EVENT_REMOTE_CONTROL_STOP = 6
CHANNEL_EVENT_ATTACHED = 7
CHANNEL_EVENT_DETACHED = 8
CHANNEL_EVENT_DATA_RECEIVED = 10
CHANNEL_EVENT_WRITE_COMPLETE = 11
CHANNEL_EVENT_WRITE_CANCELLED = 12
)
const (
CHANNEL_OPTION_INITIALIZED = 0x80000000
CHANNEL_OPTION_ENCRYPT_RDP = 0x40000000
CHANNEL_OPTION_ENCRYPT_SC = 0x20000000
CHANNEL_OPTION_ENCRYPT_CS = 0x10000000
CHANNEL_OPTION_PRI_HIGH = 0x08000000
CHANNEL_OPTION_PRI_MED = 0x04000000
CHANNEL_OPTION_PRI_LOW = 0x02000000
CHANNEL_OPTION_COMPRESS_RDP = 0x00800000
CHANNEL_OPTION_COMPRESS = 0x00400000
CHANNEL_OPTION_SHOW_PROTOCOL = 0x00200000
CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT = 0x00100000
)
type ChannelDef struct {
Name string
Options uint32
}
type CHANNEL_INIT_EVENT_EX_FN func(lpUserParam interface{},
pInitHandle interface{}, event uint, pData uintptr, dataLength uint)
type VIRTUALCHANNELINITEX func(lpUserParam interface{}, clientContext interface{},
pInitHandle interface{}, pChannel []ChannelDef,
channelCount int, versionRequested uint32,
pChannelInitEventProcEx CHANNEL_INIT_EVENT_EX_FN) uint
type CHANNEL_OPEN_EVENT_EX_FN func(lpUserParam uintptr,
openHandle uint32, event uint,
pData uintptr, dataLength uint32, totalLength uint32, dataFlags uint32)
type VIRTUALCHANNELOPENEX func(pInitHandle interface{}, pOpenHandle *uint32,
pChannelName string,
pChannelOpenEventProcEx *CHANNEL_OPEN_EVENT_EX_FN) uint
type VIRTUALCHANNELCLOSEEX func(pInitHandle interface{}, openHandle uint32) uint
type VIRTUALCHANNELWRITEEX func(pInitHandle interface{}, openHandle uint32, pData interface{},
dataLength uint32, pUserData interface{}) uint
type ChannelEntryPointsEx struct {
CbSize uint32
ProtocolVersion uint32
PVirtualChannelInitEx VIRTUALCHANNELINITEX
PVirtualChannelOpenEx VIRTUALCHANNELOPENEX
PVirtualChannelCloseEx VIRTUALCHANNELCLOSEEX
PVirtualChannelWriteEx VIRTUALCHANNELWRITEEX
}
func NewChannelEntryPointsEx() *ChannelEntryPointsEx {
e := &ChannelEntryPointsEx{}
e.CbSize = uint32(unsafe.Sizeof(e))
e.ProtocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000
return e
}
type VIRTUALCHANNELENTRYEX func(pEntryPointsEx *ChannelEntryPointsEx,
pInitHandle interface{}) error
/*
type ChannelEntryPoints struct {
CbSize uint32
ProtocolVersion uint32
PVirtualChannelInit PVIRTUALCHANNELINIT
PVirtualChannelOpen PVIRTUALCHANNELOPEN
PVirtualChannelClose PVIRTUALCHANNELCLOSE
PVirtualChannelWrite PVIRTUALCHANNELWRITE
}
typedef VOID VCAPITYPE CHANNEL_INIT_EVENT_FN(LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength);
typedef CHANNEL_INIT_EVENT_FN* PCHANNEL_INIT_EVENT_FN;
typedef VOID VCAPITYPE CHANNEL_OPEN_EVENT_FN(DWORD openHandle, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags);
typedef CHANNEL_OPEN_EVENT_FN* PCHANNEL_OPEN_EVENT_FN;
typedef UINT VCAPITYPE VIRTUALCHANNELINIT(LPVOID* ppInitHandle, PCHANNEL_DEF pChannel,
INT channelCount, ULONG versionRequested,
PCHANNEL_INIT_EVENT_FN pChannelInitEventProc);
typedef VIRTUALCHANNELINIT* PVIRTUALCHANNELINIT;
typedef UINT VCAPITYPE VIRTUALCHANNELOPEN(LPVOID pInitHandle, LPDWORD pOpenHandle,
PCHAR pChannelName,
PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc);
typedef VIRTUALCHANNELOPEN* PVIRTUALCHANNELOPEN;
typedef UINT VCAPITYPE VIRTUALCHANNELCLOSE(DWORD openHandle);
typedef VIRTUALCHANNELCLOSE* PVIRTUALCHANNELCLOSE;
typedef UINT VCAPITYPE VIRTUALCHANNELWRITE(DWORD openHandle, LPVOID pData, ULONG dataLength,
LPVOID pUserData);
typedef VIRTUALCHANNELWRITE* PVIRTUALCHANNELWRITE;
typedef UINT VCAPITYPE VIRTUALCHANNELINITEX(LPVOID lpUserParam, LPVOID clientContext,
LPVOID pInitHandle, PCHANNEL_DEF pChannel,
INT channelCount, ULONG versionRequested,
PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx);
typedef VIRTUALCHANNELINITEX* PVIRTUALCHANNELINITEX;
typedef UINT VCAPITYPE VIRTUALCHANNELOPENEX(LPVOID pInitHandle, LPDWORD pOpenHandle,
PCHAR pChannelName,
PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx);
typedef VIRTUALCHANNELOPENEX* PVIRTUALCHANNELOPENEX;
typedef UINT VCAPITYPE VIRTUALCHANNELCLOSEEX(LPVOID pInitHandle, DWORD openHandle);
typedef VIRTUALCHANNELCLOSEEX* PVIRTUALCHANNELCLOSEEX;
typedef UINT VCAPITYPE VIRTUALCHANNELWRITEEX(LPVOID pInitHandle, DWORD openHandle, LPVOID pData,
ULONG dataLength, LPVOID pUserData);
typedef VIRTUALCHANNELWRITEEX* PVIRTUALCHANNELWRITEEX;
*/
// static channel name
const (
CLIPRDR_SVC_CHANNEL_NAME = "cliprdr" //剪切板
RDPDR_SVC_CHANNEL_NAME = "rdpdr" //设备重定向(打印机,磁盘,端口,智能卡等)
RDPSND_SVC_CHANNEL_NAME = "rdpsnd" //音频输出
RAIL_SVC_CHANNEL_NAME = "rail" //远程应用
DRDYNVC_SVC_CHANNEL_NAME = "drdynvc" //动态虚拟通道
REMDESK_SVC_CHANNEL_NAME = "remdesk" //远程协助
)
const (
RDPGFX_DVC_CHANNEL_NAME = "Microsoft::Windows::RDS::Graphics" //图形扩展
)
var StaticVirtualChannels = map[string]int{
CLIPRDR_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
RDPDR_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP,
RDPSND_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
RAIL_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
}
const (
CHANNEL_CHUNK_LENGTH = 1600
CHANNEL_FLAG_FIRST = 0x01
CHANNEL_FLAG_LAST = 0x02
CHANNEL_FLAG_SHOW_PROTOCOL = 0x10
)
type ChannelTransport interface {
GetType() (string, uint32)
Sender(core.ChannelSender)
Process(s []byte)
}
type ChannelClient struct {
ChannelDef
t ChannelTransport
}
type Channels struct {
emission.Emitter
channels map[string]ChannelClient
transport core.Transport
buff *bytes.Buffer
channelSender core.ChannelSender
}
func NewChannels(t core.Transport) *Channels {
c := &Channels{
Emitter: *emission.NewEmitter(),
channels: make(map[string]ChannelClient, 20),
transport: t,
buff: &bytes.Buffer{},
}
t.On("channel", c.process)
return c
}
func (c *Channels) SetChannelSender(f core.ChannelSender) {
c.channelSender = f
}
func (c *Channels) Register(t ChannelTransport) {
name, option := t.GetType()
_, ok := c.channels[name]
if ok {
glog.Warn("Already register channel:", name)
return
}
t.Sender(c)
c.channels[name] = ChannelClient{ChannelDef{name, option}, t}
}
func (c *Channels) SendToChannel(channel string, s []byte) (int, error) {
cli, ok := c.channels[channel]
if !ok {
glog.Warn("No register channel:", channel)
return 0, fmt.Errorf("No register channel: %s", channel)
}
idx := 0
ln := len(s)
b := &bytes.Buffer{}
for ln > 0 {
var flag uint32 = 0
if cli.Options&CHANNEL_OPTION_SHOW_PROTOCOL != 0 {
flag |= CHANNEL_FLAG_SHOW_PROTOCOL
}
if idx == 0 {
flag |= CHANNEL_FLAG_FIRST
}
var ss []byte
if ln > CHANNEL_CHUNK_LENGTH {
ss = s[idx : idx+CHANNEL_CHUNK_LENGTH]
idx += CHANNEL_CHUNK_LENGTH
} else {
flag |= CHANNEL_FLAG_LAST
ss = s[idx : idx+ln]
}
glog.Debug("len:", len(ss), "flag:", flag)
ln -= len(ss)
b.Reset()
core.WriteUInt32LE(uint32(len(s)), b)
core.WriteUInt32LE(flag, b)
b.Write(ss)
c.channelSender.SendToChannel(channel, b.Bytes())
}
return ln, nil
}
func (c *Channels) process(channel string, s []byte) {
cli, ok := c.channels[channel]
if !ok {
glog.Warn("No found channel:", channel)
return
}
r := bytes.NewReader(s)
ln, _ := core.ReadUInt32LE(r)
flags, _ := core.ReadUInt32LE(r)
glog.Debugf("channel:%s length: %d, flags: %d", channel, ln, flags)
if flags&CHANNEL_FLAG_FIRST == 0 || flags&CHANNEL_FLAG_LAST == 0 {
if flags&CHANNEL_FLAG_FIRST != 0 {
c.buff.Reset()
}
b, _ := core.ReadBytes(r.Len(), r)
c.buff.Write(b)
if flags&CHANNEL_FLAG_LAST == 0 {
return
}
s = c.buff.Bytes()
} else {
s, _ = core.ReadBytes(r.Len(), r)
}
cli.t.Process(s)
}
-159
View File
@@ -1,159 +0,0 @@
package drdynvc
import (
"bytes"
"encoding/hex"
"io"
"github.com/shadow1ng/fscan/mylib/grdp/core"
"github.com/shadow1ng/fscan/mylib/grdp/glog"
"github.com/shadow1ng/fscan/mylib/grdp/plugin"
)
const (
ChannelName = plugin.DRDYNVC_SVC_CHANNEL_NAME
ChannelOption = plugin.CHANNEL_OPTION_INITIALIZED |
plugin.CHANNEL_OPTION_ENCRYPT_RDP
)
const (
MAX_DVC_CHANNELS = 20
)
const (
DYNVC_CREATE_REQ = 0x01
DYNVC_DATA_FIRST = 0x02
DYNVC_DATA = 0x03
DYNVC_CLOSE = 0x04
DYNVC_CAPABILITIES = 0x05
DYNVC_DATA_FIRST_COMPRESSED = 0x06
DYNVC_DATA_COMPRESSED = 0x07
DYNVC_SOFT_SYNC_REQUEST = 0x08
DYNVC_SOFT_SYNC_RESPONSE = 0x09
)
type ChannelClient struct {
}
type DvcClient struct {
w core.ChannelSender
channels map[string]ChannelClient
}
func NewDvcClient() *DvcClient {
return &DvcClient{
channels: make(map[string]ChannelClient, 100),
}
}
func (c *DvcClient) LoadAddin(f core.ChannelSender) {
}
type DvcHeader struct {
cmd uint8
sp uint8
cbChId uint8
}
func readHeader(r io.Reader) *DvcHeader {
value, _ := core.ReadUInt8(r)
cmd := (value & 0xf0) >> 4
sp := (value & 0x0c) >> 2
cbChId := (value & 0x03) >> 0
return &DvcHeader{cmd, sp, cbChId}
}
func (h *DvcHeader) serialize(channelId uint32) []byte {
b := &bytes.Buffer{}
core.WriteUInt8((h.cmd<<4)|(h.sp<<2)|h.cbChId, b)
if h.cbChId == 0 {
core.WriteUInt8(uint8(channelId), b)
} else if h.cbChId == 1 {
core.WriteUInt16LE(uint16(channelId), b)
} else {
core.WriteUInt32LE(channelId, b)
}
return b.Bytes()
}
func (c *DvcClient) Send(s []byte) (int, error) {
glog.Debug("len:", len(s), "data:", hex.EncodeToString(s))
name, _ := c.GetType()
return c.w.SendToChannel(name, s)
}
func (c *DvcClient) Sender(f core.ChannelSender) {
c.w = f
}
func (c *DvcClient) GetType() (string, uint32) {
return ChannelName, ChannelOption
}
func (c *DvcClient) Process(s []byte) {
glog.Debug("recv:", hex.EncodeToString(s))
r := bytes.NewReader(s)
hdr := readHeader(r)
glog.Infof("dvc: Cmd=0x%x, Sp=%d CbChId=%d all=%d", hdr.cmd, hdr.sp, hdr.cbChId, r.Len())
b, _ := core.ReadBytes(r.Len(), r)
switch hdr.cmd {
case DYNVC_CAPABILITIES:
glog.Info("DYNVC_CAPABILITIES")
c.processCapsPdu(hdr, b)
case DYNVC_CREATE_REQ:
glog.Info("DYNVC_CREATE_REQ")
c.processCreateReq(hdr, b)
case DYNVC_DATA_FIRST:
glog.Info("DYNVC_DATA_FIRST")
case DYNVC_DATA:
glog.Info("DYNVC_DATA")
case DYNVC_CLOSE:
glog.Info("DYNVC_CLOSE")
default:
glog.Errorf("type 0x%x not supported", hdr.cmd)
}
}
func (c *DvcClient) processCreateReq(hdr *DvcHeader, s []byte) {
r := bytes.NewReader(s)
channelId := readDvcId(r, hdr.cbChId)
name, _ := core.ReadBytes(r.Len(), r)
channelName := string(name)
glog.Infof("Server requests channelId=%d, name=%s", channelId, channelName)
//response
b := &bytes.Buffer{}
b.Write(hdr.serialize(channelId))
core.WriteUInt32LE(0, b)
c.Send(b.Bytes())
}
func readDvcId(r io.Reader, cbLen uint8) (id uint32) {
switch cbLen {
case 0:
i, _ := core.ReadUInt8(r)
id = uint32(i)
case 1:
i, _ := core.ReadUint16LE(r)
id = uint32(i)
default:
id, _ = core.ReadUInt32LE(r)
}
return
}
func (c *DvcClient) processCapsPdu(hdr *DvcHeader, s []byte) {
r := bytes.NewReader(s)
core.ReadUInt8(r)
ver, _ := core.ReadUint16LE(r)
glog.Infof("Server supports dvc=%d", ver)
hdr.cmd = DYNVC_CAPABILITIES
hdr.cbChId = 0
hdr.sp = 0
b := &bytes.Buffer{}
core.WriteUInt16LE(0x0050, b)
core.WriteUInt16LE(ver, b)
c.Send(b.Bytes())
}
-451
View File
@@ -1,451 +0,0 @@
// rail.go
package rail
import (
"bytes"
"encoding/hex"
"github.com/shadow1ng/fscan/mylib/grdp/core"
"github.com/shadow1ng/fscan/mylib/grdp/glog"
"github.com/shadow1ng/fscan/mylib/grdp/plugin"
)
const (
ChannelName = plugin.RAIL_SVC_CHANNEL_NAME
ChannelOption = plugin.CHANNEL_OPTION_INITIALIZED | plugin.CHANNEL_OPTION_ENCRYPT_RDP |
plugin.CHANNEL_OPTION_COMPRESS_RDP | plugin.CHANNEL_OPTION_SHOW_PROTOCOL
)
const (
TS_RAIL_ORDER_EXEC = 0x0001
TS_RAIL_ORDER_ACTIVATE = 0x0002
TS_RAIL_ORDER_SYSPARAM = 0x0003
TS_RAIL_ORDER_SYSCOMMAND = 0x0004
TS_RAIL_ORDER_HANDSHAKE = 0x0005
TS_RAIL_ORDER_NOTIFY_EVENT = 0x0006
TS_RAIL_ORDER_WINDOWMOVE = 0x0008
TS_RAIL_ORDER_LOCALMOVESIZE = 0x0009
TS_RAIL_ORDER_MINMAXINFO = 0x000A
TS_RAIL_ORDER_CLIENTSTATUS = 0x000B
TS_RAIL_ORDER_SYSMENU = 0x000C
TS_RAIL_ORDER_LANGBARINFO = 0x000D
TS_RAIL_ORDER_GET_APPID_REQ = 0x000E
TS_RAIL_ORDER_GET_APPID_RESP = 0x000F
TS_RAIL_ORDER_TASKBARINFO = 0x0010
TS_RAIL_ORDER_LANGUAGEIMEINFO = 0x0011
TS_RAIL_ORDER_COMPARTMENTINFO = 0x0012
TS_RAIL_ORDER_HANDSHAKE_EX = 0x0013
TS_RAIL_ORDER_ZORDER_SYNC = 0x0014
TS_RAIL_ORDER_CLOAK = 0x0015
TS_RAIL_ORDER_POWER_DISPLAY_REQUEST = 0x0016
TS_RAIL_ORDER_SNAP_ARRANGE = 0x0017
TS_RAIL_ORDER_GET_APPID_RESP_EX = 0x0018
TS_RAIL_ORDER_EXEC_RESULT = 0x0080
)
type RailClient struct {
w core.ChannelSender
DesktopWidth uint16
DesktopHeight uint16
RemoteApplicationProgram string
ShellWorkingDirectory string
RemoteApplicationCmdLine string
}
func NewClient() *RailClient {
return &RailClient{
DesktopWidth: 800,
DesktopHeight: 600,
RemoteApplicationProgram: "calc",
ShellWorkingDirectory: "/tmp",
}
}
type RailPDUHeader struct {
OrderType uint16 `struc:"little"`
OrderLength uint16 `struc:"little"`
}
func NewRailPDUHeader(mType, ln uint16) *RailPDUHeader {
return &RailPDUHeader{
OrderType: mType,
OrderLength: ln,
}
}
func (h *RailPDUHeader) serialize() []byte {
b := &bytes.Buffer{}
core.WriteUInt16LE(h.OrderType, b)
core.WriteUInt16LE(h.OrderLength, b)
return b.Bytes()
}
func (c *RailClient) sendData(mType uint16, ln int, s []byte) {
glog.Debug(ln, ":ln:", len(s), "data:", hex.EncodeToString(s))
header := NewRailPDUHeader(mType, uint16(ln))
b := &bytes.Buffer{}
core.WriteBytes(header.serialize(), b)
core.WriteBytes(s, b)
c.Send(b.Bytes())
}
func (c *RailClient) Send(s []byte) (int, error) {
glog.Debug("len:", len(s), "data:", hex.EncodeToString(s))
name, _ := c.GetType()
return c.w.SendToChannel(name, s)
}
func (c *RailClient) Sender(f core.ChannelSender) {
c.w = f
}
func (c *RailClient) GetType() (string, uint32) {
return ChannelName, ChannelOption
}
func (c *RailClient) Process(s []byte) {
glog.Debug("recv:", hex.EncodeToString(s))
r := bytes.NewReader(s)
msgType, _ := core.ReadUint16LE(r)
length, _ := core.ReadUint16LE(r)
glog.Infof("rail: type=0x%x length=%d, all=%d", msgType, length, r.Len())
b, _ := core.ReadBytes(int(length), r)
glog.Info("b:", hex.EncodeToString(b))
switch msgType {
case TS_RAIL_ORDER_HANDSHAKE:
glog.Info("TS_RAIL_ORDER_HANDSHAKE")
c.processOrderHandshake(b)
case TS_RAIL_ORDER_SYSPARAM:
glog.Info("TS_RAIL_ORDER_SYSPARAM")
c.processOrderSysparam(b)
case TS_RAIL_ORDER_EXEC_RESULT:
glog.Info("TS_RAIL_ORDER_EXEC_RESULT")
c.processExecResult(b)
default:
glog.Errorf("type 0x%x not supported", msgType)
}
}
func (c *RailClient) processOrderHandshake(b []byte) {
r := bytes.NewReader(b)
buildNumber, _ := core.ReadUInt32LE(r)
glog.Info("buildNumber:", buildNumber)
//send client info
c.sendClientStatus()
//send client systemparam
c.sendClientSystemparam()
//send client execute
c.sendClientExecute()
}
const (
TS_RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE = 0x00000001
TS_RAIL_CLIENTSTATUS_AUTORECONNECT = 0x00000002
TS_RAIL_CLIENTSTATUS_ZORDER_SYNC = 0x00000004
TS_RAIL_CLIENTSTATUS_WINDOW_RESIZE_MARGIN_SUPPORTED = 0x00000010
TS_RAIL_CLIENTSTATUS_HIGH_DPI_ICONS_SUPPORTED = 0x00000020
TS_RAIL_CLIENTSTATUS_APPBAR_REMOTING_SUPPORTED = 0x00000040
TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED = 0x00000080
TS_RAIL_CLIENTSTATUS_GET_APPID_RESPONSE_EX_SUPPORTED = 0x00000100
TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED = 0x00000200
)
func (c *RailClient) sendClientStatus() {
glog.Info("Send client Status")
var flags uint32 = TS_RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE
//if (settings->AutoReconnectionEnabled)
//clientStatus.flags |= TS_RAIL_CLIENTSTATUS_AUTORECONNECT;
flags |= TS_RAIL_CLIENTSTATUS_ZORDER_SYNC
flags |= TS_RAIL_CLIENTSTATUS_WINDOW_RESIZE_MARGIN_SUPPORTED
flags |= TS_RAIL_CLIENTSTATUS_APPBAR_REMOTING_SUPPORTED
flags |= TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED
flags |= TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED
b := &bytes.Buffer{}
core.WriteUInt32LE(flags, b)
c.sendData(TS_RAIL_ORDER_CLIENTSTATUS, 4, b.Bytes())
}
const (
SPI_SET_SCREEN_SAVE_ACTIVE = 0x00000011
SPI_SET_SCREEN_SAVE_SECURE = 0x00000077
)
const (
/*Bit mask values for SPI_ parameters*/
SPI_MASK_SET_DRAG_FULL_WINDOWS = 0x00000001
SPI_MASK_SET_KEYBOARD_CUES = 0x00000002
SPI_MASK_SET_KEYBOARD_PREF = 0x00000004
SPI_MASK_SET_MOUSE_BUTTON_SWAP = 0x00000008
SPI_MASK_SET_WORK_AREA = 0x00000010
SPI_MASK_DISPLAY_CHANGE = 0x00000020
SPI_MASK_TASKBAR_POS = 0x00000040
SPI_MASK_SET_HIGH_CONTRAST = 0x00000080
SPI_MASK_SET_SCREEN_SAVE_ACTIVE = 0x00000100
SPI_MASK_SET_SET_SCREEN_SAVE_SECURE = 0x00000200
SPI_MASK_SET_CARET_WIDTH = 0x00000400
SPI_MASK_SET_STICKY_KEYS = 0x00000800
SPI_MASK_SET_TOGGLE_KEYS = 0x00001000
SPI_MASK_SET_FILTER_KEYS = 0x00002000
)
const (
SPI_SET_DRAG_FULL_WINDOWS = 0x00000025
SPI_SET_KEYBOARD_CUES = 0x0000100B
SPI_SET_KEYBOARD_PREF = 0x00000045
SPI_SET_MOUSE_BUTTON_SWAP = 0x00000021
SPI_SET_WORK_AREA = 0x0000002F
SPI_DISPLAY_CHANGE = 0x0000F001
SPI_TASKBAR_POS = 0x0000F000
SPI_SET_HIGH_CONTRAST = 0x00000043
SPI_SETCARETWIDTH = 0x00002007
SPI_SETSTICKYKEYS = 0x0000003B
SPI_SETTOGGLEKEYS = 0x00000035
SPI_SETFILTERKEYS = 0x00000033
)
type TsFilterKeys struct {
Flags uint32
WaitTime uint32
DelayTime uint32
RepeatTime uint32
BounceTime uint32
}
type RailHighContrast struct {
flags uint32
colorSchemeLength uint32
colorScheme string
}
type Rectangle16 struct {
left uint16
top uint16
right uint16
bottom uint16
}
type RailSysparamOrder struct {
param uint32
params uint32
dragFullWindows uint8
keyboardCues uint8
keyboardPref uint8
mouseButtonSwap uint8
workArea Rectangle16
displayChange Rectangle16
taskbarPos Rectangle16
highContrast RailHighContrast
caretWidth uint32
stickyKeys uint32
toggleKeys uint32
filterKeys TsFilterKeys
setScreenSaveActive uint8
setScreenSaveSecure uint8
}
func (c *RailClient) sendClientSystemparam() {
glog.Info("Send client Systemparam")
var sp RailSysparamOrder
sp.params = 0
sp.params |= SPI_MASK_SET_HIGH_CONTRAST
sp.highContrast.colorScheme = ""
sp.highContrast.colorSchemeLength = 0
sp.highContrast.flags = 0x7E
sp.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP
sp.mouseButtonSwap = 0
sp.params |= SPI_MASK_SET_KEYBOARD_PREF
sp.keyboardPref = 0
sp.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS
sp.dragFullWindows = 0
sp.params |= SPI_MASK_SET_KEYBOARD_CUES
sp.keyboardCues = 0
sp.params |= SPI_MASK_SET_WORK_AREA
sp.workArea.left = 0
sp.workArea.top = 0
sp.workArea.right = c.DesktopWidth
sp.workArea.bottom = c.DesktopHeight
if sp.params&SPI_MASK_SET_HIGH_CONTRAST != 0 {
sp.param = SPI_SET_HIGH_CONTRAST
c.sendOneClientSysparam(&sp)
}
if sp.params&SPI_MASK_TASKBAR_POS != 0 {
sp.param = SPI_TASKBAR_POS
c.sendOneClientSysparam(&sp)
}
if sp.params&SPI_MASK_SET_MOUSE_BUTTON_SWAP != 0 {
sp.param = SPI_SET_MOUSE_BUTTON_SWAP
c.sendOneClientSysparam(&sp)
}
if sp.params&SPI_MASK_SET_KEYBOARD_PREF != 0 {
sp.param = SPI_SET_KEYBOARD_PREF
c.sendOneClientSysparam(&sp)
}
if sp.params&SPI_MASK_SET_DRAG_FULL_WINDOWS != 0 {
sp.param = SPI_SET_DRAG_FULL_WINDOWS
c.sendOneClientSysparam(&sp)
}
if sp.params&SPI_MASK_SET_KEYBOARD_CUES != 0 {
sp.param = SPI_SET_KEYBOARD_CUES
c.sendOneClientSysparam(&sp)
}
if sp.params&SPI_MASK_SET_WORK_AREA != 0 {
sp.param = SPI_SET_WORK_AREA
glog.Debug("SPI_SET_WORK_AREA")
c.sendOneClientSysparam(&sp)
}
}
func (c *RailClient) sendOneClientSysparam(sp *RailSysparamOrder) {
length := 0
b := &bytes.Buffer{}
core.WriteUInt32LE(sp.param, b)
switch sp.param {
case SPI_SET_DRAG_FULL_WINDOWS:
core.WriteUInt8(sp.dragFullWindows, b)
case SPI_SET_KEYBOARD_CUES:
core.WriteUInt8(sp.keyboardCues, b)
case SPI_SET_KEYBOARD_PREF:
core.WriteUInt8(sp.keyboardPref, b)
case SPI_SET_MOUSE_BUTTON_SWAP:
core.WriteUInt8(sp.mouseButtonSwap, b)
case SPI_SET_WORK_AREA:
core.WriteUInt16LE(sp.workArea.left, b)
core.WriteUInt16LE(sp.workArea.top, b)
core.WriteUInt16LE(sp.workArea.right, b)
core.WriteUInt16LE(sp.workArea.bottom, b)
case SPI_DISPLAY_CHANGE:
core.WriteUInt16LE(sp.displayChange.left, b)
core.WriteUInt16LE(sp.displayChange.top, b)
core.WriteUInt16LE(sp.displayChange.right, b)
core.WriteUInt16LE(sp.displayChange.bottom, b)
case SPI_TASKBAR_POS:
core.WriteUInt16LE(sp.taskbarPos.left, b)
core.WriteUInt16LE(sp.taskbarPos.top, b)
core.WriteUInt16LE(sp.taskbarPos.right, b)
core.WriteUInt16LE(sp.taskbarPos.bottom, b)
case SPI_SET_HIGH_CONTRAST:
core.WriteUInt32LE(sp.highContrast.flags, b)
core.WriteUInt32LE(sp.highContrast.colorSchemeLength, b)
data := core.UnicodeEncode(sp.highContrast.colorScheme)
core.WriteBytes(data, b)
case SPI_SETFILTERKEYS:
core.WriteUInt32LE(sp.filterKeys.Flags, b)
core.WriteUInt32LE(sp.filterKeys.WaitTime, b)
core.WriteUInt32LE(sp.filterKeys.DelayTime, b)
core.WriteUInt32LE(sp.filterKeys.RepeatTime, b)
core.WriteUInt32LE(sp.filterKeys.BounceTime, b)
case SPI_SETSTICKYKEYS:
core.WriteUInt32LE(sp.stickyKeys, b)
case SPI_SETCARETWIDTH:
core.WriteUInt32LE(sp.caretWidth, b)
case SPI_SETTOGGLEKEYS:
core.WriteUInt32LE(sp.toggleKeys, b)
case SPI_MASK_SET_SET_SCREEN_SAVE_SECURE:
core.WriteUInt8(sp.setScreenSaveSecure, b)
case SPI_MASK_SET_SCREEN_SAVE_ACTIVE:
core.WriteUInt8(sp.setScreenSaveActive, b)
default:
glog.Error("ERROR_BAD_ARGUMENTS")
return
}
c.sendData(TS_RAIL_ORDER_SYSPARAM, length+b.Len(), b.Bytes())
}
type RailExecOrder struct {
flags uint16
RemoteApplicationProgram string
RemoteApplicationWorkingDir string
RemoteApplicationArguments string
}
func (c *RailClient) sendClientExecute() {
glog.Info("Send Client Execute")
var exec RailExecOrder
//exec.flags = TS_RAIL_EXEC_FLAG_EXPAND_ARGUMENTS
exec.RemoteApplicationProgram = c.RemoteApplicationProgram
exec.RemoteApplicationWorkingDir = c.ShellWorkingDirectory
exec.RemoteApplicationArguments = c.RemoteApplicationCmdLine
program := core.UnicodeEncode(exec.RemoteApplicationProgram)
workdir := core.UnicodeEncode(exec.RemoteApplicationWorkingDir)
arguments := core.UnicodeEncode(exec.RemoteApplicationArguments)
length := 4
b := &bytes.Buffer{}
core.WriteUInt16LE(exec.flags, b)
core.WriteUInt16LE(uint16(len(program)), b)
core.WriteUInt16LE(uint16(len(workdir)), b)
core.WriteUInt16LE(uint16(len(arguments)), b)
core.WriteBytes(program, b)
core.WriteBytes(workdir, b)
core.WriteBytes(arguments, b)
length += b.Len()
c.sendData(TS_RAIL_ORDER_EXEC, length, b.Bytes())
}
func (c *RailClient) processOrderSysparam(b []byte) {
r := bytes.NewReader(b)
systemParam, _ := core.ReadUInt32LE(r)
body, _ := core.ReadUInt8(r)
glog.Infof("systemParam:0x%x, body:%d", systemParam, body)
}
const (
//The Client Execute request was successful and the requested application or file has been launched.
RAIL_EXEC_S_OK = 0x0000
//The Client Execute request could not be satisfied because the server is not monitoring the current input desktop.
RAIL_EXEC_E_HOOK_NOT_LOADED = 0x0001
//The Execute request could not be satisfied because the request PDU was malformed.
RAIL_EXEC_E_DECODE_FAILED = 0x0002
//The Client Execute request could not be satisfied because the requested application was blocked by policy from being launched on the server.
RAIL_EXEC_E_NOT_IN_ALLOWLIST = 0x0003
//The Client Execute request could not be satisfied because the application or file path could not be found.
RAIL_EXEC_E_FILE_NOT_FOUND = 0x0005
//The Client Execute request could not be satisfied because an unspecified error occurred on the server.
RAIL_EXEC_E_FAIL = 0x0006
//The Client Execute request could not be satisfied because the remote session is locked.
RAIL_EXEC_E_SESSION_LOCKED = 0x0007
)
func (c *RailClient) processExecResult(b []byte) {
r := bytes.NewReader(b)
flags, _ := core.ReadUint16LE(r)
execResult, _ := core.ReadUint16LE(r)
rawResult, _ := core.ReadUInt32LE(r)
core.ReadUint16LE(r)
exeOrFileLength, _ := core.ReadUint16LE(r)
exeOrFile, _ := core.ReadBytes(r.Len(), r)
glog.Info("flags:", flags, "execResult:", execResult, "rawResult:", rawResult)
glog.Info("length:", exeOrFileLength, "file:", core.UnicodeDecode(exeOrFile))
}
-9
View File
@@ -1,9 +0,0 @@
package rdpgfx
import (
"github.com/shadow1ng/fscan/mylib/grdp/plugin"
)
const (
ChannelName = plugin.RDPGFX_DVC_CHANNEL_NAME
)
+2 -1
View File
@@ -909,7 +909,8 @@ func readFastPathUpdatePDU(r io.Reader, code uint8) (*FastPathUpdatePDU, error)
//glog.Debugf("FastPathPDU type %s(0x%x)", FastPathUpdateType(code), code)
switch code {
case FASTPATH_UPDATETYPE_ORDERS:
d = &FastPathOrdersPDU{}
// 绘图指令,认证检测不需要处理
return nil, errors.New(fmt.Sprintf("Unsupport FastPathPDU type 0x%x", code))
case FASTPATH_UPDATETYPE_BITMAP:
d = &FastPathBitmapUpdateDataPDU{}
case FASTPATH_UPDATETYPE_PALETTE:
-541
View File
@@ -1,541 +0,0 @@
package pdu
/* Binary Raster Operations (ROP2) */
const (
GDI_R2_BLACK = 0x01
GDI_R2_NOTMERGEPEN = 0x02
GDI_R2_MASKNOTPEN = 0x03
GDI_R2_NOTCOPYPEN = 0x04
GDI_R2_MASKPENNOT = 0x05
GDI_R2_NOT = 0x06
GDI_R2_XORPEN = 0x07
GDI_R2_NOTMASKPEN = 0x08
GDI_R2_MASKPEN = 0x09
GDI_R2_NOTXORPEN = 0x0A
GDI_R2_NOP = 0x0B
GDI_R2_MERGENOTPEN = 0x0C
GDI_R2_COPYPEN = 0x0D
GDI_R2_MERGEPENNOT = 0x0E
GDI_R2_MERGEPEN = 0x0F
GDI_R2_WHITE = 0x10
)
/* Ternary Raster Operations (ROP3) */
const (
GDI_BLACKNESS = 0x00000042
GDI_DPSoon = 0x00010289
GDI_DPSona = 0x00020C89
GDI_PSon = 0x000300AA
GDI_SDPona = 0x00040C88
GDI_DPon = 0x000500A9
GDI_PDSxnon = 0x00060865
GDI_PDSaon = 0x000702C5
GDI_SDPnaa = 0x00080F08
GDI_PDSxon = 0x00090245
GDI_DPna = 0x000A0329
GDI_PSDnaon = 0x000B0B2A
GDI_SPna = 0x000C0324
GDI_PDSnaon = 0x000D0B25
GDI_PDSonon = 0x000E08A5
GDI_Pn = 0x000F0001
GDI_PDSona = 0x00100C85
GDI_NOTSRCERASE = 0x001100A6
GDI_SDPxnon = 0x00120868
GDI_SDPaon = 0x001302C8
GDI_DPSxnon = 0x00140869
GDI_DPSaon = 0x001502C9
GDI_PSDPSanaxx = 0x00165CCA
GDI_SSPxDSxaxn = 0x00171D54
GDI_SPxPDxa = 0x00180D59
GDI_SDPSanaxn = 0x00191CC8
GDI_PDSPaox = 0x001A06C5
GDI_SDPSxaxn = 0x001B0768
GDI_PSDPaox = 0x001C06CA
GDI_DSPDxaxn = 0x001D0766
GDI_PDSox = 0x001E01A5
GDI_PDSoan = 0x001F0385
GDI_DPSnaa = 0x00200F09
GDI_SDPxon = 0x00210248
GDI_DSna = 0x00220326
GDI_SPDnaon = 0x00230B24
GDI_SPxDSxa = 0x00240D55
GDI_PDSPanaxn = 0x00251CC5
GDI_SDPSaox = 0x002606C8
GDI_SDPSxnox = 0x00271868
GDI_DPSxa = 0x00280369
GDI_PSDPSaoxxn = 0x002916CA
GDI_DPSana = 0x002A0CC9
GDI_SSPxPDxaxn = 0x002B1D58
GDI_SPDSoax = 0x002C0784
GDI_PSDnox = 0x002D060A
GDI_PSDPxox = 0x002E064A
GDI_PSDnoan = 0x002F0E2A
GDI_PSna = 0x0030032A
GDI_SDPnaon = 0x00310B28
GDI_SDPSoox = 0x00320688
GDI_NOTSRCCOPY = 0x00330008
GDI_SPDSaox = 0x003406C4
GDI_SPDSxnox = 0x00351864
GDI_SDPox = 0x003601A8
GDI_SDPoan = 0x00370388
GDI_PSDPoax = 0x0038078A
GDI_SPDnox = 0x00390604
GDI_SPDSxox = 0x003A0644
GDI_SPDnoan = 0x003B0E24
GDI_PSx = 0x003C004A
GDI_SPDSonox = 0x003D18A4
GDI_SPDSnaox = 0x003E1B24
GDI_PSan = 0x003F00EA
GDI_PSDnaa = 0x00400F0A
GDI_DPSxon = 0x00410249
GDI_SDxPDxa = 0x00420D5D
GDI_SPDSanaxn = 0x00431CC4
GDI_SRCERASE = 0x00440328
GDI_DPSnaon = 0x00450B29
GDI_DSPDaox = 0x004606C6
GDI_PSDPxaxn = 0x0047076A
GDI_SDPxa = 0x00480368
GDI_PDSPDaoxxn = 0x004916C5
GDI_DPSDoax = 0x004A0789
GDI_PDSnox = 0x004B0605
GDI_SDPana = 0x004C0CC8
GDI_SSPxDSxoxn = 0x004D1954
GDI_PDSPxox = 0x004E0645
GDI_PDSnoan = 0x004F0E25
GDI_PDna = 0x00500325
GDI_DSPnaon = 0x00510B26
GDI_DPSDaox = 0x005206C9
GDI_SPDSxaxn = 0x00530764
GDI_DPSonon = 0x005408A9
GDI_DSTINVERT = 0x00550009
GDI_DPSox = 0x005601A9
GDI_DPSoan = 0x00570389
GDI_PDSPoax = 0x00580785
GDI_DPSnox = 0x00590609
GDI_PATINVERT = 0x005A0049
GDI_DPSDonox = 0x005B18A9
GDI_DPSDxox = 0x005C0649
GDI_DPSnoan = 0x005D0E29
GDI_DPSDnaox = 0x005E1B29
GDI_DPan = 0x005F00E9
GDI_PDSxa = 0x00600365
GDI_DSPDSaoxxn = 0x006116C6
GDI_DSPDoax = 0x00620786
GDI_SDPnox = 0x00630608
GDI_SDPSoax = 0x00640788
GDI_DSPnox = 0x00650606
GDI_SRCINVERT = 0x00660046
GDI_SDPSonox = 0x006718A8
GDI_DSPDSonoxxn = 0x006858A6
GDI_PDSxxn = 0x00690145
GDI_DPSax = 0x006A01E9
GDI_PSDPSoaxxn = 0x006B178A
GDI_SDPax = 0x006C01E8
GDI_PDSPDoaxxn = 0x006D1785
GDI_SDPSnoax = 0x006E1E28
GDI_PDSxnan = 0x006F0C65
GDI_PDSana = 0x00700CC5
GDI_SSDxPDxaxn = 0x00711D5C
GDI_SDPSxox = 0x00720648
GDI_SDPnoan = 0x00730E28
GDI_DSPDxox = 0x00740646
GDI_DSPnoan = 0x00750E26
GDI_SDPSnaox = 0x00761B28
GDI_DSan = 0x007700E6
GDI_PDSax = 0x007801E5
GDI_DSPDSoaxxn = 0x00791786
GDI_DPSDnoax = 0x007A1E29
GDI_SDPxnan = 0x007B0C68
GDI_SPDSnoax = 0x007C1E24
GDI_DPSxnan = 0x007D0C69
GDI_SPxDSxo = 0x007E0955
GDI_DPSaan = 0x007F03C9
GDI_DPSaa = 0x008003E9
GDI_SPxDSxon = 0x00810975
GDI_DPSxna = 0x00820C49
GDI_SPDSnoaxn = 0x00831E04
GDI_SDPxna = 0x00840C48
GDI_PDSPnoaxn = 0x00851E05
GDI_DSPDSoaxx = 0x008617A6
GDI_PDSaxn = 0x008701C5
GDI_SRCAND = 0x008800C6
GDI_SDPSnaoxn = 0x00891B08
GDI_DSPnoa = 0x008A0E06
GDI_DSPDxoxn = 0x008B0666
GDI_SDPnoa = 0x008C0E08
GDI_SDPSxoxn = 0x008D0668
GDI_SSDxPDxax = 0x008E1D7C
GDI_PDSanan = 0x008F0CE5
GDI_PDSxna = 0x00900C45
GDI_SDPSnoaxn = 0x00911E08
GDI_DPSDPoaxx = 0x009217A9
GDI_SPDaxn = 0x009301C4
GDI_PSDPSoaxx = 0x009417AA
GDI_DPSaxn = 0x009501C9
GDI_DPSxx = 0x00960169
GDI_PSDPSonoxx = 0x0097588A
GDI_SDPSonoxn = 0x00981888
GDI_DSxn = 0x00990066
GDI_DPSnax = 0x009A0709
GDI_SDPSoaxn = 0x009B07A8
GDI_SPDnax = 0x009C0704
GDI_DSPDoaxn = 0x009D07A6
GDI_DSPDSaoxx = 0x009E16E6
GDI_PDSxan = 0x009F0345
GDI_DPa = 0x00A000C9
GDI_PDSPnaoxn = 0x00A11B05
GDI_DPSnoa = 0x00A20E09
GDI_DPSDxoxn = 0x00A30669
GDI_PDSPonoxn = 0x00A41885
GDI_PDxn = 0x00A50065
GDI_DSPnax = 0x00A60706
GDI_PDSPoaxn = 0x00A707A5
GDI_DPSoa = 0x00A803A9
GDI_DPSoxn = 0x00A90189
GDI_DSTCOPY = 0x00AA0029
GDI_DPSono = 0x00AB0889
GDI_SPDSxax = 0x00AC0744
GDI_DPSDaoxn = 0x00AD06E9
GDI_DSPnao = 0x00AE0B06
GDI_DPno = 0x00AF0229
GDI_PDSnoa = 0x00B00E05
GDI_PDSPxoxn = 0x00B10665
GDI_SSPxDSxox = 0x00B21974
GDI_SDPanan = 0x00B30CE8
GDI_PSDnax = 0x00B4070A
GDI_DPSDoaxn = 0x00B507A9
GDI_DPSDPaoxx = 0x00B616E9
GDI_SDPxan = 0x00B70348
GDI_PSDPxax = 0x00B8074A
GDI_DSPDaoxn = 0x00B906E6
GDI_DPSnao = 0x00BA0B09
GDI_MERGEPAINT = 0x00BB0226
GDI_SPDSanax = 0x00BC1CE4
GDI_SDxPDxan = 0x00BD0D7D
GDI_DPSxo = 0x00BE0269
GDI_DPSano = 0x00BF08C9
GDI_MERGECOPY = 0x00C000CA
GDI_SPDSnaoxn = 0x00C11B04
GDI_SPDSonoxn = 0x00C21884
GDI_PSxn = 0x00C3006A
GDI_SPDnoa = 0x00C40E04
GDI_SPDSxoxn = 0x00C50664
GDI_SDPnax = 0x00C60708
GDI_PSDPoaxn = 0x00C707AA
GDI_SDPoa = 0x00C803A8
GDI_SPDoxn = 0x00C90184
GDI_DPSDxax = 0x00CA0749
GDI_SPDSaoxn = 0x00CB06E4
GDI_SRCCOPY = 0x00CC0020
GDI_SDPono = 0x00CD0888
GDI_SDPnao = 0x00CE0B08
GDI_SPno = 0x00CF0224
GDI_PSDnoa = 0x00D00E0A
GDI_PSDPxoxn = 0x00D1066A
GDI_PDSnax = 0x00D20705
GDI_SPDSoaxn = 0x00D307A4
GDI_SSPxPDxax = 0x00D41D78
GDI_DPSanan = 0x00D50CE9
GDI_PSDPSaoxx = 0x00D616EA
GDI_DPSxan = 0x00D70349
GDI_PDSPxax = 0x00D80745
GDI_SDPSaoxn = 0x00D906E8
GDI_DPSDanax = 0x00DA1CE9
GDI_SPxDSxan = 0x00DB0D75
GDI_SPDnao = 0x00DC0B04
GDI_SDno = 0x00DD0228
GDI_SDPxo = 0x00DE0268
GDI_SDPano = 0x00DF08C8
GDI_PDSoa = 0x00E003A5
GDI_PDSoxn = 0x00E10185
GDI_DSPDxax = 0x00E20746
GDI_PSDPaoxn = 0x00E306EA
GDI_SDPSxax = 0x00E40748
GDI_PDSPaoxn = 0x00E506E5
GDI_SDPSanax = 0x00E61CE8
GDI_SPxPDxan = 0x00E70D79
GDI_SSPxDSxax = 0x00E81D74
GDI_DSPDSanaxxn = 0x00E95CE6
GDI_DPSao = 0x00EA02E9
GDI_DPSxno = 0x00EB0849
GDI_SDPao = 0x00EC02E8
GDI_SDPxno = 0x00ED0848
GDI_SRCPAINT = 0x00EE0086
GDI_SDPnoo = 0x00EF0A08
GDI_PATCOPY = 0x00F00021
GDI_PDSono = 0x00F10885
GDI_PDSnao = 0x00F20B05
GDI_PSno = 0x00F3022A
GDI_PSDnao = 0x00F40B0A
GDI_PDno = 0x00F50225
GDI_PDSxo = 0x00F60265
GDI_PDSano = 0x00F708C5
GDI_PDSao = 0x00F802E5
GDI_PDSxno = 0x00F90845
GDI_DPo = 0x00FA0089
GDI_PATPAINT = 0x00FB0A09
GDI_PSo = 0x00FC008A
GDI_PSDnoo = 0x00FD0A0A
GDI_DPSoo = 0x00FE02A9
GDI_WHITENESS = 0x00FF0062
GDI_GLYPH_ORDER = 0xFFFFFFFF
)
var Rop3CodeTable = map[int]string{
GDI_BLACKNESS: "0",
GDI_DPSoon: "DPSoon",
GDI_DPSona: "DPSona",
GDI_PSon: "PSon",
GDI_SDPona: "SDPona",
GDI_DPon: "DPon",
GDI_PDSxnon: "PDSxnon",
GDI_PDSaon: "PDSaon",
GDI_SDPnaa: "SDPnaa",
GDI_PDSxon: "PDSxon",
GDI_DPna: "DPna",
GDI_PSDnaon: "PSDnaon",
GDI_SPna: "SPna",
GDI_PDSnaon: "PDSnaon",
GDI_PDSonon: "PDSonon",
GDI_Pn: "Pn",
GDI_PDSona: "PDSona",
GDI_NOTSRCERASE: "DSon",
GDI_SDPxnon: "SDPxnon",
GDI_SDPaon: "SDPaon",
GDI_DPSxnon: "DPSxnon",
GDI_DPSaon: "DPSaon",
GDI_PSDPSanaxx: "PSDPSanaxx",
GDI_SSPxDSxaxn: "SSPxDSxaxn",
GDI_SPxPDxa: "SPxPDxa",
GDI_SDPSanaxn: "SDPSanaxn",
GDI_PDSPaox: "PDSPaox",
GDI_SDPSxaxn: "SDPSxaxn",
GDI_PSDPaox: "PSDPaox",
GDI_DSPDxaxn: "DSPDxaxn",
GDI_PDSox: "PDSox",
GDI_PDSoan: "PDSoan",
GDI_DPSnaa: "DPSnaa",
GDI_SDPxon: "SDPxon",
GDI_DSna: "DSna",
GDI_SPDnaon: "SPDnaon",
GDI_SPxDSxa: "SPxDSxa",
GDI_PDSPanaxn: "PDSPanaxn",
GDI_SDPSaox: "SDPSaox",
GDI_SDPSxnox: "SDPSxnox",
GDI_DPSxa: "DPSxa",
GDI_PSDPSaoxxn: "PSDPSaoxxn",
GDI_DPSana: "DPSana",
GDI_SSPxPDxaxn: "SSPxPDxaxn",
GDI_SPDSoax: "SPDSoax",
GDI_PSDnox: "PSDnox",
GDI_PSDPxox: "PSDPxox",
GDI_PSDnoan: "PSDnoan",
GDI_PSna: "PSna",
GDI_SDPnaon: "SDPnaon",
GDI_SDPSoox: "SDPSoox",
GDI_NOTSRCCOPY: "Sn",
GDI_SPDSaox: "SPDSaox",
GDI_SPDSxnox: "SPDSxnox",
GDI_SDPox: "SDPox",
GDI_SDPoan: "SDPoan",
GDI_PSDPoax: "PSDPoax",
GDI_SPDnox: "SPDnox",
GDI_SPDSxox: "SPDSxox",
GDI_SPDnoan: "SPDnoan",
GDI_PSx: "PSx",
GDI_SPDSonox: "SPDSonox",
GDI_SPDSnaox: "SPDSnaox",
GDI_PSan: "PSan",
GDI_PSDnaa: "PSDnaa",
GDI_DPSxon: "DPSxon",
GDI_SDxPDxa: "SDxPDxa",
GDI_SPDSanaxn: "SPDSanaxn",
GDI_SRCERASE: "SDna",
GDI_DPSnaon: "DPSnaon",
GDI_DSPDaox: "DSPDaox",
GDI_PSDPxaxn: "PSDPxaxn",
GDI_SDPxa: "SDPxa",
GDI_PDSPDaoxxn: "PDSPDaoxxn",
GDI_DPSDoax: "DPSDoax",
GDI_PDSnox: "PDSnox",
GDI_SDPana: "SDPana",
GDI_SSPxDSxoxn: "SSPxDSxoxn",
GDI_PDSPxox: "PDSPxox",
GDI_PDSnoan: "PDSnoan",
GDI_PDna: "PDna",
GDI_DSPnaon: "DSPnaon",
GDI_DPSDaox: "DPSDaox",
GDI_SPDSxaxn: "SPDSxaxn",
GDI_DPSonon: "DPSonon",
GDI_DSTINVERT: "Dn",
GDI_DPSox: "DPSox",
GDI_DPSoan: "DPSoan",
GDI_PDSPoax: "PDSPoax",
GDI_DPSnox: "DPSnox",
GDI_PATINVERT: "DPx",
GDI_DPSDonox: "DPSDonox",
GDI_DPSDxox: "DPSDxox",
GDI_DPSnoan: "DPSnoan",
GDI_DPSDnaox: "DPSDnaox",
GDI_DPan: "DPan",
GDI_PDSxa: "PDSxa",
GDI_DSPDSaoxxn: "DSPDSaoxxn",
GDI_DSPDoax: "DSPDoax",
GDI_SDPnox: "SDPnox",
GDI_SDPSoax: "SDPSoax",
GDI_DSPnox: "DSPnox",
GDI_SRCINVERT: "DSx",
GDI_SDPSonox: "SDPSonox",
GDI_DSPDSonoxxn: "DSPDSonoxxn",
GDI_PDSxxn: "PDSxxn",
GDI_DPSax: "DPSax",
GDI_PSDPSoaxxn: "PSDPSoaxxn",
GDI_SDPax: "SDPax",
GDI_PDSPDoaxxn: "PDSPDoaxxn",
GDI_SDPSnoax: "SDPSnoax",
GDI_PDSxnan: "PDSxnan",
GDI_PDSana: "PDSana",
GDI_SSDxPDxaxn: "SSDxPDxaxn",
GDI_SDPSxox: "SDPSxox",
GDI_SDPnoan: "SDPnoan",
GDI_DSPDxox: "DSPDxox",
GDI_DSPnoan: "DSPnoan",
GDI_SDPSnaox: "SDPSnaox",
GDI_DSan: "DSan",
GDI_PDSax: "PDSax",
GDI_DSPDSoaxxn: "DSPDSoaxxn",
GDI_DPSDnoax: "DPSDnoax",
GDI_SDPxnan: "SDPxnan",
GDI_SPDSnoax: "SPDSnoax",
GDI_DPSxnan: "DPSxnan",
GDI_SPxDSxo: "SPxDSxo",
GDI_DPSaan: "DPSaan",
GDI_DPSaa: "DPSaa",
GDI_SPxDSxon: "SPxDSxon",
GDI_DPSxna: "DPSxna",
GDI_SPDSnoaxn: "SPDSnoaxn",
GDI_SDPxna: "SDPxna",
GDI_PDSPnoaxn: "PDSPnoaxn",
GDI_DSPDSoaxx: "DSPDSoaxx",
GDI_PDSaxn: "PDSaxn",
GDI_SRCAND: "DSa",
GDI_SDPSnaoxn: "SDPSnaoxn",
GDI_DSPnoa: "DSPnoa",
GDI_DSPDxoxn: "DSPDxoxn",
GDI_SDPnoa: "SDPnoa",
GDI_SDPSxoxn: "SDPSxoxn",
GDI_SSDxPDxax: "SSDxPDxax",
GDI_PDSanan: "PDSanan",
GDI_PDSxna: "PDSxna",
GDI_SDPSnoaxn: "SDPSnoaxn",
GDI_DPSDPoaxx: "DPSDPoaxx",
GDI_SPDaxn: "SPDaxn",
GDI_PSDPSoaxx: "PSDPSoaxx",
GDI_DPSaxn: "DPSaxn",
GDI_DPSxx: "DPSxx",
GDI_PSDPSonoxx: "PSDPSonoxx",
GDI_SDPSonoxn: "SDPSonoxn",
GDI_DSxn: "DSxn",
GDI_DPSnax: "DPSnax",
GDI_SDPSoaxn: "SDPSoaxn",
GDI_SPDnax: "SPDnax",
GDI_DSPDoaxn: "DSPDoaxn",
GDI_DSPDSaoxx: "DSPDSaoxx",
GDI_PDSxan: "PDSxan",
GDI_DPa: "DPa",
GDI_PDSPnaoxn: "PDSPnaoxn",
GDI_DPSnoa: "DPSnoa",
GDI_DPSDxoxn: "DPSDxoxn",
GDI_PDSPonoxn: "PDSPonoxn",
GDI_PDxn: "PDxn",
GDI_DSPnax: "DSPnax",
GDI_PDSPoaxn: "PDSPoaxn",
GDI_DPSoa: "DPSoa",
GDI_DPSoxn: "DPSoxn",
GDI_DSTCOPY: "D",
GDI_DPSono: "DPSono",
GDI_SPDSxax: "SPDSxax",
GDI_DPSDaoxn: "DPSDaoxn",
GDI_DSPnao: "DSPnao",
GDI_DPno: "DPno",
GDI_PDSnoa: "PDSnoa",
GDI_PDSPxoxn: "PDSPxoxn",
GDI_SSPxDSxox: "SSPxDSxox",
GDI_SDPanan: "SDPanan",
GDI_PSDnax: "PSDnax",
GDI_DPSDoaxn: "DPSDoaxn",
GDI_DPSDPaoxx: "DPSDPaoxx",
GDI_SDPxan: "SDPxan",
GDI_PSDPxax: "PSDPxax",
GDI_DSPDaoxn: "DSPDaoxn",
GDI_DPSnao: "DPSnao",
GDI_MERGEPAINT: "DSno",
GDI_SPDSanax: "SPDSanax",
GDI_SDxPDxan: "SDxPDxan",
GDI_DPSxo: "DPSxo",
GDI_DPSano: "DPSano",
GDI_MERGECOPY: "PSa",
GDI_SPDSnaoxn: "SPDSnaoxn",
GDI_SPDSonoxn: "SPDSonoxn",
GDI_PSxn: "PSxn",
GDI_SPDnoa: "SPDnoa",
GDI_SPDSxoxn: "SPDSxoxn",
GDI_SDPnax: "SDPnax",
GDI_PSDPoaxn: "PSDPoaxn",
GDI_SDPoa: "SDPoa",
GDI_SPDoxn: "SPDoxn",
GDI_DPSDxax: "DPSDxax",
GDI_SPDSaoxn: "SPDSaoxn",
GDI_SRCCOPY: "S",
GDI_SDPono: "SDPono",
GDI_SDPnao: "SDPnao",
GDI_SPno: "SPno",
GDI_PSDnoa: "PSDnoa",
GDI_PSDPxoxn: "PSDPxoxn",
GDI_PDSnax: "PDSnax",
GDI_SPDSoaxn: "SPDSoaxn",
GDI_SSPxPDxax: "SSPxPDxax",
GDI_DPSanan: "DPSanan",
GDI_PSDPSaoxx: "PSDPSaoxx",
GDI_DPSxan: "DPSxan",
GDI_PDSPxax: "PDSPxax",
GDI_SDPSaoxn: "SDPSaoxn",
GDI_DPSDanax: "DPSDanax",
GDI_SPxDSxan: "SPxDSxan",
GDI_SPDnao: "SPDnao",
GDI_SDno: "SDno",
GDI_SDPxo: "SDPxo",
GDI_SDPano: "SDPano",
GDI_PDSoa: "PDSoa",
GDI_PDSoxn: "PDSoxn",
GDI_DSPDxax: "DSPDxax",
GDI_PSDPaoxn: "PSDPaoxn",
GDI_SDPSxax: "SDPSxax",
GDI_PDSPaoxn: "PDSPaoxn",
GDI_SDPSanax: "SDPSanax",
GDI_SPxPDxan: "SPxPDxan",
GDI_SSPxDSxax: "SSPxDSxax",
GDI_DSPDSanaxxn: "DSPDSanaxxn",
GDI_DPSao: "DPSao",
GDI_DPSxno: "DPSxno",
GDI_SDPao: "SDPao",
GDI_SDPxno: "SDPxno",
GDI_SRCPAINT: "DSo",
GDI_SDPnoo: "SDPnoo",
GDI_PATCOPY: "P",
GDI_PDSono: "PDSono",
GDI_PDSnao: "PDSnao",
GDI_PSno: "PSno",
GDI_PSDnao: "PSDnao",
GDI_PDno: "PDno",
GDI_PDSxo: "PDSxo",
GDI_PDSano: "PDSano",
GDI_PDSao: "PDSao",
GDI_PDSxno: "PDSxno",
GDI_DPo: "DPo",
GDI_PATPAINT: "DPSnoo",
GDI_PSo: "PSo",
GDI_PSDnoo: "PSDnoo",
GDI_DPSoo: "DPSoo",
GDI_WHITENESS: "1",
}
File diff suppressed because it is too large Load Diff
-4
View File
@@ -383,8 +383,6 @@ func (c *Client) recvPDU(s []byte) {
p := up.Udata
if up.UpdateType == FASTPATH_UPDATETYPE_BITMAP {
c.Emit("bitmap", p.(*BitmapUpdateDataPDU).Rectangles)
} else if up.UpdateType == FASTPATH_UPDATETYPE_ORDERS {
c.Emit("orders", p.(*FastPathOrdersPDU).OrderPdus)
}
}
if d.Header.PDUType2 == PDUTYPE2_SAVE_SESSION_INFO {
@@ -445,8 +443,6 @@ func (c *Client) RecvFastPath(secFlag byte, s []byte) {
c.Emit("bitmap", p.Data.(*FastPathBitmapUpdateDataPDU).Rectangles)
} else if updateCode == FASTPATH_UPDATETYPE_COLOR {
c.Emit("color", p.Data.(*FastPathColorPdu))
} else if updateCode == FASTPATH_UPDATETYPE_ORDERS {
c.Emit("orders", p.Data.(*FastPathOrdersPDU).OrderPdus)
}
}
}
-457
View File
@@ -1,457 +0,0 @@
// rfb.go
package rfb
import (
"bytes"
"crypto/des"
"encoding/hex"
"errors"
"fmt"
"io"
"log"
"net"
"github.com/lunixbochs/struc"
"github.com/shadow1ng/fscan/mylib/grdp/core"
"github.com/shadow1ng/fscan/mylib/grdp/emission"
"github.com/shadow1ng/fscan/mylib/grdp/glog"
)
// ProtocolVersion
const (
RFB003003 = "RFB 003.003\n"
RFB003007 = "RFB 003.007\n"
RFB003008 = "RFB 003.008\n"
)
// SecurityType
const (
SEC_INVALID uint8 = 0
SEC_NONE uint8 = 1
SEC_VNC uint8 = 2
)
type RFBConn struct {
emission.Emitter
// The Socket connection to the client
Conn net.Conn
s *ServerInit
NbRect uint16
BitRect *BitRect
Password string
}
func NewRFBConn(s net.Conn, passwd string) *RFBConn {
fc := &RFBConn{
Emitter: *emission.NewEmitter(),
Conn: s,
BitRect: new(BitRect),
Password: passwd,
}
core.StartReadBytes(12, fc, fc.recvProtocolVersion)
return fc
}
func (fc *RFBConn) Read(b []byte) (n int, err error) {
return fc.Conn.Read(b)
}
func (fc *RFBConn) Write(data []byte) (n int, err error) {
buff := &bytes.Buffer{}
buff.Write(data)
return fc.Conn.Write(buff.Bytes())
}
func (fc *RFBConn) Close() error {
return fc.Conn.Close()
}
func (fc *RFBConn) recvProtocolVersion(s []byte, err error) {
version := string(s)
glog.Debug("RFBConn recvProtocolVersion", version, err)
if err != nil {
fc.Emit("error", err)
return
}
fc.Emit("data", version)
if version == RFB003003 {
fc.Emit("error", fmt.Errorf("%s", "Not Support RFB003003"))
return
//core.StartReadBytes(4, fc, fc.recvSecurityServer)
} else {
core.StartReadBytes(1, fc, fc.checkSecurityList)
}
}
func (fc *RFBConn) checkSecurityList(s []byte, err error) {
r := bytes.NewReader(s)
result, _ := core.ReadUInt8(r)
glog.Debug("RFBConn recvSecurityList", result, err)
core.StartReadBytes(int(result), fc, fc.recvSecurityList)
}
func (fc *RFBConn) recvSecurityList(s []byte, err error) {
r := bytes.NewReader(s)
secLevel := SEC_VNC
for r.Len() > 0 {
result, _ := core.ReadUInt8(r)
if result == SEC_NONE || result == SEC_VNC {
secLevel = result
break
}
}
glog.Debug("RFBConn recvSecurityList", secLevel, err)
buff := &bytes.Buffer{}
core.WriteUInt8(secLevel, buff)
fc.Write(buff.Bytes())
if secLevel == SEC_VNC {
core.StartReadBytes(16, fc, fc.recvVNCChallenge)
} else {
core.StartReadBytes(4, fc, fc.recvSecurityResult)
}
}
func fixDesKeyByte(val byte) byte {
var newval byte = 0
for i := 0; i < 8; i++ {
newval <<= 1
newval += (val & 1)
val >>= 1
}
return newval
}
// fixDesKey will make sure that exactly 8 bytes is used either by truncating or padding with nulls
// The bytes are then bit mirrored and returned
func fixDesKey(key []byte) []byte {
tmp := key
buf := make([]byte, 8)
if len(tmp) <= 8 {
copy(buf, tmp)
} else {
copy(buf, tmp[:8])
}
for i := 0; i < 8; i++ {
buf[i] = fixDesKeyByte(buf[i])
}
return buf
}
func (fc *RFBConn) recvVNCChallenge(s []byte, err error) {
glog.Debug("RFBConn recvVNCChallenge", hex.EncodeToString(s), len(s), err)
key := core.UnicodeEncode(fc.Password)
bk, err := des.NewCipher(fixDesKey(key))
if err != nil {
log.Printf("Error generating authentication cipher: %s\n", err.Error())
return
}
result := make([]byte, 16)
bk.Encrypt(result, s) //Encrypt first 8 bytes
bk.Encrypt(result[8:], s[8:])
if err != nil {
fmt.Println(err)
}
fmt.Println(string(result))
fc.Write(result)
core.StartReadBytes(4, fc, fc.recvSecurityResult)
}
func (fc *RFBConn) recvSecurityResult(s []byte, err error) {
r := bytes.NewReader(s)
result, _ := core.ReadUInt32BE(r)
glog.Debug("RFBConn recvSecurityResult", result, err)
if result == 1 {
fc.Emit("error", fmt.Errorf("%s", "Authentification failed"))
return
}
buff := &bytes.Buffer{}
core.WriteUInt8(0, buff) //share
fc.Write(buff.Bytes())
core.StartReadBytes(20, fc, fc.recvServerInit)
}
type ServerInit struct {
Width uint16 `struc:"little"`
Height uint16 `struc:"little"`
PixelFormat *PixelFormat `struc:"little"`
}
func (fc *RFBConn) recvServerInit(s []byte, err error) {
glog.Debug("RFBConn recvServerInit", len(s), err)
r := bytes.NewReader(s)
si := &ServerInit{}
si.Width, err = core.ReadUint16BE(r)
si.Height, err = core.ReadUint16BE(r)
si.PixelFormat = ReadPixelFormat(r)
glog.Infof("serverInit:%+v, %+v", si, si.PixelFormat)
fc.s = si
fc.BitRect.Pf = si.PixelFormat
core.StartReadBytes(4, fc, fc.checkServerName)
}
func (fc *RFBConn) checkServerName(s []byte, err error) {
r := bytes.NewReader(s)
result, _ := core.ReadUInt32BE(r)
glog.Debug("RFBConn recvSecurityList", result, err)
core.StartReadBytes(int(result), fc, fc.recvServerName)
}
func (fc *RFBConn) recvServerName(s []byte, err error) {
glog.Debug("RFBConn recvServerName", string(s), err)
//fc.sendPixelFormat()
fc.sendSetEncoding()
fc.sendFramebufferUpdateRequest(0, 0, 0, fc.s.Width, fc.s.Height)
fc.Emit("ready")
core.StartReadBytes(1, fc, fc.recvServerOrder)
}
func (fc *RFBConn) sendSetEncoding() {
glog.Debug("sendSetEncoding")
buff := &bytes.Buffer{}
core.WriteUInt8(2, buff)
core.WriteUInt8(0, buff)
core.WriteUInt16BE(1, buff)
core.WriteUInt32BE(0, buff)
fc.Write(buff.Bytes())
}
type FrameBufferUpdateRequest struct {
Incremental uint8
X uint16
Y uint16
Width uint16
Height uint16
}
func (fc *RFBConn) sendFramebufferUpdateRequest(Incremental uint8,
X uint16,
Y uint16,
Width uint16,
Height uint16) {
glog.Debug("sendFramebufferUpdateRequest")
buff := &bytes.Buffer{}
core.WriteUInt8(3, buff)
core.WriteUInt8(Incremental, buff)
core.WriteUInt16BE(X, buff)
core.WriteUInt16BE(Y, buff)
core.WriteUInt16BE(Width, buff)
core.WriteUInt16BE(Height, buff)
fc.Write(buff.Bytes())
}
func (fc *RFBConn) recvServerOrder(s []byte, err error) {
glog.Debug("RFBConn recvServerOrder", hex.EncodeToString(s), err)
r := bytes.NewReader(s)
packetType, _ := core.ReadUInt8(r)
switch packetType {
case 0:
core.StartReadBytes(3, fc, fc.recvFrameBufferUpdateHeader)
case 2:
//TODO
case 3:
core.StartReadBytes(7, fc, fc.recvServerCutTextHeader)
default:
glog.Errorf("Unknown message type %d", packetType)
}
}
type BitRect struct {
Rects []Rectangles
Pf *PixelFormat
}
type Rectangles struct {
Rect *Rectangle
Data []byte
}
func (fc *RFBConn) recvFrameBufferUpdateHeader(s []byte, err error) {
glog.Debug("RFBConn recvFrameBufferUpdateHeader", hex.EncodeToString(s), err)
r := bytes.NewReader(s)
core.ReadUInt8(r)
NbRect, _ := core.ReadUint16BE(r)
fc.NbRect = NbRect
fc.BitRect.Rects = make([]Rectangles, fc.NbRect)
if NbRect == 0 {
return
}
glog.Info("NbRect:", NbRect)
core.StartReadBytes(12, fc, fc.recvRectHeader)
}
type Rectangle struct {
X uint16 `struc:"little"`
Y uint16 `struc:"little"`
Width uint16 `struc:"little"`
Height uint16 `struc:"little"`
Encoding uint32 `struc:"little"`
}
func (fc *RFBConn) recvRectHeader(s []byte, err error) {
glog.Debug("RFBConn recvRectHeader", hex.EncodeToString(s), err)
r := bytes.NewReader(s)
x, err := core.ReadUint16BE(r)
y, err := core.ReadUint16BE(r)
w, err := core.ReadUint16BE(r)
h, err := core.ReadUint16BE(r)
e, err := core.ReadUInt32BE(r)
rect := &Rectangle{x, y, w, h, e}
fc.BitRect.Rects[fc.NbRect-1].Rect = rect
glog.Infof("rect:%+v, len=%d", rect, int(rect.Width)*int(rect.Height)*4)
core.StartReadBytes(int(rect.Width)*int(rect.Height)*4, fc, fc.recvRectBody)
}
func (fc *RFBConn) recvRectBody(s []byte, err error) {
glog.Debug("RFBConn recvRectBody", hex.EncodeToString(s), err)
fc.BitRect.Rects[fc.NbRect-1].Data = s
fc.NbRect--
glog.Info("fc.NbRect:", fc.NbRect)
if fc.NbRect == 0 {
fc.Emit("bitmap", fc.BitRect)
fc.sendFramebufferUpdateRequest(1, 0, 0, fc.s.Width, fc.s.Height)
core.StartReadBytes(1, fc, fc.recvServerOrder)
} else {
core.StartReadBytes(12, fc, fc.recvRectHeader)
}
}
type ServerCutTextHeader struct {
Padding [3]byte `struc:"little"`
Size uint32 `struc:"little"`
}
func (fc *RFBConn) recvServerCutTextHeader(s []byte, err error) {
glog.Debug("RFBConn recvServerCutTextHeader", string(s), err)
r := bytes.NewReader(s)
header := &ServerCutTextHeader{}
err = struc.Unpack(r, header)
if err != nil {
fc.Emit("error", err)
return
}
core.StartReadBytes(int(header.Size), fc, fc.recvServerCutTextBody)
}
func (fc *RFBConn) recvServerCutTextBody(s []byte, err error) {
glog.Debug("RFBConn recvServerCutTextBody", string(s), err)
fc.Emit("CutText", s)
core.StartReadBytes(1, fc, fc.recvServerOrder)
}
type PixelFormat struct {
BitsPerPixel uint8 `struc:"little"`
Depth uint8 `struc:"little"`
BigEndianFlag uint8 `struc:"little"`
TrueColorFlag uint8 `struc:"little"`
RedMax uint16 `struc:"little"`
GreenMax uint16 `struc:"little"`
BlueMax uint16 `struc:"little"`
RedShift uint8 `struc:"little"`
GreenShift uint8 `struc:"little"`
BlueShift uint8 `struc:"little"`
Padding uint16 `struc:"little"`
Padding1 uint8 `struc:"little"`
}
func ReadPixelFormat(r io.Reader) *PixelFormat {
p := NewPixelFormat()
p.BitsPerPixel, _ = core.ReadUInt8(r)
p.Depth, _ = core.ReadUInt8(r)
p.BigEndianFlag, _ = core.ReadUInt8(r)
p.TrueColorFlag, _ = core.ReadUInt8(r)
p.RedMax, _ = core.ReadUint16BE(r)
p.GreenMax, _ = core.ReadUint16BE(r)
p.BlueMax, _ = core.ReadUint16BE(r)
p.RedShift, _ = core.ReadUInt8(r)
p.GreenShift, _ = core.ReadUInt8(r)
p.BlueShift, _ = core.ReadUInt8(r)
p.Padding, _ = core.ReadUint16BE(r)
p.Padding1, _ = core.ReadUInt8(r)
return p
}
func NewPixelFormat() *PixelFormat {
return &PixelFormat{
32, 24, 0, 1, 65280, 65280, 65280, 16, 8, 0, 0, 0,
}
}
type RFB struct {
core.Transport
Version string
SecurityLevel uint8
ServerName string
PixelFormat *PixelFormat
NbRect int
CurrentRect *Rectangle
}
func NewRFB(t core.Transport) *RFB {
fb := &RFB{t, RFB003008, SEC_INVALID, "", NewPixelFormat(), 0, &Rectangle{}}
return fb
}
func (fb *RFB) Connect() error {
if fb.Transport == nil {
return errors.New("no transport")
}
fb.Once("data", fb.recvProtocolVersion)
return nil
}
func (fb *RFB) recvProtocolVersion(version string) {
if version != RFB003003 && version != RFB003007 && version != RFB003008 {
version = RFB003008
}
glog.Infof("version:%s", version)
b := &bytes.Buffer{}
b.WriteString(version)
fb.Write(b.Bytes())
}
type KeyEvent struct {
DownFlag uint8 `struc:"little"`
Padding uint16 `struc:"little"`
Key uint32 `struc:"little"`
}
func (fb *RFB) SendKeyEvent(k *KeyEvent) {
b := &bytes.Buffer{}
core.WriteUInt8(4, b)
core.WriteUInt8(k.DownFlag, b)
core.WriteUInt16BE(k.Padding, b)
core.WriteUInt32BE(k.Key, b)
fmt.Println(b.Bytes())
fb.Write(b.Bytes())
}
type PointerEvent struct {
Mask uint8 `struc:"little"`
XPos uint16 `struc:"little"`
YPos uint16 `struc:"little"`
}
func (fb *RFB) SendPointEvent(p *PointerEvent) {
b := &bytes.Buffer{}
core.WriteUInt8(5, b)
core.WriteUInt8(p.Mask, b)
core.WriteUInt16BE(p.XPos, b)
core.WriteUInt16BE(p.YPos, b)
fmt.Println(b.Bytes())
fb.Write(b.Bytes())
}
type ClientCutText struct {
Padding uint16 `struc:"little"`
Padding1 uint8 `struc:"little"`
Size uint32 `struc:"little"`
Message string `struc:"little"`
}
func (fb *RFB) SendClientCutText(t *ClientCutText) {
b := &bytes.Buffer{}
core.WriteUInt8(6, b)
struc.Pack(b, t)
fb.Write(b.Bytes())
}