Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for xrdp backend #294

Open
khast3x opened this issue Feb 4, 2021 · 12 comments
Open

Support for xrdp backend #294

khast3x opened this issue Feb 4, 2021 · 12 comments
Labels
honeypot investigate Needs more thought / experience

Comments

@khast3x
Copy link

khast3x commented Feb 4, 2021

Hello,

Does PyRDP support using the mitm feature in front of a xrdp server? If not, this could help deploy honeypots with a small alpine/ubuntu container acting as RDP backend.
This is the current output when running as a mitm for a ubuntu+xrdp container (it is a bit verbose, sorry):

user@dockervps:~# docker run -d --name uxrdp --hostname terminalserver --shm-size 1g danielguerra/ubuntu-xrdp
user@dockervps:~# docker run -p 3389:3389 gosecure/pyrdp pyrdp-mitm.py 172.17.0.2
[2021-02-04 18:53:46,507] - INFO - GLOBAL - pyrdp.mitm - Target: 172.17.0.2:3389
[2021-02-04 18:53:46,507] - INFO - GLOBAL - pyrdp.mitm - Output directory: /home/pyrdp/pyrdp_output
[2021-02-04 18:53:46,509] - INFO - GLOBAL - pyrdp - MITM Server listening on port 3389
[2021-02-04 18:54:16,729] - INFO - Jeanne859549 - pyrdp.mitm.connections.tcp - New client connected from xx.xx.xx.22
[2021-02-04 18:54:16,730] - INFO - Jeanne859549 - pyrdp.mitm.connections.x224 - No cookie for this connection
[2021-02-04 18:54:16,733] - INFO - Jeanne859549 - pyrdp.mitm.connections.tcp - Server connected
[2021-02-04 18:54:17,856] - INFO - Jeanne859549 - pyrdp.mitm.connections.cert - Cloned server certificate to pyrdp_output/certs/Terminalserver.crt
CLIENT_RANDOM 605840d49e2b351091cb3c83a154c7923c09e1a634c24958c494429050124282 c0898b9270fb5aa7483ac14c8deb1fdfa3c89921419396cbf364f08b8b8f81f7ad34098bd28257bf611a8a11546a03aa
[2021-02-04 18:54:20,520] - INFO - Jeanne859549 - pyrdp.mitm.connections.mcs - Client hostname shinyboi
CLIENT_RANDOM 13e4e08473315c9113328b458a64b9ca6b380172d89e06ffdae5fad186ab2068 aab6858872e3782f775abaae75feae9e0d20854de346676dc44ffa3f7c17b2456a0350a184f03f03bbedc2cacdb1eeee
[2021-02-04 18:54:21,318] - INFO - Jeanne859549 - pyrdp.mitm.connections.security - Client Info: username = '\x00', password = '\x00', domain = '\x00', clientAddress = '192.168.1.63\x00\x00'
[2021-02-04 18:54:21,422] - ERROR - Jeanne859549 - pyrdp.mitm.connections.tcp - 6 is not a valid CapabilityType
ValueError: 6 is not a valid CapabilityType

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/tcp.py", line 92, in dataReceived
    self.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/segmentation.py", line 79, in recv
    layer.recv(forwarded)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/buffered.py", line 55, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 110, in pduReceived
    self.observer.onPDUReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 82, in __call__
    self.composite.doCall(self.item, args, kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 56, in doCall
    getattr(observer, item)(*args, **kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 48, in onPDUReceived
    self.handlers[pdu.header](pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mitm/MCSMITM.py", line 257, in onSendDataIndication
    self.serverChannels[pdu.channelID].recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mcs/channel.py", line 33, in recv
    self.next.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/rdp/security.py", line 142, in recv
    self.next.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 142, in recv
    pdu = self.mainParser.parse(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/parser.py", line 49, in parse
    return super().parse(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/parser.py", line 24, in parse
    return self.doParse(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/rdp/slowpath.py", line 67, in doParse
    return self.parsers[header.pduType](stream, header)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/rdp/slowpath.py", line 156, in parseDemandActive
    parsedCapabilitySets = self.parseCapabilitySets(capabilitySets, numberCapabilities)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/rdp/slowpath.py", line 199, in parseCapabilitySets
    capabilitySets[CapabilityType(capabilitySetType)] = capability
  File "/usr/lib/python3.8/enum.py", line 309, in __call__
    return cls.__new__(cls, value)
  File "/usr/lib/python3.8/enum.py", line 600, in __new__
    raise exc
  File "/usr/lib/python3.8/enum.py", line 584, in __new__
    result = cls._missing_(value)
  File "/usr/lib/python3.8/enum.py", line 613, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 6 is not a valid CapabilityType
[2021-02-04 18:54:21,427] - ERROR - Jeanne859549 - pyrdp.mitm.connections.tcp - Exception occurred when receiving: 030001bc02f08068000103eb7081adad011100ea03ea03010004009701524450000f00000009000800ea03b5e201001800010003000002000000000104000000000000000002001c000000010001000100000000000000010001000000000000000e000400030058000000000000000000000000000000000040420f0001001400000001002f0022000101010100000000010001000000000000000100000000000000000100000000a106020040420f0040420f0001000000000000001d005d0004b91b8dca0f004f15589fae2d1a87e2d6010300010103122f777672bd6344afb3b73c9c6f788600040000000000d4cc44278a9d744e803c0ecbeea19c5400040000000000e64caf1bed9e0c43869acb8b37b662370001004b0a0008000600000008000a000100190019000d0058003d0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000170008000300000018000b0002000000030c0006000500001a000800000030001e000800020000001c000c00520000000000000000000000

Traceback (most recent call last):
  File "/opt/venv/lib/python3.8/site-packages/twisted/python/log.py", line 103, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/opt/venv/lib/python3.8/site-packages/twisted/python/log.py", line 86, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/opt/venv/lib/python3.8/site-packages/twisted/python/context.py", line 122, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/opt/venv/lib/python3.8/site-packages/twisted/python/context.py", line 85, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/opt/venv/lib/python3.8/site-packages/twisted/internet/asyncioreactor.py", line 136, in _readOrWrite
    why = method()
  File "/opt/venv/lib/python3.8/site-packages/twisted/internet/tcp.py", line 243, in doRead
    return self._dataReceived(data)
  File "/opt/venv/lib/python3.8/site-packages/twisted/internet/tcp.py", line 249, in _dataReceived
    rval = self.protocol.dataReceived(data)
  File "/opt/venv/lib/python3.8/site-packages/twisted/protocols/tls.py", line 330, in dataReceived
    self._flushReceiveBIO()
  File "/opt/venv/lib/python3.8/site-packages/twisted/protocols/tls.py", line 295, in _flushReceiveBIO
    ProtocolWrapper.dataReceived(self, bytes)
  File "/opt/venv/lib/python3.8/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/tcp.py", line 92, in dataReceived
    self.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/segmentation.py", line 79, in recv
    layer.recv(forwarded)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/buffered.py", line 55, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 110, in pduReceived
    self.observer.onPDUReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 82, in __call__
    self.composite.doCall(self.item, args, kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 56, in doCall
    getattr(observer, item)(*args, **kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 48, in onPDUReceived
    self.handlers[pdu.header](pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mitm/MCSMITM.py", line 257, in onSendDataIndication
    self.serverChannels[pdu.channelID].recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mcs/channel.py", line 33, in recv
    self.next.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/rdp/security.py", line 142, in recv
    self.next.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 142, in recv
    pdu = self.mainParser.parse(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/parser.py", line 49, in parse
    return super().parse(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/parser.py", line 24, in parse
    return self.doParse(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/rdp/slowpath.py", line 67, in doParse
    return self.parsers[header.pduType](stream, header)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/rdp/slowpath.py", line 156, in parseDemandActive
    parsedCapabilitySets = self.parseCapabilitySets(capabilitySets, numberCapabilities)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.0.1.dev0-py3.8-linux-x86_64.egg/pyrdp/parser/rdp/slowpath.py", line 199, in parseCapabilitySets
    capabilitySets[CapabilityType(capabilitySetType)] = capability
  File "/usr/lib/python3.8/enum.py", line 309, in __call__
    return cls.__new__(cls, value)
  File "/usr/lib/python3.8/enum.py", line 600, in __new__
    raise exc
  File "/usr/lib/python3.8/enum.py", line 584, in __new__
    result = cls._missing_(value)
  File "/usr/lib/python3.8/enum.py", line 613, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
builtins.ValueError: 6 is not a valid CapabilityType

[2021-02-04 18:54:21,431] - INFO - Jeanne859549 - pyrdp.mitm.connections.tcp - Server connection closed. Connection to the other side was lost in a non-clean fashion: Connection lost.

Cheers!

@michelbf
Copy link

michelbf commented Mar 9, 2021

This would be really helpful as I'm also looking to using this in an Ubuntu honeypot running xrdp.

@jkasser
Copy link

jkasser commented Oct 8, 2021

Hey @michelbf @khast3x, have either of you figured out a way around this? I am running into it as well.

@michelbf
Copy link

michelbf commented Oct 8, 2021

I, unfortunately, don't have a solution for this.

@khast3x
Copy link
Author

khast3x commented Oct 10, 2021

Same ^

@obilodeau obilodeau added honeypot investigate Needs more thought / experience labels Oct 12, 2021
@dylanhudson
Copy link

Also wrestling with this error; can't say I have a solution but maybe someone who knows more about xRDP can shed some light on what I've found so far:

On page 91 of Microsoft's RDP spec, they lay out the structure for CapabilitySets. As you can see, there is no corresponding type for a value of 6. The structure is mirrored in PyRDP here -

class CapabilityType(IntEnum):

It appears from the above stack trace that xRDP has sent a CapabilitySetType of 6, which does not exist. I'm trying to track down where and why this is set in the xRDP source- my best guess so far is here on line 87- https://github.com/neutrinolabs/xrdp/blob/devel/libxrdp/xrdp_caps.c
...but I don't know squat about xRDP. If I have time to read and understand more of the code that sets the CapabilitySetType, I'll make some changes and try building from source, and see what happens, or if there's any further useful errors.

@obilodeau
Copy link
Member

obilodeau commented Oct 15, 2021

You could just add an entry in the enum in pyrdp and test. Something like:

    CAPSTYPE_BOGUS_XRDP = 0x0006

and see if everything starts working from there or if something fails

@jkasser
Copy link

jkasser commented Oct 15, 2021

I made that change and am now digging into this error:

[2021-10-15 18:46:51,772] - ERROR - Ted978785 - pyrdp.mitm.connections.tcp - <CapabilityType.CAPSTYPE_VIRTUALCHANNEL: 20>
Traceback (most recent call last):
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/tcp.py", line 92, in dataReceived
    self.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/segmentation.py", line 79, in recv
    layer.recv(forwarded)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/buffered.py", line 55, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 203, in pduReceived
    self.next.recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 110, in pduReceived
    self.observer.onPDUReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 82, in __call__
    self.composite.doCall(self.item, args, kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 56, in doCall
    getattr(observer, item)(*args, **kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 48, in onPDUReceived
    self.handlers[pdu.header](pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mitm/MCSMITM.py", line 259, in onSendDataIndication
    self.serverChannels[pdu.channelID].recv(pdu.payload)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mcs/channel.py", line 33, in recv
    self.next.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/rdp/security.py", line 142, in recv
    self.next.recv(data)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 145, in recv
    self.pduReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/layer.py", line 110, in pduReceived
    self.observer.onPDUReceived(pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 82, in __call__
    self.composite.doCall(self.item, args, kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/core/observer.py", line 56, in doCall
    getattr(observer, item)(*args, **kwargs)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mitm/SlowPathMITM.py", line 56, in onServerPDUReceived
    SlowPathObserver.onPDUReceived(self.serverObserver, pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/layer/rdp/slowpath.py", line 49, in onPDUReceived
    self.handlers[pdu.header.pduType](pdu)
  File "/opt/venv/lib/python3.8/site-packages/pyrdp-1.1.1.dev0-py3.8-linux-x86_64.egg/pyrdp/mitm/SlowPathMITM.py", line 112, in onDemandActive
    pdu.parsedCapabilitySets[CapabilityType.CAPSTYPE_VIRTUALCHANNEL].flags = \
KeyError: <CapabilityType.CAPSTYPE_VIRTUALCHANNEL: 20>

@obilodeau
Copy link
Member

I don't understand why but there is no VirtualChannel setup at this point in the connection yet PyRDP assumes there is. Apply this patch. It will test if there's a virtualchannel before trying to disable its compression.

diff --git a/pyrdp/mitm/SlowPathMITM.py b/pyrdp/mitm/SlowPathMITM.py
index 0bff4aa..f4e1dd5 100644
--- a/pyrdp/mitm/SlowPathMITM.py
+++ b/pyrdp/mitm/SlowPathMITM.py
@@ -109,5 +109,6 @@ class SlowPathMITM(BasePathMITM):
             supported[Order.TS_NEG_DRAWNINEGRID_INDEX] = 0
             orders.orderSupport = supported
 
-        pdu.parsedCapabilitySets[CapabilityType.CAPSTYPE_VIRTUALCHANNEL].flags = \
-            VirtualChannelCompressionFlag.VCCAPS_NO_COMPR
+        if CapabilityType.CAPSTYPE_VIRTUALCHANNEL in pdu.parsedCapabilitySets:
+            pdu.parsedCapabilitySets[CapabilityType.CAPSTYPE_VIRTUALCHANNEL].flags = \
+                VirtualChannelCompressionFlag.VCCAPS_NO_COMPR

@obilodeau
Copy link
Member

Did the patch get you further? Should I add this to PyRDP?

@dylanhudson
Copy link

hey, sorry for not following up sooner, that was very helpful!
Yes, the patch worked to resolve that, although we ran into some separate issues with our virtualization that prevented us from confirming full functionality afterwards.
I think adding the patch would be great; it would be really helpful to be able to deploy it in docker without having to manually overwrite the source.

@obilodeau
Copy link
Member

Added the patch to master. It will be part of the next release. Leaving this issue open since we are not sure about resolution.

obilodeau added a commit to alxbl/pyrdp that referenced this issue Jan 6, 2022
obilodeau added a commit that referenced this issue Jan 17, 2022
@saluto
Copy link

saluto commented Mar 31, 2023

In addition to the two already mentioned patches (this and this, where currently only the latter is merged/released), I also had to change 0x2a to len(pdu.payload) + 14) in parser/gcc.py#L132. It seems that XRDP would otherwise ignore the requested channels and return 0 channels, resulting in an error on the client side.

After the changes, a simple pyrdp MITM seems to work (on Linux with XRDP server and Remmina client or FreeRDP client), even though the client shows the following messages (which don't occur when connecting directly to XRDP instead of MITM server):

[...] [ERROR][com.freerdp.core.rdp] - incorrect PDU type: 0x0000
[...] [WARN][com.freerdp.core.rdp] - pduType UNKNOWN 0000 not properly parsed, 122 bytes remaining unhandled. Skipping.

I'm not sure what this might break. Also, I'm not sure whether my patch breaks support for other servers, e.g. on Windows. Could someone check that? I currently only have Linux with XRDP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
honeypot investigate Needs more thought / experience
Projects
None yet
Development

No branches or pull requests

6 participants