Blog: How-Tos

Exfiltration by encoding data in pixel colour values

Alan Monie 08 Nov 2017

Introduction

Sometimes remote display protocols such as RDP are locked down such that it is not possible to transfer files to, or from, the host. Others such as VMware console or VNC don’t have file transfer capabilities. Uploading code can be performed easily with a Rubber Ducky or tools such as AutoHotkey, but getting results or data back to your hacktop can be more challenging.

Flashing pixels

Four years ago, Dave Lodge, had an idea to encode data in a series of QR codes to pull data back from a host. This method would work, but QR codes do not hold a lot of data, so transferring even 1MB would be time-consuming. I decided to try to increase the bandwidth by encoding data using individual pixel colour values and flashing the remote screen.

A listener on your hacktop would capture the screen flashes and reconstruct the data. A typical laptop screen resolution of 1920×1080 at 24bit colour can encode almost 6MB of data in one image, so this method offers a moderate bandwidth link from the remote host.

Protocol compression

I knocked up a quick client/server tool in .NET to test the idea, and local testing on the same host worked brilliantly, however moving to a remote RDP host I noticed that the RDP protocol didn’t send accurate pixel colour information. It appears that the RDP protocol slightly changes the colour values such that they are not noticeable to a human, but it destroys the encoded data – I wouldn’t be able to encode quite as much data as I initially thought. It looks like the value changes by as much as 6 in any byte from my small sample.

I estimated that it might be possible to encode up to around 15 bits per pixel on a good connection before you’d start losing data. This would likely vary between protocols and connection quality, so I decided to give a good margin of error, and rather than coding three bytes per pixel, I decided to drop it right down to 3 bits per pixel (1 bit for each RGB value in the pixel) to handle the protocol compression “errors”. After I made this change, I tested it over an RDP connection, and was able to exfiltrate a 3MB file in a few seconds.

How it works

Each screen flash starts with a header. This contains a magic string, “PTP-RAT-CHUNK” followed by a sequence number. When the receiver is activated, it starts taking screenshots at twice the transmission frequency (the Nyquist rate). When it detects a valid header, it decodes the pixel colour information and waits on the next flash. As soon as a valid header is not detected, it reconstructs all the flashes and saves the result to a file.

Using the Rat

The Rat is a single-window application which zips to 13k. This can be easily uploaded via keystrokes and turned back into a binary on the remote host.

To transfer a file, you run an instance of the Rat locally on your hacktop, and set that up as a receiver. Another instance is run on the remote server and this acts as a sender. You simply click on send file, and select a file to send. The mouse pointer disappears and the screen begins to flash as the file is transmitted via the pixel colour values. At the end of the transfer, a file-save dialog appears on the receiver, and the file is saved.

You can download the Rat from here:
https://github.com/pentestpartners/PTP-RAT/blob/master/RAT.zip

Video demo

The following is a demo of the Rat in action. The remote host is a Virtual Machine hosted in Paris, and the receiver is a Microsoft Surface located in Scotland. The sent file, is a 1.8MB image of the Eiffel tower. This could easily be a large ntds.dit file or results from an on-host audit.