RDP Honeypots

Increase in public RDP hosts

In a recent post the SANS ISC warned of an increase in RDP Scanning. Although the initially reported number was adjusted downward later, there is still an increase in exposed RDP servers. It would be interesting to track the volume of RDP scans, and the credentials used in the scan. Let’s run an RDP honeypot.


One of these RDP honeypots is written by Sylvain Peyrefitte, RDPY. RDPY is more than just a RDP honeypot. It is a Python implementation of the Microsoft RDP protocol, built over the event driven network engine Twisted.

RDP Session

One of the first things you need to do, is record an RDP session (the login screen) which can then be used with the RDP honeypot. First have a Windows system where RDP is enabled and NLA (Network Level Authentication) is disabled, then create a MiTM attack and record the session (RSS files). This session is actually the ‘screen’ how visitors on the RDP connection are greeted. For my exercise, I used a Windows 7 system.

rdpy-rdpmitm.py -t -o rss_files

The target ( is the IP of the Windows system. Then connect to the RDP service, via the MiTM proxy.

xfreerdp --no-nla

When this is done, you can replay the recorded session, stored in an RSS file, with rdpy-rssplayer.py.

Start the RDP honeypot

The original implementation of rdpy-rdphoneypot.py did not contain timestamps and logging to a file. Also, the tracking of submitted credentials was on a multiline. I changed this via PR 108, which is now also included in the master branch. Running the honeypot is as simple as it gets by starting the rdpy-rdphoneypot.py command. I run it from screen and have the screen restarted daily.

screen -S rdphoneypot rdpy-rdphoneypot.py -L rdpy-rdphoneypot/rdp.log rdpy-rdphoneypot/win7.rss

This is how a succesfull logged connection looks like.

The options are self-explanatory.

  • -L the log path;
  • the recorded RDP session.

Other options available include

  • -l listen_port default 3389;
  • -k private_key_file_path (mandatory for SSL);
  • -c certificate_file_path (mandatory for SSL).

It took less than 20 minutes after the start of the RDP honeypot to see the first connections.


I store the logs from the different honeypots in Elastic. Below is the grok filter used for the RPD logs.

					if "Credentials" in [message] {
						grok {
							match => { "message" => "INFO:\t%{TIMESTAMP_ISO8601:timestamp} --- Credentials: domain: (?:%{SPACE}|%{WORD:rdp_domain}) username: (?:%{SPACE}|%{WORD:rdp_username}) password: (?:%{SPACE}|%{WORD:rdp_password}) hostname: %{WORD:rdp_hostname}"}
							remove_field => [ "message" ]
							add_field => { "rdp_type" => "credentials" }

					if "Connection" in [message] {
						grok {
							match => { "message" => "INFO:\t%{TIMESTAMP_ISO8601:timestamp} --- Connection from %{IPV4:src_ip}:%{POSINT:src_port}"}
							remove_field => [ "message" ]
							add_field => { "rdp_type" => "connection" }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.