This post will explore establishing command and control sessions over remote desktop (RDP) virtual channels. As per Microsoft, virtual channels are software extensions that can be used to add functional enhancements to RDP. Audio, shared clipboard, forwarded drives, and printer redirection are all examples of virtual channels in action; doesn’t it make life easier? Well it comes at a risk. Before getting into it, I have to mention that this is not a new area of research, listed below are tools and information I leveraged to put this post together.
- NCCGroup’s Virtual Channel Research
- OutFlank’s External C2 Example
- XPN’s Exploring External C2 Post
- Earthquake’s Universal Dynamic Virtual Channel
- AwakeCoding’s TsTeleport
While speaking at OT Cybersecurity conferences I’ve always preached the importance of egress filtering. Reason is, whenever we hijack a MFA’d session at the IT/OT perimeter, the first thing we (and attackers) do is attempt to setup an out-of-band command and control session to establish a more permanent foothold in the environment.
Since egress dataflows from the OT to the IT are often few or not required, correctly configured egress filtering can make this difficult bordering on impossible. However, command and control sessions over RDP virtual channels entirely circumvent egress filtering. So having been such an advocate of egress filtering (it’s still important), I felt it was necessary to explore this topic further.
Command and Control Over Redirected Drives (External C2)
As you’ve probably noticed I use Cobalt Strike so this post will focus around it. Raphael Mudge, developer of Cobalt Strike, released the specs for External C2 which provided us the ability to establish a command and control session outside of the traditional TCP and UDP sockets. For example, XPN and OutFlank each wrote blog posts detailing how to establish a command and control session over a shared file between the teamserver and the target system. From a virtual channel standpoint, we can leverage RDP drive redirection to take this a step further.
Using OutFlank’s PoC, we copy and execute c2file.exe on the remote desktop server which generates a command and control data transfer file on a mapped redirected drive. The second step of the process sees us run a python script which communicates with the teamserver while reading and writing to the data transfer file, the end result is a Cobalt Strike session entirely over ingress TCP/3389.
The next tool I came across when digging into RDP virtual channels was rdp2tcp. Using rdp2tcp, we can stand up a SOCKS server or do port forwarding over RDP virtual channels. I liked rdp2tcp for two reasons: one, the virtual channel bypassed device redirection restriction policies and two, the latest FreeRDP version includes rdp2tcp functionality (you still need the client/server executable).
Universal Dynamic Virtual Channel
Universal Dynamic Virtual Channel (UDVC) is written by earthquake and is part of the XFLTReaT tunneling toolkit. There is source code for a client dll plugin and a server executable to establish a dynamic virtual channel over RDP. The channel can be put into socket (server || client) or named pipe mode. Priority can also be set to provide better performance for the command and control virtual channel; however, there is risk associated with assigning higher priority and how it could impact the RDP session.
From an offensive standpoint, I’m a big fan of UDVC. I’ve had engagements where we’ve had 20+ pivot sessions spawned off a single RDP virtual channel without any performance issues. It’s simple to setup and provides good error messaging. Additionally, I think there is potential to leverage a modified version of UDVC to create an event-driven solution which establishes a background command and control session whenever a user remote desktops to a server.
- 00:19 – Ingrid establishes a remote desktop session to the OT DMZ jumphost.
- 00:48 – IT network fully compromised.
- 01:07 – Ingrid walks away from IT PC with a idle OT session.
- 01:30 – Seizing Ingrid’s IT PC, and by extension, OT session.
- 02:01 – Copy files via shared clipboard to the OT jumphost
- 02:13 – Batch file which creates a schedule task that runs the modified UDVC-Server at user OnLogon.
- 02:31 – Register UDVC plugin and create 127.0.0.1:443 reverse tcp listener on IT systems.
- 02:44 to End – Users logging into the OT jumphost which establishes the UDVC channel and runs the reverse pivot payload.
On the Defensive
Fortunately, blocking redirected devices via RDP is quite simple and can be done with GPO. Safe bet is to disable as much as possible as any redirected device that sends and receives data can be used to establish a C2 session, that includes COM ports, clipboard, printers and so on. In my opinion, this is a must at the IT/OT boundary.
Computer Configuration\Policies\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection
For rdp2tcp and UDVC, endpoint protection is paramount. Each of the demonstrated tools kicked things off via an executable. Standard antivirus won’t do much; however, in this case, application whitelisting (AWL) would have blocked each attempt. On a critical system like the Jumphost at the IT/OT boundary, AWL is a must. As a defender, you want to force the attacker to leverage an AWL bypass + UDVC to gain a foothold.
Finally, I wrote a silly PoC application which enumerates RDP sessions and scans for rdp2tcp and UDVC virtual channels, check it out here.