mirror of
https://github.com/yv1ing/ShotRDP.git
synced 2025-09-16 15:10:57 +08:00
基本适应win7,win10,win server 08,win server 12,win server 16的截图
This commit is contained in:
229
grdp/protocol/tpkt/tpkt.go
Normal file
229
grdp/protocol/tpkt/tpkt.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package tpkt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"ShotRDP/grdp/core"
|
||||
"ShotRDP/grdp/emission"
|
||||
"ShotRDP/grdp/glog"
|
||||
"ShotRDP/grdp/protocol/nla"
|
||||
)
|
||||
|
||||
// take idea from https://github.com/Madnikulin50/gordp
|
||||
|
||||
/**
|
||||
* Type of tpkt packet
|
||||
* Fastpath is use to shortcut RDP stack
|
||||
* @see http://msdn.microsoft.com/en-us/library/cc240621.aspx
|
||||
* @see http://msdn.microsoft.com/en-us/library/cc240589.aspx
|
||||
*/
|
||||
const (
|
||||
FASTPATH_ACTION_FASTPATH = 0x0
|
||||
FASTPATH_ACTION_X224 = 0x3
|
||||
)
|
||||
|
||||
/**
|
||||
* TPKT layer of rdp stack
|
||||
*/
|
||||
type TPKT struct {
|
||||
emission.Emitter
|
||||
Conn *core.SocketLayer
|
||||
ntlm *nla.NTLMv2
|
||||
secFlag byte
|
||||
lastShortLength int
|
||||
fastPathListener core.FastPathListener
|
||||
ntlmSec *nla.NTLMv2Security
|
||||
}
|
||||
|
||||
func New(s *core.SocketLayer, ntlm *nla.NTLMv2) *TPKT {
|
||||
t := &TPKT{
|
||||
Emitter: *emission.NewEmitter(),
|
||||
Conn: s,
|
||||
secFlag: 0,
|
||||
ntlm: ntlm}
|
||||
core.StartReadBytes(2, s, t.recvHeader)
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *TPKT) StartTLS() error {
|
||||
return t.Conn.StartTLS()
|
||||
}
|
||||
|
||||
func (t *TPKT) StartNLA() error {
|
||||
err := t.StartTLS()
|
||||
if err != nil {
|
||||
glog.Info("start tls failed", err)
|
||||
return err
|
||||
}
|
||||
req := nla.EncodeDERTRequest([]nla.Message{t.ntlm.GetNegotiateMessage()}, nil, nil)
|
||||
_, err = t.Conn.Write(req)
|
||||
if err != nil {
|
||||
glog.Info("send NegotiateMessage", err)
|
||||
return err
|
||||
}
|
||||
|
||||
resp := make([]byte, 1024)
|
||||
n, err := t.Conn.Read(resp)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read %s", err)
|
||||
} else {
|
||||
glog.Debug("StartNLA Read success")
|
||||
}
|
||||
return t.recvChallenge(resp[:n])
|
||||
}
|
||||
|
||||
func (t *TPKT) recvChallenge(data []byte) error {
|
||||
glog.Trace("recvChallenge", hex.EncodeToString(data))
|
||||
tsreq, err := nla.DecodeDERTRequest(data)
|
||||
if err != nil {
|
||||
glog.Info("DecodeDERTRequest", err)
|
||||
return err
|
||||
}
|
||||
glog.Debugf("tsreq:%+v", tsreq)
|
||||
// get pubkey
|
||||
pubkey, err := t.Conn.TlsPubKey()
|
||||
glog.Debugf("pubkey=%+v", pubkey)
|
||||
|
||||
authMsg, ntlmSec := t.ntlm.GetAuthenticateMessage(tsreq.NegoTokens[0].Data)
|
||||
t.ntlmSec = ntlmSec
|
||||
|
||||
encryptPubkey := ntlmSec.GssEncrypt(pubkey)
|
||||
req := nla.EncodeDERTRequest([]nla.Message{authMsg}, nil, encryptPubkey)
|
||||
_, err = t.Conn.Write(req)
|
||||
if err != nil {
|
||||
glog.Info("send AuthenticateMessage", err)
|
||||
return err
|
||||
}
|
||||
resp := make([]byte, 1024)
|
||||
n, err := t.Conn.Read(resp)
|
||||
if err != nil {
|
||||
glog.Error("Read:", err)
|
||||
return fmt.Errorf("read %s", err)
|
||||
} else {
|
||||
glog.Debug("recvChallenge Read success")
|
||||
}
|
||||
return t.recvPubKeyInc(resp[:n])
|
||||
}
|
||||
|
||||
func (t *TPKT) recvPubKeyInc(data []byte) error {
|
||||
glog.Trace("recvPubKeyInc", hex.EncodeToString(data))
|
||||
tsreq, err := nla.DecodeDERTRequest(data)
|
||||
if err != nil {
|
||||
glog.Info("DecodeDERTRequest", err)
|
||||
return err
|
||||
}
|
||||
glog.Trace("PubKeyAuth:", tsreq.PubKeyAuth)
|
||||
//ignore
|
||||
//pubkey := t.ntlmSec.GssDecrypt([]byte(tsreq.PubKeyAuth))
|
||||
domain, username, password := t.ntlm.GetEncodedCredentials()
|
||||
credentials := nla.EncodeDERTCredentials(domain, username, password)
|
||||
authInfo := t.ntlmSec.GssEncrypt(credentials)
|
||||
req := nla.EncodeDERTRequest(nil, authInfo, nil)
|
||||
_, err = t.Conn.Write(req)
|
||||
if err != nil {
|
||||
glog.Info("send AuthenticateMessage", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TPKT) Read(b []byte) (n int, err error) {
|
||||
return t.Conn.Read(b)
|
||||
}
|
||||
|
||||
func (t *TPKT) Write(data []byte) (n int, err error) {
|
||||
buff := &bytes.Buffer{}
|
||||
core.WriteUInt8(FASTPATH_ACTION_X224, buff)
|
||||
core.WriteUInt8(0, buff)
|
||||
core.WriteUInt16BE(uint16(len(data)+4), buff)
|
||||
buff.Write(data)
|
||||
glog.Trace("tpkt Write", hex.EncodeToString(buff.Bytes()))
|
||||
return t.Conn.Write(buff.Bytes())
|
||||
}
|
||||
|
||||
func (t *TPKT) Close() error {
|
||||
return t.Conn.Close()
|
||||
}
|
||||
|
||||
func (t *TPKT) SetFastPathListener(f core.FastPathListener) {
|
||||
t.fastPathListener = f
|
||||
}
|
||||
|
||||
func (t *TPKT) SendFastPath(secFlag byte, data []byte) (n int, err error) {
|
||||
buff := &bytes.Buffer{}
|
||||
core.WriteUInt8(FASTPATH_ACTION_FASTPATH|((secFlag&0x3)<<6), buff)
|
||||
core.WriteUInt16BE(uint16(len(data)+3)|0x8000, buff)
|
||||
buff.Write(data)
|
||||
glog.Trace("TPTK SendFastPath", hex.EncodeToString(buff.Bytes()))
|
||||
return t.Conn.Write(buff.Bytes())
|
||||
}
|
||||
|
||||
func (t *TPKT) recvHeader(s []byte, err error) {
|
||||
glog.Trace("tpkt recvHeader", hex.EncodeToString(s), err)
|
||||
if err != nil {
|
||||
t.Emit("error", err)
|
||||
return
|
||||
}
|
||||
r := bytes.NewReader(s)
|
||||
version, _ := core.ReadUInt8(r)
|
||||
if version == FASTPATH_ACTION_X224 {
|
||||
glog.Debug("tptk recvHeader FASTPATH_ACTION_X224, wait for recvExtendedHeader")
|
||||
core.StartReadBytes(2, t.Conn, t.recvExtendedHeader)
|
||||
} else {
|
||||
t.secFlag = (version >> 6) & 0x3
|
||||
length, _ := core.ReadUInt8(r)
|
||||
t.lastShortLength = int(length)
|
||||
if t.lastShortLength&0x80 != 0 {
|
||||
core.StartReadBytes(1, t.Conn, t.recvExtendedFastPathHeader)
|
||||
} else {
|
||||
core.StartReadBytes(t.lastShortLength-2, t.Conn, t.recvFastPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TPKT) recvExtendedHeader(s []byte, err error) {
|
||||
glog.Trace("tpkt recvExtendedHeader", hex.EncodeToString(s), err)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r := bytes.NewReader(s)
|
||||
size, _ := core.ReadUint16BE(r)
|
||||
glog.Debug("tpkt wait recvData:", size)
|
||||
core.StartReadBytes(int(size-4), t.Conn, t.recvData)
|
||||
}
|
||||
|
||||
func (t *TPKT) recvData(s []byte, err error) {
|
||||
glog.Trace("tpkt recvData", hex.EncodeToString(s), err)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
t.Emit("data", s)
|
||||
core.StartReadBytes(2, t.Conn, t.recvHeader)
|
||||
}
|
||||
|
||||
func (t *TPKT) recvExtendedFastPathHeader(s []byte, err error) {
|
||||
glog.Trace("tpkt recvExtendedFastPathHeader", hex.EncodeToString(s))
|
||||
r := bytes.NewReader(s)
|
||||
rightPart, err := core.ReadUInt8(r)
|
||||
if err != nil {
|
||||
glog.Error("TPTK recvExtendedFastPathHeader", err)
|
||||
return
|
||||
}
|
||||
|
||||
leftPart := t.lastShortLength & ^0x80
|
||||
packetSize := (leftPart << 8) + int(rightPart)
|
||||
core.StartReadBytes(packetSize-3, t.Conn, t.recvFastPath)
|
||||
}
|
||||
|
||||
func (t *TPKT) recvFastPath(s []byte, err error) {
|
||||
glog.Trace("tpkt recvFastPath")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
t.fastPathListener.RecvFastPath(t.secFlag, s)
|
||||
core.StartReadBytes(2, t.Conn, t.recvHeader)
|
||||
}
|
||||
Reference in New Issue
Block a user