diff --git a/mylib/grdp/client/client.go b/mylib/grdp/client/client.go deleted file mode 100644 index 1a16757..0000000 --- a/mylib/grdp/client/client.go +++ /dev/null @@ -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) {} diff --git a/mylib/grdp/client/rdp.go b/mylib/grdp/client/rdp.go deleted file mode 100644 index 33b08d0..0000000 --- a/mylib/grdp/client/rdp.go +++ /dev/null @@ -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() - } -} diff --git a/mylib/grdp/client/rfb.go b/mylib/grdp/client/rfb.go deleted file mode 100644 index af2f3d0..0000000 --- a/mylib/grdp/client/rfb.go +++ /dev/null @@ -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() - } -} diff --git a/mylib/grdp/core/io.go b/mylib/grdp/core/io.go index dc47f4f..de810d2 100644 --- a/mylib/grdp/core/io.go +++ b/mylib/grdp/core/io.go @@ -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 -} diff --git a/mylib/grdp/core/rle.go b/mylib/grdp/core/rle.go deleted file mode 100644 index 3d7c628..0000000 --- a/mylib/grdp/core/rle.go +++ /dev/null @@ -1,1085 +0,0 @@ -package core - -import ( - "github.com/shadow1ng/fscan/mylib/grdp/glog" - "unsafe" -) - -func CVAL(p *[]uint8) int { - a := int((*p)[0]) - *p = (*p)[1:] - return a -} - -func CVAL2(p *[]uint8, v *uint16) { - *v = *((*uint16)(unsafe.Pointer(&(*p)[0]))) - *p = (*p)[2:] -} - -func CVAL3(p *[]uint8, v *[3]uint8) { - (*v)[0] = (*p)[0] - (*v)[1] = (*p)[1] - (*v)[2] = (*p)[2] - *p = (*p)[3:] -} - -func REPEAT(f func(), count *int, x *int, width int) { - for (*count & ^0x7) != 0 && ((*x + 8) < width) { - for i := 0; i < 8; i++ { - f() - *count = *count - 1 - *x = *x + 1 - } - } - - for (*count > 0) && (*x < width) { - f() - *count = *count - 1 - *x = *x + 1 - } -} - -/* 1 byte bitmap decompress */ -func decompress1(output *[]uint8, width, height int, input []uint8, size int) bool { - var ( - prevline, line, count int - offset, code int - x int = width - opcode int - lastopcode int8 = -1 - insertmix, bicolour, isfillormix bool - mixmask, mask uint8 - colour1, colour2 uint8 - mix uint8 = 0xff - fom_mask uint8 - ) - out := *output - for len(input) != 0 { - fom_mask = 0 - code = CVAL(&input) - opcode = code >> 4 - /* Handle different opcode forms */ - switch opcode { - case 0xc, 0xd, 0xe: - opcode -= 6 - count = int(code & 0xf) - offset = 16 - case 0xf: - opcode = code & 0xf - if opcode < 9 { - count = int(CVAL(&input)) - count |= int(CVAL(&input) << 8) - } else { - count = 1 - if opcode < 0xb { - count = 8 - } - } - offset = 0 - default: - opcode >>= 1 - count = int(code & 0x1f) - offset = 32 - } - /* Handle strange cases for counts */ - if offset != 0 { - isfillormix = ((opcode == 2) || (opcode == 7)) - if count == 0 { - if isfillormix { - count = int(CVAL(&input)) + 1 - } else { - count = int(CVAL(&input) + offset) - } - } else if isfillormix { - count <<= 3 - } - } - /* Read preliminary data */ - switch opcode { - case 0: /* Fill */ - if (lastopcode == int8(opcode)) && !((x == width) && (prevline == 0)) { - insertmix = true - } - break - case 8: /* Bicolour */ - colour1 = uint8(CVAL(&input)) - colour2 = uint8(CVAL(&input)) - break - case 3: /* Colour */ - colour2 = uint8(CVAL(&input)) - break - case 6: /* SetMix/Mix */ - fallthrough - case 7: /* SetMix/FillOrMix */ - mix = uint8(CVAL(&input)) - opcode -= 5 - break - case 9: /* FillOrMix_1 */ - mask = 0x03 - opcode = 0x02 - fom_mask = 3 - break - case 0x0a: /* FillOrMix_2 */ - mask = 0x05 - opcode = 0x02 - fom_mask = 5 - break - } - lastopcode = int8(opcode) - mixmask = 0 - /* Output body */ - for count > 0 { - if x >= width { - if height <= 0 { - return false - } - - x = 0 - height-- - prevline = line - line = height * width - } - switch opcode { - case 0: /* Fill */ - if insertmix { - if prevline == 0 { - out[x+line] = mix - } else { - out[x+line] = out[prevline+x] ^ mix - } - insertmix = false - count-- - x++ - } - if prevline == 0 { - REPEAT(func() { - out[x+line] = 0 - }, &count, &x, width) - } else { - REPEAT(func() { - out[x+line] = out[prevline+x] - }, &count, &x, width) - } - break - case 1: /* Mix */ - if prevline == 0 { - REPEAT(func() { - out[x+line] = mix - }, &count, &x, width) - } else { - REPEAT(func() { - out[x+line] = out[prevline+x] ^ mix - }, &count, &x, width) - } - break - case 2: /* Fill or Mix */ - if prevline == 0 { - REPEAT(func() { - mixmask <<= 1 - if mixmask == 0 { - mask = fom_mask - if fom_mask == 0 { - mask = uint8(CVAL(&input)) - mixmask = 1 - } - } - if mask&mixmask != 0 { - out[x+line] = mix - } else { - out[x+line] = 0 - } - }, &count, &x, width) - } else { - REPEAT(func() { - mixmask = mixmask << 1 - if mixmask == 0 { - mask = fom_mask - if fom_mask == 0 { - mask = uint8(CVAL(&input)) - mixmask = 1 - } - } - if mask&mixmask != 0 { - out[x+line] = out[prevline+x] ^ mix - } else { - out[x+line] = out[prevline+x] - } - }, &count, &x, width) - } - break - case 3: /* Colour */ - REPEAT(func() { - out[x+line] = colour2 - }, &count, &x, width) - break - case 4: /* Copy */ - REPEAT(func() { - out[x+line] = uint8(CVAL(&input)) - }, &count, &x, width) - break - case 8: /* Bicolour */ - REPEAT(func() { - if bicolour { - out[x+line] = colour2 - bicolour = false - } else { - out[x+line] = colour1 - bicolour = true - count++ - } - }, &count, &x, width) - - break - - case 0xd: /* White */ - REPEAT(func() { - out[x+line] = 0xff - }, &count, &x, width) - break - case 0xe: /* Black */ - REPEAT(func() { - out[x+line] = 0 - }, &count, &x, width) - break - default: - glog.Debugf("bitmap opcode 0x%x\n", opcode) - return false - } - } - } - return true -} - -/* 2 byte bitmap decompress */ -func decompress2(output *[]uint8, width, height int, input []uint8, size int) bool { - var ( - prevline, line, count int - offset, code int - x int = width - opcode int - lastopcode int = -1 - insertmix, bicolour, isfillormix bool - mixmask, mask uint8 - colour1, colour2 uint16 - mix uint16 = 0xffff - fom_mask uint8 - ) - - out := make([]uint16, width*height) - for len(input) != 0 { - fom_mask = 0 - code = CVAL(&input) - opcode = code >> 4 - /* Handle different opcode forms */ - switch opcode { - case 0xc, 0xd, 0xe: - opcode -= 6 - count = code & 0xf - offset = 16 - break - case 0xf: - opcode = code & 0xf - if opcode < 9 { - count = CVAL(&input) - count |= CVAL(&input) << 8 - } else { - count = 1 - if opcode < 0xb { - count = 8 - } - } - offset = 0 - break - default: - opcode >>= 1 - count = code & 0x1f - offset = 32 - break - } - - /* Handle strange cases for counts */ - if offset != 0 { - isfillormix = ((opcode == 2) || (opcode == 7)) - if count == 0 { - if isfillormix { - count = CVAL(&input) + 1 - } else { - count = CVAL(&input) + offset - } - } else if isfillormix { - count <<= 3 - } - } - /* Read preliminary data */ - switch opcode { - case 0: /* Fill */ - if (lastopcode == opcode) && !((x == width) && (prevline == 0)) { - insertmix = true - } - break - case 8: /* Bicolour */ - CVAL2(&input, &colour1) - CVAL2(&input, &colour2) - break - case 3: /* Colour */ - CVAL2(&input, &colour2) - break - case 6: /* SetMix/Mix */ - fallthrough - case 7: /* SetMix/FillOrMix */ - CVAL2(&input, &mix) - opcode -= 5 - break - case 9: /* FillOrMix_1 */ - mask = 0x03 - opcode = 0x02 - fom_mask = 3 - break - case 0x0a: /* FillOrMix_2 */ - mask = 0x05 - opcode = 0x02 - fom_mask = 5 - break - } - lastopcode = opcode - mixmask = 0 - /* Output body */ - for count > 0 { - if x >= width { - if height <= 0 { - return false - } - - x = 0 - height-- - prevline = line - line = height * width - } - switch opcode { - case 0: /* Fill */ - if insertmix { - if prevline == 0 { - out[x+line] = mix - } else { - out[x+line] = out[prevline+x] ^ mix - } - insertmix = false - count-- - x++ - } - if prevline == 0 { - REPEAT(func() { - out[x+line] = 0 - }, &count, &x, width) - } else { - REPEAT(func() { - out[x+line] = out[prevline+x] - }, &count, &x, width) - } - break - case 1: /* Mix */ - if prevline == 0 { - REPEAT(func() { - out[x+line] = mix - }, &count, &x, width) - } else { - REPEAT(func() { - out[x+line] = out[prevline+x] ^ mix - }, &count, &x, width) - } - break - case 2: /* Fill or Mix */ - if prevline == 0 { - REPEAT(func() { - mixmask <<= 1 - if mixmask == 0 { - mask = fom_mask - if fom_mask == 0 { - mask = uint8(CVAL(&input)) - mixmask = 1 - } - } - if mask&mixmask != 0 { - out[x+line] = mix - } else { - out[x+line] = 0 - } - }, &count, &x, width) - } else { - REPEAT(func() { - mixmask = mixmask << 1 - if mixmask == 0 { - mask = fom_mask - if fom_mask == 0 { - mask = uint8(CVAL(&input)) - mixmask = 1 - } - } - if mask&mixmask != 0 { - out[x+line] = out[prevline+x] ^ mix - } else { - out[x+line] = out[prevline+x] - } - }, &count, &x, width) - } - break - case 3: /* Colour */ - REPEAT(func() { - out[x+line] = colour2 - }, &count, &x, width) - break - case 4: /* Copy */ - REPEAT(func() { - var a uint16 - CVAL2(&input, &a) - out[x+line] = a - }, &count, &x, width) - - break - case 8: /* Bicolour */ - REPEAT(func() { - if bicolour { - out[x+line] = colour2 - bicolour = false - } else { - out[x+line] = colour1 - bicolour = true - count++ - } - }, &count, &x, width) - - break - case 0xd: /* White */ - REPEAT(func() { - out[x+line] = 0xffff - }, &count, &x, width) - break - case 0xe: /* Black */ - REPEAT(func() { - out[x+line] = 0 - }, &count, &x, width) - break - default: - glog.Debugf("bitmap opcode 0x%x\n", opcode) - return false - } - } - } - j := 0 - for _, v := range out { - (*output)[j], (*output)[j+1] = PutUint16BE(v) - //(*output)[j+1], (*output)[j] = PutUint16BE(v) - j += 2 - } - return true -} - -//func decompress2(output *[]uint8, width, height int, input []uint8, size int) bool { -// var ( -// prevline, line int -// opcode, count, offset, code int -// x int = width -// lastopcode int = -1 -// insertmix, bicolour, isfillormix bool -// mixmask, mask uint8 -// colour1, colour2 uint16 -// mix uint16 = 0xffff -// fom_mask uint8 -// ) -// -// out := make([]uint16, width*height) -// for len(input) != 0 { -// fom_mask = 0 -// code = CVAL(&input) -// opcode = code >> 4 -// /* Handle different opcode forms */ -// switch opcode { -// case 0xc, 0xd, 0xe: -// opcode -= 6 -// count = code & 0xf -// offset = 16 -// break -// case 0xf: -// opcode = code & 0xf -// if opcode < 9 { -// count = CVAL(&input) -// count |= CVAL(&input) << 8 -// } else { -// count = 1 -// if opcode < 0xb { -// count = 8 -// } -// } -// offset = 0 -// break -// default: -// opcode >>= 1 -// count = code & 0x1f -// offset = 32 -// break -// } -// -// /* Handle strange cases for counts */ -// if offset != 0 { -// isfillormix = ((opcode == 2) || (opcode == 7)) -// if count == 0 { -// if isfillormix { -// count = CVAL(&input) + 1 -// } else { -// count = CVAL(&input) + offset -// } -// } else if isfillormix { -// count <<= 3 -// } -// } -// /* Read preliminary data */ -// switch opcode { -// case 0: /* Fill */ -// if (lastopcode == opcode) && !((x == width) && (prevline == 0)) { -// insertmix = true -// } -// break -// case 8: /* Bicolour */ -// CVAL2(&input, &colour1) -// CVAL2(&input, &colour2) -// break -// case 3: /* Colour */ -// CVAL2(&input, &colour2) -// break -// case 6: /* SetMix/Mix */ -// fallthrough -// case 7: /* SetMix/FillOrMix */ -// CVAL2(&input, &mix) -// opcode -= 5 -// break -// case 9: /* FillOrMix_1 */ -// mask = 0x03 -// opcode = 0x02 -// fom_mask = 3 -// break -// case 0x0a: /* FillOrMix_2 */ -// mask = 0x05 -// opcode = 0x02 -// fom_mask = 5 -// break -// } -// lastopcode = opcode -// mixmask = 0 -// /* Output body */ -// for count > 0 { -// if x >= width { -// if height <= 0 { -// return false -// } -// -// x = 0 -// height-- -// prevline = line -// line = height * width -// } -// switch opcode { -// case 0: /* Fill */ -// if insertmix { -// if prevline == 0 { -// out[x+line] = mix -// } else { -// out[x+line] = out[prevline+x] ^ mix -// } -// insertmix = false -// count-- -// x++ -// } -// if prevline == 0 { -// REPEAT(func() { -// out[x+line] = 0 -// }, &count, &x, width) -// } else { -// REPEAT(func() { -// out[x+line] = out[prevline+x] -// }, &count, &x, width) -// } -// break -// case 1: /* Mix */ -// if prevline == 0 { -// REPEAT(func() { -// out[x+line] = mix -// }, &count, &x, width) -// } else { -// REPEAT(func() { -// out[x+line] = out[prevline+x] ^ mix -// }, &count, &x, width) -// } -// break -// case 2: /* Fill or Mix */ -// if prevline == 0 { -// REPEAT(func() { -// mixmask <<= 1 -// if mixmask == 0 { -// mask = fom_mask -// if fom_mask == 0 { -// mask = uint8(CVAL(&input)) -// mixmask = 1 -// } -// } -// if mask&mixmask != 0 { -// out[x+line] = mix -// } else { -// out[x+line] = 0 -// } -// }, &count, &x, width) -// } else { -// REPEAT(func() { -// mixmask = mixmask << 1 -// if mixmask == 0 { -// mask = fom_mask -// if fom_mask == 0 { -// mask = uint8(CVAL(&input)) -// mixmask = 1 -// } -// } -// if mask&mixmask != 0 { -// out[x+line] = out[prevline+x] ^ mix -// } else { -// out[x+line] = out[prevline+x] -// } -// }, &count, &x, width) -// } -// break -// case 3: /* Colour */ -// REPEAT(func() { -// out[x+line] = colour2 -// }, &count, &x, width) -// break -// case 4: /* Copy */ -// REPEAT(func() { -// var a uint16 -// CVAL2(&input, &a) -// out[x+line] = a -// }, &count, &x, width) -// -// break -// case 8: /* Bicolour */ -// REPEAT(func() { -// if bicolour { -// out[x+line] = colour2 -// bicolour = false -// } else { -// out[x+line] = colour1 -// bicolour = true -// count++ -// } -// }, &count, &x, width) -// -// break -// case 0xd: /* White */ -// REPEAT(func() { -// out[x+line] = 0xffff -// }, &count, &x, width) -// break -// case 0xe: /* Black */ -// REPEAT(func() { -// out[x+line] = 0 -// }, &count, &x, width) -// break -// default: -// glog.Debugf("bitmap opcode 0x%x\n", opcode) -// return false -// } -// } -// } -// j := 0 -// for _, v := range out { -// (*output)[j], (*output)[j+1] = PutUint16BE(v) -// j += 2 -// } -// return true -//} - -// /* 3 byte bitmap decompress */ -func decompress3(output *[]uint8, width, height int, input []uint8, size int) bool { - var ( - prevline, line, count int - opcode, offset, code int - x int = width - lastopcode int = -1 - insertmix, bicolour, isfillormix bool - mixmask, mask uint8 - colour1 = [3]uint8{0, 0, 0} - colour2 = [3]uint8{0, 0, 0} - mix = [3]uint8{0xff, 0xff, 0xff} - fom_mask uint8 - ) - out := *output - for len(input) != 0 { - fom_mask = 0 - code = CVAL(&input) - opcode = code >> 4 - /* Handle different opcode forms */ - switch opcode { - case 0xc, 0xd, 0xe: - opcode -= 6 - count = code & 0xf - offset = 16 - break - case 0xf: - opcode = code & 0xf - if opcode < 9 { - count = CVAL(&input) - count |= CVAL(&input) << 8 - } else { - count = 1 - if opcode < 0xb { - count = 8 - } - } - offset = 0 - break - default: - opcode >>= 1 - count = code & 0x1f - offset = 32 - break - } - - /* Handle strange cases for counts */ - if offset != 0 { - isfillormix = ((opcode == 2) || (opcode == 7)) - if count == 0 { - if isfillormix { - count = CVAL(&input) + 1 - } else { - count = CVAL(&input) + offset - } - } else if isfillormix { - count <<= 3 - } - } - /* Read preliminary data */ - switch opcode { - case 0: /* Fill */ - if (lastopcode == opcode) && !((x == width) && (prevline == 0)) { - insertmix = true - } - break - case 8: /* Bicolour */ - CVAL3(&input, &colour1) - CVAL3(&input, &colour2) - break - case 3: /* Colour */ - CVAL3(&input, &colour2) - break - case 6: /* SetMix/Mix */ - fallthrough - case 7: /* SetMix/FillOrMix */ - CVAL3(&input, &mix) - opcode -= 5 - break - case 9: /* FillOrMix_1 */ - mask = 0x03 - opcode = 0x02 - fom_mask = 3 - break - case 0x0a: /* FillOrMix_2 */ - mask = 0x05 - opcode = 0x02 - fom_mask = 5 - break - } - - lastopcode = opcode - mixmask = 0 - /* Output body */ - for count > 0 { - if x >= width { - if height <= 0 { - return false - } - - x = 0 - height-- - prevline = line - line = height * width * 3 - } - switch opcode { - case 0: /* Fill */ - if insertmix { - if prevline == 0 { - out[3*x+line] = mix[0] - out[3*x+line+1] = mix[1] - out[3*x+line+2] = mix[2] - } else { - out[3*x+line] = out[prevline+3*x] ^ mix[0] - out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1] - out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2] - } - insertmix = false - count-- - x++ - } - if prevline == 0 { - REPEAT(func() { - out[3*x+line] = 0 - out[3*x+line+1] = 0 - out[3*x+line+2] = 0 - }, &count, &x, width) - } else { - REPEAT(func() { - out[3*x+line] = out[prevline+3*x] - out[3*x+line+1] = out[prevline+3*x+1] - out[3*x+line+2] = out[prevline+3*x+2] - }, &count, &x, width) - } - break - case 1: /* Mix */ - if prevline == 0 { - REPEAT(func() { - out[3*x+line] = mix[0] - out[3*x+line+1] = mix[1] - out[3*x+line+2] = mix[2] - }, &count, &x, width) - } else { - REPEAT(func() { - out[3*x+line] = out[prevline+3*x] ^ mix[0] - out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1] - out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2] - }, &count, &x, width) - } - break - case 2: /* Fill or Mix */ - if prevline == 0 { - REPEAT(func() { - mixmask = mixmask << 1 - if mixmask == 0 { - mask = fom_mask - if fom_mask == 0 { - mask = uint8(CVAL(&input)) - mixmask = 1 - } - } - if mask&mixmask != 0 { - out[3*x+line] = mix[0] - out[3*x+line+1] = mix[1] - out[3*x+line+2] = mix[2] - } else { - out[3*x+line] = 0 - out[3*x+line+1] = 0 - out[3*x+line+2] = 0 - } - }, &count, &x, width) - } else { - REPEAT(func() { - mixmask = mixmask << 1 - if mixmask == 0 { - mask = fom_mask - if fom_mask == 0 { - mask = uint8(CVAL(&input)) - mixmask = 1 - } - } - if mask&mixmask != 0 { - out[3*x+line] = out[prevline+3*x] ^ mix[0] - out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1] - out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2] - } else { - out[3*x+line] = out[prevline+3*x] - out[3*x+line+1] = out[prevline+3*x+1] - out[3*x+line+2] = out[prevline+3*x+2] - } - }, &count, &x, width) - } - break - case 3: /* Colour */ - REPEAT(func() { - out[3*x+line] = colour2[0] - out[3*x+line+1] = colour2[1] - out[3*x+line+2] = colour2[2] - - }, &count, &x, width) - break - case 4: /* Copy */ - REPEAT(func() { - out[3*x+line] = uint8(CVAL(&input)) - out[3*x+line+1] = uint8(CVAL(&input)) - out[3*x+line+2] = uint8(CVAL(&input)) - }, &count, &x, width) - break - case 8: /* Bicolour */ - REPEAT(func() { - if bicolour { - out[3*x+line] = colour2[0] - out[3*x+line+1] = colour2[1] - out[3*x+line+2] = colour2[2] - bicolour = false - } else { - out[3*x+line] = colour1[0] - out[3*x+line+1] = colour1[1] - out[3*x+line+2] = colour1[2] - bicolour = true - count++ - } - }, &count, &x, width) - break - case 0xd: /* White */ - REPEAT(func() { - out[3*x+line] = 0xff - out[3*x+line+1] = 0xff - out[3*x+line+2] = 0xff - - }, &count, &x, width) - break - case 0xe: /* Black */ - REPEAT(func() { - out[3*x+line] = 0 - out[3*x+line+1] = 0 - out[3*x+line+2] = 0 - }, &count, &x, width) - break - default: - glog.Debugf("bitmap opcode 0x%x\n", opcode) - return false - } - } - } - - return true -} - -/* decompress a colour plane */ -func processPlane(in *[]uint8, width, height int, output *[]uint8, j int) int { - var ( - indexw int - indexh int - code int - collen int - replen int - color uint8 - x uint8 - revcode int - lastline int - thisline int - ) - ln := len(*in) - - lastline = 0 - indexh = 0 - i := 0 - for indexh < height { - thisline = j + (width * height * 4) - ((indexh + 1) * width * 4) - color = 0 - indexw = 0 - i = thisline - - if lastline == 0 { - for indexw < width { - code = CVAL(in) - replen = int(code & 0xf) - collen = int((code >> 4) & 0xf) - revcode = (replen << 4) | collen - if (revcode <= 47) && (revcode >= 16) { - replen = revcode - collen = 0 - } - for collen > 0 { - color = uint8(CVAL(in)) - (*output)[i] = uint8(color) - i += 4 - - indexw++ - collen-- - } - for replen > 0 { - (*output)[i] = uint8(color) - i += 4 - indexw++ - replen-- - } - } - } else { - for indexw < width { - code = CVAL(in) - replen = int(code & 0xf) - collen = int((code >> 4) & 0xf) - revcode = (replen << 4) | collen - if (revcode <= 47) && (revcode >= 16) { - replen = revcode - collen = 0 - } - for collen > 0 { - x = uint8(CVAL(in)) - if x&1 != 0 { - x = x >> 1 - x = x + 1 - color = -x - } else { - x = x >> 1 - color = x - } - x = (*output)[indexw*4+lastline] + color - (*output)[i] = uint8(x) - i += 4 - indexw++ - collen-- - } - for replen > 0 { - x = (*output)[indexw*4+lastline] + color - (*output)[i] = uint8(x) - i += 4 - indexw++ - replen-- - } - } - } - indexh++ - lastline = thisline - } - return ln - len(*in) -} - -/* 4 byte bitmap decompress */ -func decompress4(output *[]uint8, width, height int, input []uint8, size int) bool { - var ( - code int - onceBytes, total int - ) - - code = CVAL(&input) - if code != 0x10 { - return false - } - - total = 1 - onceBytes = processPlane(&input, width, height, output, 3) - total += onceBytes - - onceBytes = processPlane(&input, width, height, output, 2) - total += onceBytes - - onceBytes = processPlane(&input, width, height, output, 1) - total += onceBytes - - onceBytes = processPlane(&input, width, height, output, 0) - total += onceBytes - - return size == total -} - -/* main decompress function */ -func Decompress(input []uint8, width, height int, Bpp int) []uint8 { - size := width * height * Bpp - output := make([]uint8, size) - glog.Debug("decompress, bmp tpye =", Bpp) - switch Bpp { - case 1: - decompress1(&output, width, height, input, size) - case 2: - decompress2(&output, width, height, input, size) - case 3: - decompress3(&output, width, height, input, size) - case 4: - decompress4(&output, width, height, input, size) - default: - glog.Debugf("Bpp %d\n", Bpp) - } - - return output -} diff --git a/mylib/grdp/login/screen.go b/mylib/grdp/login/screen.go index e8fb2f7..910b4f0 100644 --- a/mylib/grdp/login/screen.go +++ b/mylib/grdp/login/screen.go @@ -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 -} diff --git a/mylib/grdp/plugin/addins.go b/mylib/grdp/plugin/addins.go deleted file mode 100644 index 21538eb..0000000 --- a/mylib/grdp/plugin/addins.go +++ /dev/null @@ -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 -} diff --git a/mylib/grdp/plugin/channel.go b/mylib/grdp/plugin/channel.go deleted file mode 100644 index 22b682d..0000000 --- a/mylib/grdp/plugin/channel.go +++ /dev/null @@ -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) -} diff --git a/mylib/grdp/plugin/drdynvc/dvc.go b/mylib/grdp/plugin/drdynvc/dvc.go deleted file mode 100644 index 47ec564..0000000 --- a/mylib/grdp/plugin/drdynvc/dvc.go +++ /dev/null @@ -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()) -} diff --git a/mylib/grdp/plugin/rail/rail.go b/mylib/grdp/plugin/rail/rail.go deleted file mode 100644 index 6d1c115..0000000 --- a/mylib/grdp/plugin/rail/rail.go +++ /dev/null @@ -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)) -} diff --git a/mylib/grdp/plugin/rdpgfx/rdpgfx.go b/mylib/grdp/plugin/rdpgfx/rdpgfx.go deleted file mode 100644 index b9b1707..0000000 --- a/mylib/grdp/plugin/rdpgfx/rdpgfx.go +++ /dev/null @@ -1,9 +0,0 @@ -package rdpgfx - -import ( - "github.com/shadow1ng/fscan/mylib/grdp/plugin" -) - -const ( - ChannelName = plugin.RDPGFX_DVC_CHANNEL_NAME -) diff --git a/mylib/grdp/protocol/pdu/data.go b/mylib/grdp/protocol/pdu/data.go index 6d9cd8c..f0ca6d6 100644 --- a/mylib/grdp/protocol/pdu/data.go +++ b/mylib/grdp/protocol/pdu/data.go @@ -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: diff --git a/mylib/grdp/protocol/pdu/gdi.go b/mylib/grdp/protocol/pdu/gdi.go deleted file mode 100644 index 21a022e..0000000 --- a/mylib/grdp/protocol/pdu/gdi.go +++ /dev/null @@ -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", -} diff --git a/mylib/grdp/protocol/pdu/orders.go b/mylib/grdp/protocol/pdu/orders.go deleted file mode 100644 index abb2091..0000000 --- a/mylib/grdp/protocol/pdu/orders.go +++ /dev/null @@ -1,1236 +0,0 @@ -package pdu - -import ( - "bytes" - "errors" - "fmt" - "io" - - "github.com/shadow1ng/fscan/mylib/grdp/glog" - - "github.com/shadow1ng/fscan/mylib/grdp/core" -) - -type ControlFlag uint8 - -const ( - TS_STANDARD = 0x01 - TS_SECONDARY = 0x02 - TS_BOUNDS = 0x04 - TS_TYPE_CHANGE = 0x08 - TS_DELTA_COORDINATES = 0x10 - TS_ZERO_BOUNDS_DELTAS = 0x20 - TS_ZERO_FIELD_BYTE_BIT0 = 0x40 - TS_ZERO_FIELD_BYTE_BIT1 = 0x80 -) - -type PrimaryOrderType uint8 - -const ( - ORDER_TYPE_DSTBLT = 0x00 //0 - ORDER_TYPE_PATBLT = 0x01 //1 - ORDER_TYPE_SCRBLT = 0x02 //2 - //ORDER_TYPE_DRAWNINEGRID = 0x07 //7 - //ORDER_TYPE_MULTI_DRAWNINEGRID = 0x08 //8 - ORDER_TYPE_LINETO = 0x09 //9 - ORDER_TYPE_OPAQUERECT = 0x0A //10 - ORDER_TYPE_SAVEBITMAP = 0x0B //11 - ORDER_TYPE_MEMBLT = 0x0D //13 - ORDER_TYPE_MEM3BLT = 0x0E //14 - //ORDER_TYPE_MULTIDSTBLT = 0x0F //15 - //ORDER_TYPE_MULTIPATBLT = 0x10 //16 - //ORDER_TYPE_MULTISCRBLT = 0x11 //17 - //ORDER_TYPE_MULTIOPAQUERECT = 0x12 //18 - //ORDER_TYPE_FAST_INDEX = 0x13 //19 - ORDER_TYPE_POLYGON_SC = 0x14 //20 - ORDER_TYPE_POLYGON_CB = 0x15 //21 - ORDER_TYPE_POLYLINE = 0x16 //22 - //ORDER_TYPE_FAST_GLYPH = 0x18 //24 - ORDER_TYPE_ELLIPSE_SC = 0x19 //25 - ORDER_TYPE_ELLIPSE_CB = 0x1A //26 - ORDER_TYPE_TEXT2 = 0x1B //27 -) - -type SecondaryOrderType uint8 - -const ( - ORDER_TYPE_BITMAP_UNCOMPRESSED = 0x00 - ORDER_TYPE_CACHE_COLOR_TABLE = 0x01 - ORDER_TYPE_CACHE_BITMAP_COMPRESSED = 0x02 - ORDER_TYPE_CACHE_GLYPH = 0x03 - ORDER_TYPE_BITMAP_UNCOMPRESSED_V2 = 0x04 - ORDER_TYPE_BITMAP_COMPRESSED_V2 = 0x05 - ORDER_TYPE_CACHE_BRUSH = 0x07 - ORDER_TYPE_BITMAP_COMPRESSED_V3 = 0x08 -) - -func (s SecondaryOrderType) String() string { - name := "Unknown" - switch s { - case ORDER_TYPE_BITMAP_UNCOMPRESSED: - name = "Cache Bitmap" - case ORDER_TYPE_CACHE_COLOR_TABLE: - name = "Cache Color Table" - case ORDER_TYPE_CACHE_BITMAP_COMPRESSED: - name = "Cache Bitmap (Compressed)" - case ORDER_TYPE_CACHE_GLYPH: - name = "Cache Glyph" - case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2: - name = "Cache Bitmap V2" - case ORDER_TYPE_BITMAP_COMPRESSED_V2: - name = "Cache Bitmap V2 (Compressed)" - case ORDER_TYPE_CACHE_BRUSH: - name = "Cache Brush" - case ORDER_TYPE_BITMAP_COMPRESSED_V3: - name = "Cache Bitmap V3" - } - return fmt.Sprintf("[0x%02d] %s", s, name) -} - -/* Alternate Secondary Drawing Orders */ -const ( - ORDER_TYPE_SWITCH_SURFACE = 0x00 - ORDER_TYPE_CREATE_OFFSCREEN_BITMAP = 0x01 - ORDER_TYPE_STREAM_BITMAP_FIRST = 0x02 - ORDER_TYPE_STREAM_BITMAP_NEXT = 0x03 - ORDER_TYPE_CREATE_NINE_GRID_BITMAP = 0x04 - ORDER_TYPE_GDIPLUS_FIRST = 0x05 - ORDER_TYPE_GDIPLUS_NEXT = 0x06 - ORDER_TYPE_GDIPLUS_END = 0x07 - ORDER_TYPE_GDIPLUS_CACHE_FIRST = 0x08 - ORDER_TYPE_GDIPLUS_CACHE_NEXT = 0x09 - ORDER_TYPE_GDIPLUS_CACHE_END = 0x0A - ORDER_TYPE_WINDOW = 0x0B - ORDER_TYPE_COMPDESK_FIRST = 0x0C - ORDER_TYPE_FRAME_MARKER = 0x0D -) - -const ( - GLYPH_FRAGMENT_NOP = 0x00 - GLYPH_FRAGMENT_USE = 0xFE - GLYPH_FRAGMENT_ADD = 0xFF - - CBR2_HEIGHT_SAME_AS_WIDTH = 0x01 - CBR2_PERSISTENT_KEY_PRESENT = 0x02 - CBR2_NO_BITMAP_COMPRESSION_HDR = 0x08 - CBR2_DO_NOT_CACHE = 0x10 -) - -const ( - ORDER_PRIMARY = iota - ORDER_SECONDARY - ORDER_ALTSEC -) - -type OrderPdu struct { - ControlFlags uint8 - Type int - Altsec *Altsec - Primary *Primary - Secondary *Secondary -} - -func (o *OrderPdu) HasBounds() bool { - return o.ControlFlags&TS_BOUNDS != 0 -} - -type Altsec struct { -} - -type Secondary struct { -} - -type Primary struct { - Bounds Bounds - Data PrimaryOrder -} - -type FastPathOrdersPDU struct { - NumberOrders uint16 - OrderPdus []OrderPdu -} - -func (*FastPathOrdersPDU) FastPathUpdateType() uint8 { - return FASTPATH_UPDATETYPE_ORDERS -} - -func (f *FastPathOrdersPDU) Unpack(r io.Reader) error { - f.NumberOrders, _ = core.ReadUint16LE(r) - //glog.Info("NumberOrders:", f.NumberOrders) - for i := 0; i < int(f.NumberOrders); i++ { - var o OrderPdu - o.ControlFlags, _ = core.ReadUInt8(r) - if o.ControlFlags&TS_STANDARD == 0 { - //glog.Info("Altsec order") - o.processAltsecOrder(r) - o.Type = ORDER_ALTSEC - //return errors.New("Not support") - } else if o.ControlFlags&TS_SECONDARY != 0 { - //glog.Info("Secondary order") - o.processSecondaryOrder(r) - o.Type = ORDER_SECONDARY - } else { - //glog.Info("Primary order") - o.processPrimaryOrder(r) - o.Type = ORDER_PRIMARY - } - - if f.OrderPdus == nil { - f.OrderPdus = make([]OrderPdu, 0, f.NumberOrders) - } - f.OrderPdus = append(f.OrderPdus, o) - } - return nil -} -func (o *OrderPdu) processAltsecOrder(r io.Reader) error { - orderType := o.ControlFlags >> 2 - //glog.Info("Altsec:", orderType) - switch orderType { - case ORDER_TYPE_SWITCH_SURFACE: - case ORDER_TYPE_CREATE_OFFSCREEN_BITMAP: - case ORDER_TYPE_STREAM_BITMAP_FIRST: - case ORDER_TYPE_STREAM_BITMAP_NEXT: - case ORDER_TYPE_CREATE_NINE_GRID_BITMAP: - case ORDER_TYPE_GDIPLUS_FIRST: - case ORDER_TYPE_GDIPLUS_NEXT: - case ORDER_TYPE_GDIPLUS_END: - case ORDER_TYPE_GDIPLUS_CACHE_FIRST: - case ORDER_TYPE_GDIPLUS_CACHE_NEXT: - case ORDER_TYPE_GDIPLUS_CACHE_END: - case ORDER_TYPE_WINDOW: - case ORDER_TYPE_COMPDESK_FIRST: - case ORDER_TYPE_FRAME_MARKER: - core.ReadUInt32LE(r) - } - - return nil -} -func (o *OrderPdu) processSecondaryOrder(r io.Reader) error { - var sec Secondary - length, _ := core.ReadUint16LE(r) - flags, _ := core.ReadUint16LE(r) - orderType, _ := core.ReadUInt8(r) - - glog.Info("Secondary:", SecondaryOrderType(orderType)) - - b, _ := core.ReadBytes(int(length)+13-6, r) - //fmt.Println("read ok, orderType = ", orderType) - r0 := bytes.NewReader(b) - - switch orderType { - case ORDER_TYPE_BITMAP_UNCOMPRESSED: - fallthrough - case ORDER_TYPE_CACHE_BITMAP_COMPRESSED: - compressed := (orderType == ORDER_TYPE_CACHE_BITMAP_COMPRESSED) - sec.updateCacheBitmapOrder(r0, compressed, flags) - case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2: - fallthrough - case ORDER_TYPE_BITMAP_COMPRESSED_V2: - compressed := (orderType == ORDER_TYPE_BITMAP_COMPRESSED_V2) - sec.updateCacheBitmapV2Order(r0, compressed, flags) - case ORDER_TYPE_BITMAP_COMPRESSED_V3: - sec.updateCacheBitmapV3Order(r0, flags) - case ORDER_TYPE_CACHE_COLOR_TABLE: - sec.updateCacheColorTableOrder(r0, flags) - case ORDER_TYPE_CACHE_GLYPH: - sec.updateCacheGlyphOrder(r0, flags) - case ORDER_TYPE_CACHE_BRUSH: - sec.updateCacheBrushOrder(r0, flags) - default: - glog.Debugf("Unsupport order type 0x%x", orderType) - } - - return nil -} -func (b *Bounds) updateBounds(r io.Reader) { - present, _ := core.ReadUInt8(r) - - if present&1 != 0 { - readOrderCoord(r, &b.left, false) - } else if present&16 != 0 { - readOrderCoord(r, &b.left, true) - } - - if present&2 != 0 { - readOrderCoord(r, &b.top, false) - } else if present&32 != 0 { - readOrderCoord(r, &b.top, true) - } - - if present&4 != 0 { - readOrderCoord(r, &b.right, false) - } else if present&64 != 0 { - readOrderCoord(r, &b.right, true) - } - if present&8 != 0 { - readOrderCoord(r, &b.bottom, false) - } else if present&128 != 0 { - readOrderCoord(r, &b.bottom, true) - } -} - -type PrimaryOrder interface { - Type() int - Unpack(io.Reader, uint32, bool) error -} - -var ( - orderType uint8 - bounds Bounds -) - -func (o *OrderPdu) processPrimaryOrder(r io.Reader) error { - o.Primary = &Primary{} - if o.ControlFlags&TS_TYPE_CHANGE != 0 { - orderType, _ = core.ReadUInt8(r) - } - size := 1 - switch orderType { - case ORDER_TYPE_MEM3BLT, ORDER_TYPE_TEXT2: - size = 3 - - case ORDER_TYPE_PATBLT, ORDER_TYPE_MEMBLT, ORDER_TYPE_LINETO, ORDER_TYPE_POLYGON_CB, ORDER_TYPE_ELLIPSE_CB: - size = 2 - } - - if o.ControlFlags&TS_ZERO_FIELD_BYTE_BIT0 != 0 { - size-- - } - if o.ControlFlags&TS_ZERO_FIELD_BYTE_BIT1 != 0 { - if size < 2 { - size = 0 - } else { - size -= 2 - } - } - var present uint32 - for i := 0; i < size; i++ { - bits, _ := core.ReadUInt8(r) - present |= uint32(bits) << (i * 8) - } - - if o.ControlFlags&TS_BOUNDS != 0 { - if o.ControlFlags&TS_ZERO_BOUNDS_DELTAS == 0 { - bounds.updateBounds(r) - } - //glog.Infof("updateBounds") - o.Primary.Bounds = bounds - } - - delta := o.ControlFlags&TS_DELTA_COORDINATES != 0 - - //glog.Infof("present=%d,delta=%v", present, delta) - - var p PrimaryOrder - switch orderType { - case ORDER_TYPE_DSTBLT: - p = &Dstblt{} - - case ORDER_TYPE_PATBLT: - p = &Patblt{} - - case ORDER_TYPE_SCRBLT: - p = &Scrblt{} - - //case ORDER_TYPE_DRAWNINEGRID: - - //case ORDER_TYPE_MULTI_DRAWNINEGRID: - - case ORDER_TYPE_LINETO: - p = &LineTo{} - - case ORDER_TYPE_OPAQUERECT: - p = &OpaqueRect{} - - case ORDER_TYPE_SAVEBITMAP: - p = &SaveBitmap{} - - case ORDER_TYPE_MEMBLT: - p = &Memblt{} - - case ORDER_TYPE_MEM3BLT: - p = &Mem3blt{} - - //case ORDER_TYPE_MULTIDSTBLT: - - //case ORDER_TYPE_MULTIPATBLT: - - //case ORDER_TYPE_MULTISCRBLT: - - //case ORDER_TYPE_MULTIOPAQUERECT: - - //case ORDER_TYPE_FAST_INDEX: - - case ORDER_TYPE_POLYGON_SC: - p = &PolygonSc{} - - case ORDER_TYPE_POLYGON_CB: - p = &PolygonCb{} - - case ORDER_TYPE_POLYLINE: - p = &Polyline{} - - //case ORDER_TYPE_FAST_GLYPH: - - case ORDER_TYPE_ELLIPSE_SC: - p = &EllipeSc{} - - case ORDER_TYPE_ELLIPSE_CB: - p = &EllipeCb{} - - case ORDER_TYPE_TEXT2: - p = &GlayphIndex{} - default: - glog.Error("Not Support order type:", orderType) - return errors.New("Not Support order type") - } - if p != nil { - if err := p.Unpack(r, present, delta); err != nil { - return err - } - } - - o.Primary.Data = p - return nil -} -func readOrderCoord(r io.Reader, coord *int32, delta bool) { - if delta { - change, _ := core.ReadUInt8(r) - *coord += int32(int8(change)) - } else { - change, _ := core.ReadUint16LE(r) - *coord = int32(int16(change)) - } -} - -type Dstblt struct { - x int32 - y int32 - cx int32 - cy int32 - opcode uint8 -} - -func (d *Dstblt) Type() int { - return ORDER_TYPE_DSTBLT -} -func (d *Dstblt) Unpack(r io.Reader, present uint32, delta bool) error { - glog.Infof("Dstblt Order") - if present&0x01 != 0 { - readOrderCoord(r, &d.x, delta) - } - if present&0x02 != 0 { - readOrderCoord(r, &d.y, delta) - } - if present&0x04 != 0 { - readOrderCoord(r, &d.cx, delta) - } - if present&0x08 != 0 { - readOrderCoord(r, &d.cy, delta) - } - if present&0x10 != 0 { - d.opcode, _ = core.ReadUInt8(r) - } - return nil -} - -type Patblt struct { - x int32 - y int32 - cx int32 - cy int32 - opcode uint8 - bgcolour [4]uint8 - fgcolour [4]uint8 - brush Brush -} - -func (d *Patblt) Type() int { - return ORDER_TYPE_PATBLT -} -func (d *Patblt) Unpack(r io.Reader, present uint32, delta bool) error { - glog.Infof("Patblt Order") - if present&0x01 != 0 { - readOrderCoord(r, &d.x, delta) - } - if present&0x02 != 0 { - readOrderCoord(r, &d.y, delta) - } - if present&0x04 != 0 { - readOrderCoord(r, &d.cx, delta) - } - if present&0x08 != 0 { - readOrderCoord(r, &d.cy, delta) - } - if present&0x10 != 0 { - d.opcode, _ = core.ReadUInt8(r) - } - if present&0x0020 != 0 { - b, g, r, a := updateReadColorRef(r) - d.bgcolour[0], d.bgcolour[1], d.bgcolour[2], d.bgcolour[3] = b, g, r, a - } - if present&0x0040 != 0 { - b, g, r, a := updateReadColorRef(r) - d.fgcolour[0], d.fgcolour[1], d.fgcolour[2], d.fgcolour[3] = b, g, r, a - } - d.brush.updateBrush(r, present>>7) - - return nil -} - -type Brush struct { - X uint8 - Y uint8 - Style uint8 - Hatch uint8 - Data []byte -} - -func (b *Brush) updateBrush(r io.Reader, present uint32) { - if present&1 != 0 { - b.X, _ = core.ReadUInt8(r) - } - - if present&2 != 0 { - b.Y, _ = core.ReadUInt8(r) - } - - if present&4 != 0 { - b.Style, _ = core.ReadUInt8(r) - } - - if present&8 != 0 { - b.Hatch, _ = core.ReadUInt8(r) - } - - if present&16 != 0 { - data, _ := core.ReadBytes(7, r) - b.Data = make([]byte, 0, 8) - b.Data = append(b.Data, b.Hatch) - b.Data = append(b.Data, data...) - } -} - -type Scrblt struct { - X int32 - Y int32 - Cx int32 - Cy int32 - Opcode uint8 - Srcx int32 - Srcy int32 -} - -func (d *Scrblt) Type() int { - return ORDER_TYPE_SCRBLT -} - -var d Scrblt - -func (d1 *Scrblt) Unpack(r io.Reader, present uint32, delta bool) error { - glog.Infof("Scrblt Order") - if present&0x0001 != 0 { - readOrderCoord(r, &d.X, delta) - } - if present&0x0002 != 0 { - readOrderCoord(r, &d.Y, delta) - } - if present&0x0004 != 0 { - readOrderCoord(r, &d.Cx, delta) - } - if present&0x0008 != 0 { - readOrderCoord(r, &d.Cy, delta) - } - if present&0x0010 != 0 { - d.Opcode, _ = core.ReadUInt8(r) - } - if present&0x0020 != 0 { - readOrderCoord(r, &d.Srcx, delta) - } - if present&0x0040 != 0 { - readOrderCoord(r, &d.Srcy, delta) - } - *d1 = d - return nil -} - -type LineTo struct { - Mixmode uint16 - Startx int32 - Starty int32 - Endx int32 - Endy int32 - Bgcolour [4]uint8 - Opcode uint8 - Pen Pen -} - -func (d *LineTo) Type() int { - return ORDER_TYPE_LINETO -} -func (d *LineTo) Unpack(r io.Reader, present uint32, delta bool) error { - glog.Infof("LineTo Order") - if present&0x0001 != 0 { - d.Mixmode, _ = core.ReadUint16LE(r) - } - if present&0x0002 != 0 { - readOrderCoord(r, &d.Startx, delta) - } - if present&0x0004 != 0 { - readOrderCoord(r, &d.Starty, delta) - } - if present&0x008 != 0 { - readOrderCoord(r, &d.Endx, delta) - } - if present&0x0010 != 0 { - readOrderCoord(r, &d.Endy, delta) - } - if present&0x0020 != 0 { - b, g, r, a := updateReadColorRef(r) - d.Bgcolour[0], d.Bgcolour[1], d.Bgcolour[2], d.Bgcolour[3] = b, g, r, a - } - if present&0x0040 != 0 { - d.Opcode, _ = core.ReadUInt8(r) - } - - d.Pen.updatePen(r, present>>7) - - return nil -} - -type Pen struct { - Style uint8 - Width uint8 - Colour [4]uint8 -} - -func (d *Pen) updatePen(r io.Reader, present uint32) { - if present&1 != 0 { - d.Style, _ = core.ReadUInt8(r) - } - - if present&2 != 0 { - d.Width, _ = core.ReadUInt8(r) - } - - if present&4 != 0 { - b, g, r, a := updateReadColorRef(r) - d.Colour[0], d.Colour[1], d.Colour[2], d.Colour[3] = b, g, r, a - } -} - -type OpaqueRect struct { - X int32 - Y int32 - Cx int32 - Cy int32 - Colour [4]uint8 -} - -func (d *OpaqueRect) Type() int { - return ORDER_TYPE_OPAQUERECT -} -func (d *OpaqueRect) Unpack(r io.Reader, present uint32, delta bool) error { - glog.Infof("OpaqueRect Order") - if present&0x0001 != 0 { - readOrderCoord(r, &d.X, delta) - } - if present&0x0002 != 0 { - readOrderCoord(r, &d.Y, delta) - } - if present&0x0004 != 0 { - readOrderCoord(r, &d.Cx, delta) - } - if present&0x0008 != 0 { - readOrderCoord(r, &d.Cy, delta) - } - if present&0x0010 != 0 { - i, _ := core.ReadUInt8(r) - d.Colour[0] = i - } - if present&0x0020 != 0 { - i, _ := core.ReadUInt8(r) - d.Colour[1] = i - } - if present&0x0040 != 0 { - i, _ := core.ReadUInt8(r) - d.Colour[2] = i - } - return nil -} - -type SaveBitmap struct { - Offset uint32 - Left int32 - Top int32 - Right int32 - Bottom int32 - action uint8 -} - -func (d *SaveBitmap) Type() int { - return ORDER_TYPE_SAVEBITMAP -} -func (d *SaveBitmap) Unpack(r io.Reader, present uint32, delta bool) error { - if present&0x0001 != 0 { - d.Offset, _ = core.ReadUInt32LE(r) - } - if present&0x0002 != 0 { - readOrderCoord(r, &d.Left, delta) - } - if present&0x0004 != 0 { - readOrderCoord(r, &d.Top, delta) - } - if present&0x0008 != 0 { - readOrderCoord(r, &d.Right, delta) - } - if present&0x0010 != 0 { - readOrderCoord(r, &d.Bottom, delta) - } - if present&0x0020 != 0 { - d.action, _ = core.ReadUInt8(r) - } - return nil -} - -type Memblt struct { - ColourTable uint8 - CacheId uint8 - X int32 - Y int32 - Cx int32 - Cy int32 - Opcode uint8 - Srcx int32 - Srcy int32 - CacheIdx uint16 -} - -func (d *Memblt) Type() int { - return ORDER_TYPE_MEMBLT -} -func (d *Memblt) Unpack(r io.Reader, present uint32, delta bool) error { - if present&0x0001 != 0 { - d.CacheId, _ = core.ReadUInt8(r) - d.ColourTable, _ = core.ReadUInt8(r) - } - if present&0x0002 != 0 { - readOrderCoord(r, &d.X, delta) - } - if present&0x0004 != 0 { - readOrderCoord(r, &d.Y, delta) - } - if present&0x0008 != 0 { - readOrderCoord(r, &d.Cx, delta) - } - if present&0x0010 != 0 { - readOrderCoord(r, &d.Cy, delta) - } - if present&0x0020 != 0 { - d.Opcode, _ = core.ReadUInt8(r) - } - if present&0x0040 != 0 { - readOrderCoord(r, &d.Srcx, delta) - } - if present&0x0080 != 0 { - readOrderCoord(r, &d.Srcy, delta) - } - if present&0x0100 != 0 { - d.CacheIdx, _ = core.ReadUint16LE(r) - } - return nil -} - -type Mem3blt struct { - ColourTable uint8 - CacheId uint8 - X int32 - Y int32 - Cx int32 - Cy int32 - Opcode uint8 - Srcx int32 - Srcy int32 - Bgcolour [4]uint8 - Fgcolour [4]uint8 - Brush Brush - CacheIdx uint16 -} - -func (d *Mem3blt) Type() int { - return ORDER_TYPE_MEM3BLT -} -func (d *Mem3blt) Unpack(r io.Reader, present uint32, delta bool) error { - if present&0x000001 != 0 { - d.CacheId, _ = core.ReadUInt8(r) - d.ColourTable, _ = core.ReadUInt8(r) - } - if present&0x000002 != 0 { - readOrderCoord(r, &d.X, delta) - } - if present&0x000004 != 0 { - readOrderCoord(r, &d.Y, delta) - } - if present&0x000008 != 0 { - readOrderCoord(r, &d.Cx, delta) - } - if present&0x000010 != 0 { - readOrderCoord(r, &d.Cy, delta) - } - if present&0x000020 != 0 { - d.Opcode, _ = core.ReadUInt8(r) - } - if present&0x000040 != 0 { - readOrderCoord(r, &d.Srcx, delta) - } - if present&0x000080 != 0 { - readOrderCoord(r, &d.Srcy, delta) - } - if present&0x000100 != 0 { - b, g, r, a := updateReadColorRef(r) - d.Bgcolour[0], d.Bgcolour[1], d.Bgcolour[2], d.Bgcolour[3] = b, g, r, a - } - if present&0x000200 != 0 { - b, g, r, a := updateReadColorRef(r) - d.Fgcolour[0], d.Fgcolour[1], d.Fgcolour[2], d.Fgcolour[3] = b, g, r, a - } - d.Brush.updateBrush(r, present>>10) - if present&0x008000 != 0 { - d.CacheIdx, _ = core.ReadUint16LE(r) - } - if present&0x010000 != 0 { - core.ReadUint16LE(r) - } - - return nil -} - -type PolygonSc struct { - X int32 - Y int32 - Opcode uint8 - Fillmode uint8 - Fgcolour [4]uint8 - Npoints uint8 - Points []Point -} - -type Point struct { - X int32 - Y int32 -} - -func (d *PolygonSc) Type() int { - return ORDER_TYPE_POLYGON_SC -} -func (d *PolygonSc) Unpack(r io.Reader, present uint32, delta bool) error { - if present&0x0001 != 0 { - readOrderCoord(r, &d.X, delta) - } - if present&0x0002 != 0 { - readOrderCoord(r, &d.Y, delta) - } - if present&0x0004 != 0 { - d.Opcode, _ = core.ReadUInt8(r) - } - if present&0x0008 != 0 { - d.Fillmode, _ = core.ReadUInt8(r) - } - if present&0x0010 != 0 { - b, g, r, a := updateReadColorRef(r) - d.Fgcolour[0], d.Fgcolour[1], d.Fgcolour[2], d.Fgcolour[3] = b, g, r, a - } - if present&0x0020 != 0 { - d.Npoints, _ = core.ReadUInt8(r) - d.Points = make([]Point, 0, d.Npoints+1) - } - if present&0x0040 != 0 { - size, _ := core.ReadUInt8(r) - data, _ := core.ReadBytes(int(size), r) - d.Points = append(d.Points, Point{d.X, d.Y}) - var flags uint8 - r = bytes.NewReader(data) - for i := 1; i <= int(d.Npoints); i++ { - var p Point - if (i-1)%4 == 0 { - flags, _ = core.ReadUInt8(r) - } - if (^flags)&0x80 != 0 { - p.X = parseDelta(r) - } - if (^flags)&0x40 != 0 { - p.Y = parseDelta(r) - } - flags <<= 2 - } - } - - return nil -} - -func parseDelta(r io.Reader) (v int32) { - b, _ := core.ReadUInt8(r) - if b&0x40 != 0 { - v = int32(b) | (^0x3F) - } else { - v = int32(b & 0x3F) - } - if b&0x80 != 0 { - b, _ := core.ReadUInt8(r) - v = (v << 8) | int32(b) - } - return -} - -type PolygonCb struct { -} - -func (d *PolygonCb) Type() int { - return ORDER_TYPE_POLYGON_CB -} -func (d *PolygonCb) Unpack(r io.Reader, present uint32, delta bool) error { - return nil -} - -type Polyline struct { -} - -func (d *Polyline) Type() int { - return ORDER_TYPE_POLYLINE -} -func (d *Polyline) Unpack(r io.Reader, present uint32, delta bool) error { - return nil -} - -type EllipeSc struct { -} - -func (d *EllipeSc) Type() int { - return ORDER_TYPE_ELLIPSE_SC -} -func (d *EllipeSc) Unpack(r io.Reader, present uint32, delta bool) error { - return nil -} - -type EllipeCb struct { -} - -func (d *EllipeCb) Type() int { - return ORDER_TYPE_ELLIPSE_CB -} -func (d *EllipeCb) Unpack(r io.Reader, present uint32, delta bool) error { - return nil -} - -type GlayphIndex struct { -} - -func (d *GlayphIndex) Type() int { - return ORDER_TYPE_TEXT2 -} -func (d *GlayphIndex) Unpack(r io.Reader, present uint32, delta bool) error { - return nil -} - -/*Secondary*/ -func (s *Secondary) updateCacheBitmapOrder(r io.Reader, compressed bool, flags uint16) { - glog.Debug("update cache bitmap..., compress:", compressed) - var cb CacheBitmapOrder - cb.cacheId, _ = core.ReadUInt8(r) - core.ReadUInt8(r) - cb.bitmapWidth, _ = core.ReadUInt8(r) - cb.bitmapHeight, _ = core.ReadUInt8(r) - cb.bitmapBpp, _ = core.ReadUInt8(r) - bitmapLength, _ := core.ReadUint16LE(r) - cb.cacheIndex, _ = core.ReadUint16LE(r) - var bitmapComprHdr []byte - if compressed { - if (flags & NO_BITMAP_COMPRESSION_HDR) == 0 { - bitmapComprHdr, _ = core.ReadBytes(8, r) - bitmapLength -= 8 - } - } - cb.bitmapComprHdr = bitmapComprHdr - cb.bitmapDataStream, _ = core.ReadBytes(int(bitmapLength), r) - cb.bitmapLength = bitmapLength - glog.Debug("cache read ok , bitmap len:", bitmapLength) -} - -type CacheBitmapOrder struct { - cacheId uint8 - bitmapBpp uint8 - bitmapWidth uint8 - bitmapHeight uint8 - bitmapLength uint16 - cacheIndex uint16 - bitmapComprHdr []byte - bitmapDataStream []byte -} - -func getCbV2Bpp(bpp uint32) (b uint32) { - switch bpp { - case 3: - b = 8 - case 4: - b = 16 - case 5: - b = 24 - case 6: - b = 32 - default: - b = 0 - } - return -} - -type CacheBitmapV2Order struct { - cacheId uint32 - flags uint32 - key1 uint32 - key2 uint32 - bitmapBpp uint32 - bitmapWidth uint8 - bitmapHeight uint8 - bitmapLength uint16 - cacheIndex uint32 - compressed bool - cbCompFirstRowSize uint16 - cbCompMainBodySize uint16 - cbScanWidth uint16 - cbUncompressedSize uint16 - bitmapDataStream []byte -} - -func (s *Secondary) updateCacheBitmapV2Order(r io.Reader, compressed bool, flags uint16) { - var cb CacheBitmapV2Order - cb.cacheId = uint32(flags) & 0x0003 - cb.flags = (uint32(flags) & 0xFF80) >> 7 - bitsPerPixelId := (uint32(flags) & 0x0078) >> 3 - cb.bitmapBpp = getCbV2Bpp(bitsPerPixelId) - - if cb.flags&CBR2_PERSISTENT_KEY_PRESENT != 0 { - cb.key1, _ = core.ReadUInt32LE(r) - cb.key2, _ = core.ReadUInt32LE(r) - } - - if cb.flags&CBR2_HEIGHT_SAME_AS_WIDTH != 0 { - cb.bitmapWidth, _ = core.ReadUInt8(r) - cb.bitmapHeight = cb.bitmapWidth - } else { - cb.bitmapWidth, _ = core.ReadUInt8(r) - cb.bitmapHeight, _ = core.ReadUInt8(r) - } - - bitmapLength, _ := core.ReadUint16LE(r) - cacheIndex, _ := core.ReadUInt8(r) - - if cb.flags&CBR2_DO_NOT_CACHE != 0 { - cb.cacheIndex = 0x7FFF - } else { - cb.cacheIndex = uint32(cacheIndex) - } - - if compressed { - if cb.flags&CBR2_NO_BITMAP_COMPRESSION_HDR == 0 { - cb.cbCompFirstRowSize, _ = core.ReadUint16LE(r) - cb.cbCompMainBodySize, _ = core.ReadUint16LE(r) - cb.cbScanWidth, _ = core.ReadUint16LE(r) - cb.cbUncompressedSize, _ = core.ReadUint16LE(r) - bitmapLength = cb.cbCompMainBodySize - } - } - - cb.bitmapDataStream, _ = core.ReadBytes(int(bitmapLength), r) - cb.bitmapLength = bitmapLength - cb.compressed = compressed - -} - -type CacheBitmapV3Order struct { - cacheId uint32 - bpp uint32 - flags uint32 - cacheIndex uint16 - key1 uint32 - key2 uint32 - bitmapData BitmapDataEx -} -type BitmapDataEx struct { - bpp uint8 - codecID uint8 - width uint16 - height uint16 - length uint32 - data []byte -} - -func (s *Secondary) updateCacheBitmapV3Order(r io.Reader, flags uint16) { - var cb CacheBitmapV3Order - - cb.cacheId = uint32(flags) & 0x00000003 - cb.flags = (uint32(flags) & 0x0000FF80) >> 7 - bitsPerPixelId := (uint32(flags) & 0x00000078) >> 3 - cb.bpp = getCbV2Bpp(bitsPerPixelId) - - cacheIndex, _ := core.ReadUint16LE(r) - cb.cacheIndex = cacheIndex - cb.key1, _ = core.ReadUInt32LE(r) - cb.key2, _ = core.ReadUInt32LE(r) - - bitmapData := &cb.bitmapData - bitmapData.bpp, _ = core.ReadUInt8(r) - core.ReadUInt8(r) - core.ReadUInt8(r) - bitmapData.codecID, _ = core.ReadUInt8(r) - bitmapData.width, _ = core.ReadUint16LE(r) - bitmapData.height, _ = core.ReadUint16LE(r) - new_len, _ := core.ReadUInt32LE(r) - - bitmapData.data, _ = core.ReadBytes(int(new_len), r) - bitmapData.length = new_len - -} - -type CacheColorTableOrder struct { - cacheIndex uint8 - numberColors uint16 - colorTable [256 * 4]uint8 -} - -func (s *Secondary) updateCacheColorTableOrder(r io.Reader, flags uint16) { - var cb CacheColorTableOrder - cb.cacheIndex, _ = core.ReadUInt8(r) - cb.numberColors, _ = core.ReadUint16LE(r) - - if cb.numberColors != 256 { - /* This field MUST be set to 256 */ - return - } - - for i := 0; i < int(cb.numberColors)*4; i++ { - cb.colorTable[i], cb.colorTable[i+1], cb.colorTable[i+2], cb.colorTable[i+3] = updateReadColorRef(r) - } -} -func updateReadColorRef(r io.Reader) (uint8, uint8, uint8, uint8) { - blue, _ := core.ReadUInt8(r) - green, _ := core.ReadUInt8(r) - red, _ := core.ReadUInt8(r) - core.ReadUInt8(r) - - return blue, green, red, 255 -} - -type CacheGlyphOrder struct { - cacheId uint8 - nglyphs uint8 - glyphs []CacheGlyph -} -type CacheGlyph struct { - character uint16 - offset uint16 - baseline uint16 - width uint16 - height uint16 - datasize int - data []uint8 -} - -func (s *Secondary) updateCacheGlyphOrder(r io.Reader, flags uint16) { - var cb CacheGlyphOrder - - cb.cacheId, _ = core.ReadUInt8(r) - cb.nglyphs, _ = core.ReadUInt8(r) - cb.glyphs = make([]CacheGlyph, 0, cb.nglyphs) - - for i := 0; i < int(cb.nglyphs); i++ { - var c CacheGlyph - c.character, _ = core.ReadUint16LE(r) - c.offset, _ = core.ReadUint16LE(r) - c.baseline, _ = core.ReadUint16LE(r) - c.width, _ = core.ReadUint16LE(r) - c.height, _ = core.ReadUint16LE(r) - - c.datasize = int(c.height*((c.width+7)/8)+3) & ^3 - c.data, _ = core.ReadBytes(c.datasize, r) - - cb.glyphs = append(cb.glyphs, c) - } -} - -type CacheBrushOrder struct { - index uint8 - bpp uint8 - cx uint8 - cy uint8 - style uint8 - length uint8 - data []uint8 -} - -func (s *Secondary) updateCacheBrushOrder(r io.Reader, flags uint16) { - var cb CacheBrushOrder - cb.index, _ = core.ReadUInt8(r) - cb.bpp, _ = core.ReadUInt8(r) - cb.cx, _ = core.ReadUInt8(r) - cb.cy, _ = core.ReadUInt8(r) - cb.style, _ = core.ReadUInt8(r) - cb.length, _ = core.ReadUInt8(r) - if cb.cx == 8 && cb.cy == 8 { - if cb.bpp == 1 { - if len(cb.data) >= 7 { - for i := 7; i >= 0; i-- { - cb.data[i], _ = core.ReadUInt8(r) - } - } - - } else { - bpp := int(cb.bpp) - 2 - if int(cb.length) == 16+4*bpp { - /* compressed brush */ - data, _ := core.ReadBytes(int(cb.length), r) - cb.data = update_decompress_brush(data, bpp) - } else { - /* uncompressed brush */ - scanline := 8 * 8 * bpp - cb.data, _ = core.ReadBytes(scanline, r) - } - } - } -} -func update_decompress_brush(in []uint8, bpp int) []uint8 { - var pal_index, in_index, shift int - - pal := in[16:] - out := make([]uint8, 8*8*bpp) - /* read it bottom up */ - for y := 7; y >= 0; y-- { - /* 2 bytes per row */ - x := 0 - for do2 := 0; do2 < 2; do2++ { - /* 4 pixels per byte */ - shift = 6 - for shift >= 0 { - pal_index = int((in[in_index] >> shift) & 3) - /* size of palette entries depends on bpp */ - for i := 0; i < bpp; i++ { - out[(y*8+x)*bpp+i] = pal[pal_index*bpp+i] - } - x++ - shift -= 2 - } - in_index++ - } - } - - return out -} - -/*Primary*/ -type Bounds struct { - left int32 - top int32 - right int32 - bottom int32 -} -type OrderInfo struct { -} diff --git a/mylib/grdp/protocol/pdu/pdu.go b/mylib/grdp/protocol/pdu/pdu.go index eba822a..8406e69 100644 --- a/mylib/grdp/protocol/pdu/pdu.go +++ b/mylib/grdp/protocol/pdu/pdu.go @@ -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) } } } diff --git a/mylib/grdp/protocol/rfb/rfb.go b/mylib/grdp/protocol/rfb/rfb.go deleted file mode 100644 index eacd703..0000000 --- a/mylib/grdp/protocol/rfb/rfb.go +++ /dev/null @@ -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()) -}