add rdp login packet
This commit is contained in:
@@ -230,7 +230,7 @@ class ClientSettings(object):
|
||||
def __init__(self):
|
||||
self.core = ClientCoreSettings()
|
||||
#list of ClientRequestedChannel read network gcc packet
|
||||
self.networkChannels = [ClientRequestedChannel("rdpdr", ChannelOptions.CHANNEL_OPTION_INITIALIZED)]
|
||||
self.networkChannels = []
|
||||
self.security = ClientSecuritySettings()
|
||||
|
||||
class ServerSettings(object):
|
||||
|
||||
@@ -3,35 +3,82 @@
|
||||
'''
|
||||
|
||||
from rdpy.protocol.network.layer import LayerAutomata
|
||||
from rdpy.protocol.network.type import CompositeType, UInt8, UniString, UInt16Le, UInt32Le
|
||||
from rdpy.protocol.network.type import CompositeType, UniString, UInt16Le, UInt16Be, UInt32Le, sizeof
|
||||
from rdpy.utils.const import ConstAttributes, TypeAttributes
|
||||
from rdpy.protocol.network.error import InvalidExpectedDataException
|
||||
|
||||
@ConstAttributes
|
||||
@TypeAttributes(UInt16Le)
|
||||
class SecurityFlag(object):
|
||||
SEC_INFO_PKT = 0x0040
|
||||
SEC_LICENSE_PKT = 0x0080
|
||||
|
||||
@ConstAttributes
|
||||
@TypeAttributes(UInt32Le)
|
||||
class InfoFlag(object):
|
||||
INFO_MOUSE = 0x00000001
|
||||
INFO_DISABLECTRLALTDEL = 0x00000002
|
||||
INFO_AUTOLOGON = 0x00000008
|
||||
INFO_UNICODE = 0x00000010
|
||||
INFO_MAXIMIZESHELL = 0x00000020
|
||||
INFO_LOGONNOTIFY = 0x00000040
|
||||
INFO_COMPRESSION = 0x00000080
|
||||
INFO_ENABLEWINDOWSKEY = 0x00000100
|
||||
INFO_REMOTECONSOLEAUDIO = 0x00002000
|
||||
INFO_FORCE_ENCRYPTED_CS_PDU = 0x00004000
|
||||
INFO_RAIL = 0x00008000
|
||||
INFO_LOGONERRORS = 0x00010000
|
||||
INFO_MOUSE_HAS_WHEEL = 0x00020000
|
||||
INFO_PASSWORD_IS_SC_PIN = 0x00040000
|
||||
INFO_NOAUDIOPLAYBACK = 0x00080000
|
||||
INFO_USING_SAVED_CREDS = 0x00100000
|
||||
INFO_AUDIOCAPTURE = 0x00200000
|
||||
INFO_VIDEO_DISABLE = 0x00400000
|
||||
INFO_CompressionTypeMask = 0x00001E00
|
||||
|
||||
@ConstAttributes
|
||||
@TypeAttributes(UInt32Le)
|
||||
class PerfFlag(object):
|
||||
PERF_DISABLE_WALLPAPER = 0x00000001
|
||||
PERF_DISABLE_FULLWINDOWDRAG = 0x00000002
|
||||
PERF_DISABLE_MENUANIMATIONS = 0x00000004
|
||||
PERF_DISABLE_THEMING = 0x00000008
|
||||
PERF_DISABLE_CURSOR_SHADOW = 0x00000020
|
||||
PERF_DISABLE_CURSORSETTINGS = 0x00000040
|
||||
PERF_ENABLE_FONT_SMOOTHING = 0x00000080
|
||||
PERF_ENABLE_DESKTOP_COMPOSITION = 0x00000100
|
||||
|
||||
@ConstAttributes
|
||||
@TypeAttributes(UInt16Le)
|
||||
class AfInet(object):
|
||||
AF_INET = 0x00002
|
||||
AF_INET6 = 0x0017
|
||||
|
||||
class RDPInfo(CompositeType):
|
||||
def __init__(self):
|
||||
CompositeType.__init__(self)
|
||||
self.audioCapture = UInt8()
|
||||
self.audioPlayback = UInt8()
|
||||
self.autoLogon = UInt8()
|
||||
self.remoteApp = UInt8()
|
||||
self.consoleAudio = UInt8()
|
||||
self.compression = UInt8()
|
||||
self.domain = UniString()
|
||||
self.username = UniString()
|
||||
self.password = UniString()
|
||||
self.codePage = UInt32Le()
|
||||
self.flag = InfoFlag.INFO_MOUSE | InfoFlag.INFO_UNICODE | InfoFlag.INFO_LOGONERRORS | InfoFlag.INFO_LOGONNOTIFY | InfoFlag.INFO_ENABLEWINDOWSKEY | InfoFlag.INFO_DISABLECTRLALTDEL
|
||||
self.cbDomain = UInt16Le(lambda:sizeof(self.domain) - 2)
|
||||
self.cbUserName = UInt16Le(lambda:sizeof(self.userName) - 2)
|
||||
self.cbPassword = UInt16Le(lambda:sizeof(self.password) - 2)
|
||||
self.cbAlternateShell = UInt16Le(lambda:sizeof(self.alternateShell) - 2)
|
||||
self.cbWorkingDir = UInt16Le(lambda:sizeof(self.workingDir) - 2)
|
||||
self.domain = UniString("coco")
|
||||
self.userName = UniString("lolo")
|
||||
self.password = UniString("toto")
|
||||
self.alternateShell = UniString()
|
||||
self.workingDir = UniString()
|
||||
|
||||
class RDPExtendedInfo(CompositeType):
|
||||
def __init__(self):
|
||||
CompositeType.__init__(self)
|
||||
self.ipv6 = UInt8()
|
||||
self.adress = UniString()
|
||||
self.clientDir = UniString()
|
||||
self.performanceFlags = UInt32Le()
|
||||
self.clientAddressFamily = AfInet.AF_INET
|
||||
self.cbClientAddress = UInt16Le(lambda:sizeof(self.clientAddress))
|
||||
self.clientAddress = UniString("192.168.135.10")
|
||||
self.cbClientDir = UInt16Le(lambda:sizeof(self.clientDir))
|
||||
self.clientDir = UniString("c:\\")
|
||||
#self.performanceFlags = PerfFlag.PERF_DISABLE_WALLPAPER | PerfFlag.PERF_DISABLE_MENUANIMATIONS | PerfFlag.PERF_DISABLE_CURSOR_SHADOW
|
||||
|
||||
class GDL(LayerAutomata):
|
||||
'''
|
||||
@@ -44,9 +91,32 @@ class GDL(LayerAutomata):
|
||||
Constructor
|
||||
'''
|
||||
LayerAutomata.__init__(self, None)
|
||||
#set by mcs layer channel init
|
||||
self._channelId = UInt16Be()
|
||||
#logon info send from client to server
|
||||
self._info = RDPInfo()
|
||||
self._extendedInfo = RDPExtendedInfo()
|
||||
|
||||
def connect(self):
|
||||
'''
|
||||
connect event in client mode send logon info
|
||||
nextstate recv licence pdu
|
||||
'''
|
||||
self.sendInfoPkt()
|
||||
#next state is licence info PDU
|
||||
self.setNextState(self.recvLicenceInfo)
|
||||
|
||||
def sendInfoPkt(self):
|
||||
self._transport.send(self, (SecurityFlag.SEC_INFO_PKT, UInt16Le(), RDPInfo(), RDPExtendedInfo()))
|
||||
'''
|
||||
send a logon info packet for RDP version 5 protocol
|
||||
'''
|
||||
#always send extended info because rdpy only accept rdp version 5 and more
|
||||
self._transport.send(self._channelId, (SecurityFlag.SEC_INFO_PKT, UInt16Le(), self._info, self._extendedInfo))
|
||||
|
||||
def recvLicenceInfo(self, data):
|
||||
securityFlag = UInt16Le()
|
||||
securityFlagHi = UInt16Le()
|
||||
data.readType((securityFlag, securityFlagHi))
|
||||
|
||||
if securityFlag & SecurityFlag.SEC_LICENSE_PKT != SecurityFlag.SEC_LICENSE_PKT:
|
||||
raise InvalidExpectedDataException("waiting license packet")
|
||||
@@ -46,18 +46,18 @@ class MCS(LayerAutomata):
|
||||
the main layer of RDP protocol
|
||||
is why he can do everything and more!
|
||||
'''
|
||||
def __init__(self):
|
||||
def __init__(self, presentation):
|
||||
'''
|
||||
ctor call base class ctor
|
||||
@param presentation: presentation layer
|
||||
'''
|
||||
LayerAutomata.__init__(self, None)
|
||||
LayerAutomata.__init__(self, presentation)
|
||||
self._clientSettings = gcc.ClientSettings()
|
||||
self._serverSettings = gcc.ServerSettings()
|
||||
#default user Id
|
||||
self._userId = UInt16Be(1)
|
||||
#list of channel use in this layer and connection state
|
||||
self._channelIds = {Channel.MCS_GLOBAL_CHANNEL: None}
|
||||
self._channelIds = {Channel.MCS_GLOBAL_CHANNEL: presentation}
|
||||
#use to record already requested channel
|
||||
self._channelIdsRequest = {}
|
||||
|
||||
@@ -86,6 +86,7 @@ class MCS(LayerAutomata):
|
||||
for (channelId, layer) in self._channelIds.iteritems():
|
||||
if self._channelIdsRequest[channelId] and not layer is None:
|
||||
layer._transport = self
|
||||
layer._channelId = channelId
|
||||
layer.connect()
|
||||
|
||||
def sendConnectInitial(self):
|
||||
@@ -195,8 +196,7 @@ class MCS(LayerAutomata):
|
||||
@param data: Stream
|
||||
'''
|
||||
opcode = UInt8()
|
||||
confirm = UInt8()
|
||||
data.readType((opcode, confirm))
|
||||
data.readType(opcode)
|
||||
|
||||
if self.readMCSPDUHeader(opcode, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
|
||||
print "receive DISCONNECT_PROVIDER_ULTIMATUM"
|
||||
@@ -215,7 +215,7 @@ class MCS(LayerAutomata):
|
||||
if length & UInt8(0x80) == UInt8(0x80):
|
||||
lengthP2 = UInt8()
|
||||
data.readType(lengthP2)
|
||||
length = (UInt16Be(length.value) << 8) | lengthP2
|
||||
length = UInt16Be(length.value & 0x7f << 8 | lengthP2.value)
|
||||
|
||||
#channel id doesn't match a requested layer
|
||||
if not self._channelIdsRequest.has_key(channelId):
|
||||
@@ -229,13 +229,11 @@ class MCS(LayerAutomata):
|
||||
|
||||
self._channelIds[channelId].recv(data)
|
||||
|
||||
def send(self, fromLayer, data):
|
||||
#retrieve channel id
|
||||
channelId = None
|
||||
for (channelIdTmp, layer) in self._channelIds.iteritems():
|
||||
if layer == fromLayer:
|
||||
channelId = channelIdTmp
|
||||
break
|
||||
def send(self, channelId, data):
|
||||
'''
|
||||
specific send function for channelId
|
||||
@param data: message to send
|
||||
'''
|
||||
self._transport.send((self.writeMCSPDUHeader(DomainMCSPDU.SEND_DATA_REQUEST), self._userId, channelId, UInt8(0x70), UInt16Be(sizeof(data)) | UInt16Be(0x8000), data))
|
||||
|
||||
|
||||
|
||||
@@ -8,10 +8,7 @@ class Factory(protocol.Factory):
|
||||
Factory of RDP protocol
|
||||
'''
|
||||
def __init__(self):
|
||||
mcsLayer = mcs.MCS()
|
||||
#set global channel to graphic layer
|
||||
mcsLayer._channelIds[mcs.Channel.MCS_GLOBAL_CHANNEL] = gdl.GDL()
|
||||
self._protocol = tpkt.TPKT(tpdu.TPDU(mcsLayer))
|
||||
self._protocol = tpkt.TPKT(tpdu.TPDU(mcs.MCS(gdl.GDL())))
|
||||
|
||||
def buildProtocol(self, addr):
|
||||
return self._protocol;
|
||||
|
||||
Reference in New Issue
Block a user