From 0bc573c93837eb3f663c3e29bf66288a38380dfb Mon Sep 17 00:00:00 2001 From: sylvain Date: Thu, 17 Oct 2013 22:09:33 +0200 Subject: [PATCH] begining of mcs layer --- rdpy/main.py | 3 +- rdpy/protocol/rdp/ber.py | 22 +++++++++ rdpy/protocol/rdp/gcc.py | 94 +++++++++++++++++++++++++-------------- rdpy/protocol/rdp/mcs.py | 25 +++++++++++ rdpy/protocol/rdp/tpdu.py | 40 ++++++++--------- 5 files changed, 129 insertions(+), 55 deletions(-) create mode 100644 rdpy/protocol/rdp/ber.py diff --git a/rdpy/main.py b/rdpy/main.py index 50e293a..72270ae 100644 --- a/rdpy/main.py +++ b/rdpy/main.py @@ -31,6 +31,7 @@ if __name__ == '__main__': #w.show() from twisted.internet import reactor #reactor.connectTCP("127.0.0.1", 5901, factory.RfbFactory(protocol)) - reactor.connectTCP("192.168.135.160", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU()))) + #reactor.connectTCP("192.168.135.160", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU()))) + reactor.connectTCP("192.168.122.184", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU()))) reactor.run() sys.exit(app.exec_()) \ No newline at end of file diff --git a/rdpy/protocol/rdp/ber.py b/rdpy/protocol/rdp/ber.py new file mode 100644 index 0000000..bc47c6b --- /dev/null +++ b/rdpy/protocol/rdp/ber.py @@ -0,0 +1,22 @@ +''' +@author: sylvain +''' +from rdpy.protocol.network.type import UInt16Le +from rdpy.utils.const import ConstAttributes + +@ConstAttributes +class BerPc(object): + BER_PC_MASK = UInt16Le(0x20) + BER_PRIMITIVE = UInt16Le(0x00) + BER_CONSTRUCT = UInt16Le(0x20) + +def berPC(pc): + ''' + return BER_CONSTRUCT if true + BER_PRIMITIVE if false + ''' + if pc: + return BerPc.BER_CONSTRUCT + else: + return BerPc.BER_PRIMITIVE + \ No newline at end of file diff --git a/rdpy/protocol/rdp/gcc.py b/rdpy/protocol/rdp/gcc.py index 9ae8226..ea92ef3 100644 --- a/rdpy/protocol/rdp/gcc.py +++ b/rdpy/protocol/rdp/gcc.py @@ -2,24 +2,36 @@ @author sylvain @summary gcc language ''' -#constants declaration -#server data -SC_CORE = 0x0C01 -SC_SECURITY = 0x0C02 -SC_NET = 0x0C03 +from rdpy.utils.const import ConstAttributes +from rdpy.protocol.network.type import UInt32Le, UInt16Le, String, CompositeType -#client data -CS_CORE = 0xC001 -CS_SECURITY = 0xC002 -CS_NET = 0xC003 -CS_CLUSTER = 0xC004 -CS_MONITOR = 0xC005 -#depth color -RNS_UD_COLOR_8BPP = 0xCA01 -RNS_UD_COLOR_16BPP_555 = 0xCA02 -RNS_UD_COLOR_16BPP_565 = 0xCA03 -RNS_UD_COLOR_24BPP = 0xCA04 +@ConstAttributes +class ServerToClientMessage(object): + SC_CORE = UInt16Le(0x0C01) + SC_SECURITY = UInt16Le(0x0C02) + SC_NET = UInt16Le(0x0C03) + +@ConstAttributes +class ClientToServerMessage(object): + ''' + Client to Server message + ''' + CS_CORE = UInt16Le(0xC001) + CS_SECURITY = UInt16Le(0xC002) + CS_NET = UInt16Le(0xC003) + CS_CLUSTER = UInt16Le(0xC004) + CS_MONITOR = UInt16Le(0xC005) + +@ConstAttributes +class ColorDepth(object): + ''' + depth color + ''' + RNS_UD_COLOR_8BPP = UInt16Le(0xCA01) + RNS_UD_COLOR_16BPP_555 = UInt16Le(0xCA02) + RNS_UD_COLOR_16BPP_565 = UInt16Le(0xCA03) + RNS_UD_COLOR_24BPP = UInt16Le(0xCA04) RNS_UD_24BPP_SUPPORT = 0x0001 RNS_UD_16BPP_SUPPORT = 0x0002 @@ -28,29 +40,45 @@ RNS_UD_32BPP_SUPPORT = 0x0008 RNS_UD_SAS_DEL = 0xAA03 -#rdp version -RDP_VERSION_4 = 0x00080001 -RDP_VERSION_5_PLUS = 0x00080004 - RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001 -class ClientCoreSettings: +@ConstAttributes +class Version(object): + ''' + supported version of RDP + ''' + RDP_VERSION_4 = UInt32Le(0x00080001) + RDP_VERSION_5_PLUS = UInt32Le(0x00080004) + + +class ClientCoreSettings(CompositeType): ''' class that represent core setting of client ''' - rdpVersion = RDP_VERSION_5_PLUS - desktopWidth = 800 - desktopHeight = 600 - kbdLayout = 0x409 - clientBuild = 2100 - clientName = "rdpy" - keyboardType = 4 - keyboardSubType = 0 - keyboardFnKeys = 12 - postBeta2ColorDepth = RNS_UD_COLOR_24BPP + def __init__(self): + CompositeType.__init__(self) + self.rdpVersion = Version.RDP_VERSION_5_PLUS + self.desktopWidth = UInt16Le(800) + self.desktopHeight = UInt16Le(600) + self.padding1 = (UInt16Le(), UInt16Le()) + self.kbdLayout = UInt32Le(0x409) + self.clientBuild = UInt32Le(2100) + self.clientName = "rdpy" + self.padding2 = UInt16Le() + self.keyboardType = UInt32Le(4) + self.keyboardSubType = UInt32Le(0) + self.keyboardFnKeys = UInt32Le(12) + self.padding3 = String(" "*64) + self.postBeta2ColorDepth = ColorDepth.RNS_UD_COLOR_24BPP + self.padding4 = (UInt16Le(), UInt32Le()) + self.highColorDepth = UInt16Le(24) + self.padding5 = (UInt16Le(), UInt16Le()) + self.padding3 = String(" "*64) -class ServerCoreSettings: +class ServerCoreSettings(CompositeType): ''' server side core settings structure ''' - rdpVersion = RDP_VERSION_5_PLUS \ No newline at end of file + def __init__(self): + CompositeType.__init__(self) + self.rdpVersion = Version.RDP_VERSION_5_PLUS \ No newline at end of file diff --git a/rdpy/protocol/rdp/mcs.py b/rdpy/protocol/rdp/mcs.py index e69de29..de321ea 100644 --- a/rdpy/protocol/rdp/mcs.py +++ b/rdpy/protocol/rdp/mcs.py @@ -0,0 +1,25 @@ +''' +@author: sylvain +''' + +from rdpy.protocol.network.layer import LayerAutomata + +class MCS(LayerAutomata): + ''' + Multi Channel Service layer + the main layer of RDP protocol + is why he can do everything and more! + ''' + + def __init__(self, presentation = None): + ''' + ctor call base class ctor + ''' + LayerAutomata.__init__(self, presentation) + + def connect(self): + ''' + connection send for client mode + a write connect initial packet + ''' + \ No newline at end of file diff --git a/rdpy/protocol/rdp/tpdu.py b/rdpy/protocol/rdp/tpdu.py index 83b91ec..6cab9fe 100644 --- a/rdpy/protocol/rdp/tpdu.py +++ b/rdpy/protocol/rdp/tpdu.py @@ -47,13 +47,12 @@ class TPDUConnectHeader(CompositeType): self.padding = (UInt16Be(), UInt16Be(), UInt8()) -class NegotiationRequest(CompositeType): +class Negotiation(CompositeType): ''' negociation request message ''' def __init__(self, protocol = Protocols.PROTOCOL_SSL): CompositeType.__init__(self) - self.header = NegociationType.TYPE_RDP_NEG_REQ self.padding = UInt8() #always 8 self.len = UInt16Le(0x0008) @@ -97,36 +96,29 @@ class TPDU(LayerAutomata): ''' write connection request message ''' - neqReq = NegotiationRequest(self._protocol) - self._transport.send((TPDUConnectHeader(MessageType.X224_TPDU_CONNECTION_REQUEST, sizeof(neqReq)), neqReq)) + neqReq = Negotiation(self._protocol) + self._transport.send((TPDUConnectHeader(MessageType.X224_TPDU_CONNECTION_REQUEST, sizeof(neqReq)), NegociationType.TYPE_RDP_NEG_REQ, neqReq)) self.setNextState(self.recvConnectionConfirm) - def send(self, data): + def send(self, message): ''' write message packet for TPDU layer add TPDU header ''' - s = Stream() - s.write_uint8(2) - s.write_uint8(TPDU.X224_TPDU_DATA) - s.write_uint8(0x80) - s.write(data.getvalue()) - self._transport.send(data) + self._transport.send((UInt8(2), MessageType.X224_TPDU_DATA, UInt8(0x80), message)) def readNeg(self, data): ''' read neagotiation response ''' - code = data.read_uint8() - - if code == TPDU.TYPE_RDP_NEG_FAILURE: + code = UInt8() + data.readType(code) + if code == NegociationType.TYPE_RDP_NEG_FAILURE: self.readNegFailure(data) - elif code == TPDU.TYPE_RDP_NEG_RSP: + elif code == NegociationType.TYPE_RDP_NEG_RSP: self.readNegResp(data) else: raise InvalidExpectedDataException("bad protocol negotiation response code") - #_transport is TPKT and transport is TCP layer of twisted - self._transport.transport.startTLS(ClientTLSContext()) def readNegFailure(self, data): ''' @@ -138,16 +130,22 @@ class TPDU(LayerAutomata): ''' read negotiation response packet ''' - flag = data.read_uint8() - len = data.read_leuint16() + negResp = Negotiation() + data.readType(negResp) - if len != 0x0008: + if negResp.len != UInt16Le(0x0008): raise InvalidExpectedDataException("invalid size of negotiation response") - protocol = data.read_leuint32() + protocol = negResp.protocol if protocol != self._protocol: raise NegotiationFailure("protocol negotiation failure") + #_transport is TPKT and transport is TCP layer of twisted + if self._protocol == Protocols.PROTOCOL_SSL: + self._transport.transport.startTLS(ClientTLSContext()) + else: + raise NegotiationFailure("protocol negociation failure") + #open ssl needed from twisted.internet import ssl