GoSecure / pyrdp

RDP monster-in-the-middle (mitm) and library for Python with the ability to watch connections live or after the fact

Home Page:https://www.gosecure.net/blog/2020/10/20/announcing-pyrdp-1/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Smart Cards not working with the MITM component

keremenci opened this issue · comments

When connecting to a server via pyrdp MITM, smart cards are not working properly. The device appears on the remote host but the certificates in the smart card are unaccessible.

Supporting SmartCard is not something we are interested in at this point. I don't even know how to test it.

That said, if you are willing to do the exploration and the code changes required, we can guide you.

I used EIDVirtual to create a smart card out of an usb stick. By installing EIDVirtual on the server, one can use the smart card manager to view the certificates on the smart card in the remote server.
It appears that the device is recognized but the certificates cannot be read from the card. I dumped the incoming and outgoing network packets but couldn't figure out the decryption in wireshark. Would love some help with that

Information about how to decrypt TLS traffic with Wireshark can be found in Wireshark's wiki. An easier-to-follow tutorial with screenshots is also available here: https://unit42.paloaltonetworks.com/wireshark-tutorial-decrypting-https-traffic/.

Record the whole conversation then open the pcap following the TLS decryption instructions. The TLS master-secrets will be in pyrdp_output/logs/ssl.log.

Good luck and keep us posted on your progress!

After dumping the incoming and outgoing packets via tcpdump using the following filters:

  • sudo tcpdump -s 0 -i <interface> -w in.pcap src <client ip> and dst port 3389
  • sudo tcpdump -s 0 -i <interface> -w out.pcap src <mitm ip> and dst <server ip> and dst port 3389

I don't seem to be able to filter the traffic by rdp in wireshark, and all I see is a bit of TLS1.2 traffic followed by a large amount of TCP packets. I did configure wireshark to use the log field and also supplied the private key in the preferences > protocols > TLS

This is what i did in order:

  • Run the first tcpdump command
  • Run the second tcpdump
  • Run the mitm
  • Connect via rdp and try to read the smart card, fail
  • Disconnect using the button in windows
  • Stop the tcpdump processes
  • Stop the rdp mitm
  • Copy over the pcap files and the key log file over to local
  • Open it in wireshark

Any ideas what I may be missing? My networking knowledge is a bit limited so any help would be appreciated.

Also, it seems that all the IO requests and responses pass through except the 0x000900a4 | FSCTL_SET_REPARSE_POINT call, which has something to do with SCardGetStatusChangeW (Couldn't really figure out this part).

I did configure wireshark to use the log field and also supplied the private key in the preferences > protocols > TLS

Don't supply the private key. Supply the TLS master secrets. Load the ssl.log in the red square here: Wireshark screenshot for TLS config

I tried various combinations of supplying the pk and the log and was not successful

These two IO requests (as defined in the docs) from the server never receive a response. Any ideas on what the cause may be?
image

I think it might be because we implemented MITM for Device IO since it is how we collect files but we haven't done anything regarding smart cards. One approach would be to use a debugger at the right spots and see if you could pass through the exchange back and forth instead of intercepting them.

For example:

install ipdb

add a statement to trigger the debugger at the right spot. In pyrdp/parser/rdp/virtual_channel/device_redirection.py, under:

    def parseDeviceIORequest(self, stream: BytesIO) -> DeviceIORequestPDU:

Add:

import ipdb; ipdb.set_trace()

Restart pyrdp-mitm and see what is mishandled (it might not be the first time the debugger trips)

Good luck!

It appears that the major function field is set to 0x0000000C and the minor function is 0 even though it is explicitly stated that this is not a valid state of the pdu in the docs.
image

You are not providing enough details. Without them, I can't help you.

  • Is the MITM sending the 0, the real server or the real client?
  • If its the MITM is it sending it to the client or to the server?
  • Is the server query before the MITM correct or not?
  • Where in the code is this value changed to a non-valid one?
  • if you debug in parseDirectoryControlResponse from pyrdp/parser/rdp/virtual_channel/device_redirection.py does this help you?

Yes, my bad. Had to tend to some other stuff and could not exactly pay attention. Sorry for any inconvenience this may have caused.

Now that i'm back, I realized that what I said here was incorrect. There is nothing wrong with the pdu.

Upon further investigation, and some parsing by hand, I managed to extract the ioctl codes for the smart card DeviceIOControl calls. I couldn't find anything about the codes that I parsed, but then stumbled across the definitions in the smart card extension page

There really should be no issue for smart cards, as all the pdu's that pass through are just forwarded with no modifications, and I couldn't find anything that was mishandled.

Do we need to do some additional work to support the protocol extensions?

It appears that the major function field is set to 0x0000000C and the minor function is 0 even though it is explicitly stated that this is not a valid state of the pdu in the docs. image

Does that feature use DynamicChannels or VirtualChannels? We don't support DynamicChannels just yet. See #232 for the beginning of that work.

It seems that the server can access the reader while the issues manifest themselves when we try to access the contents of the card.

Certutil hangs here
image
EIDVirtual smart card manager sometimes hangs and sometimes does not start at all. Starting the program via a regular rdp and switching over to the mitm also causes it to hang.

SCM Microsystems PC/SC diagnostic tool identifies the device as working but trying to access it causes the process to hang
image

The behaviour is really chaotic, debugging drops the connection. Dumping the PDU information either causes the smart card resource manager of windows to not start at all, or drops the connection after the following exchange:

900e0 -> SCARD_IOCTL_ACCESSSTARTEDEVENT
90014 -> SCARD_IOCTL_ESTABLISHCONTEXT
9002c -> SCARD_IOCTL_LISTREADERSW
90108 -> SCARD_IOCTL_GETDEVICETYPEID
90014 -> SCARD_IOCTL_ESTABLISHCONTEXT
90108 -> SCARD_IOCTL_GETDEVICETYPEID
90018 -> SCARD_IOCTL_RELEASECONTEXT
900a4 -> SCARD_IOCTL_GETSTATUSCHANGEW
900a4 -> SCARD_IOCTL_GETSTATUSCHANGEW
90014 -> SCARD_IOCTL_ESTABLISHCONTEXT
9002c -> SCARD_IOCTL_LISTREADERSW
900a4 -> SCARD_IOCTL_GETSTATUSCHANGEW
90014 -> SCARD_IOCTL_ESTABLISHCONTEXT
90014 -> SCARD_IOCTL_ESTABLISHCONTEXT
900b0 -> SCARD_IOCTL_CONNECTW
900a4 -> SCARD_IOCTL_GETSTATUSCHANGEW
900bc -> SCARD_IOCTL_BEGINTRANSACTION
900a8 -> SCARD_IOCTL_CANCEL
900a8 -> SCARD_IOCTL_CANCEL

I should also point out that this exchange occurs before the credentials are entered in the login screen

I am kind of lost at this moment. Any ideas?