Post

VNC Honeypot Setup

The Setup

I decided to setup a VNC honeypot. My goal was to essentially spin up an Ubuntu server and configure it in such a way, where when someone connected, it would start a recording of the active VNC session, and once disconnected, would save that recording into a file which i could retrieve at a later date.

The overall setup was relatively simple. I started with a fresh Ubuntu installation and updated/installed the necessary components:

1
2
3
4
5
apt update
apt upgrade
apt install tigervnc-standalone-server tigervnc-common
apt install xfce4 xfce4-goodies -y
apt install ffmpeg

I had 2 users configured on the Ubuntu server. The first was called Fred. This is the user which runs the VNC command, and ultimately who the attacker will be logging into the server with using VNC. The second user was called John, the recordings are stored in this users home directory, tucked away from Freds home directory where they cold potentially get deleted.

I then created a directory where i wanted the recordings to be stored This was done as the John user in /home/john/files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
john@ubuntu-s-1vcpu-1gb-lon1-01:~$ mkdir files
john@ubuntu-s-1vcpu-1gb-lon1-01:~$ ls -la  
total 44  
drwxr-x--x 4 john john 4096 May 21 06:44 .  
drwxr-xr-x 4 root root 4096 Apr 21 12:50 ..  
-rw------- 1 john root  120 Apr 21 13:55 .Xauthority  
-rw------- 1 john john 1940 Apr 21 14:00 .bash_history  
-rw-r--r-- 1 john john  220 Apr 21 12:50 .bash_logout  
-rw-r--r-- 1 john john 3771 Apr 21 12:50 .bashrc  
-rw-r--r-- 1 john john    0 Apr 21 12:50 .cloud-locale-test.skip  
-rw-r--r-- 1 john john 5290 Apr 21 12:50 .face  
lrwxrwxrwx 1 john john    5 Apr 21 12:50 .face.icon -> .face  
-rw-r--r-- 1 john john  807 Apr 21 12:50 .profile  
drwxr-xr-x 2 john john 4096 Apr 21 13:50 .vnc  
drwxrwxr-x 2 john john 4096 May 21 06:44 files

Then i set the permissions for the directory.

1
sudo chmod 730 /home/john/files

This sets: 7 (owner = root): full access 3 (group = john): write + execute (but no read, so can’t list files) 0 (others): no access

Then added fred to johns group:

1
2
3
4
root@ubuntu-s-1vcpu-1gb-lon1-01:/home/john# sudo usermod -aG john fred  
root@ubuntu-s-1vcpu-1gb-lon1-01:/home/john# su fred  
fred@ubuntu-s-1vcpu-1gb-lon1-01:/home/john$ id  
uid=1000(fred) gid=1000(fred) groups=1000(fred),100(users),1001(john)

This creates a place to hide away the recordings so they cant be seen when an attacker logs in. It doesn’t protect them fully, as technically the Fred user can still delete the files in this directory if they guess the filename. However, Fred is not able to list the /home/john/files directory contents. So it puts up more of a challenge. For the purpose of throwing together a quick VNC honeypot, this suffices.

I then created a bash script to start the server and recordings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/bash

LOGFILE="/home/fred/.vnc/ubuntu-s-1vcpu-1gb-lon1-01:1.log"
CONNECT_PATTERN="Connections: accepted:"
DISCONNECT_PATTERN="VNCSConnST:  closing"
PIDFILE="/tmp/vnc_ffmpeg_pid.txt"

# Clear previous log
cat /dev/null > "$LOGFILE"

# Start VNC server
vncserver --I-KNOW-THIS-IS-INSECURE -localhost no -geometry 1024x768 -depth 32 -SecurityTypes None

# Monitor log for VNC connection/disconnection events
tail -F "$LOGFILE" | while read -r line; do
	if echo "$line" | grep -q "$CONNECT_PATTERN"; then
		echo "$(date): VNC client connected, starting ffmpeg"

		# Extract IP address
		IP=$(echo "$line" | awk '{print $3}' | cut -d':' -f1)

		# Sanitize IP for use in filenames
		SAFE_IP=$(echo "$IP" | tr -cd '[:alnum:]._-')

		# Generate output filename
		FILENAME="/home/john/files/$(date +'%d-%m-%Y-%H-%M-%S')-${SAFE_IP}.mp4"

		# Start ffmpeg and save PID
		ffmpeg -f x11grab -video_size 1024x768 -framerate 30 -i :1.0 -c:v libx264 -preset ultrafast -crf 23 "$FILENAME" &

		# Send IP in ntfy notification
		curl -d "Connection to VNC server from IP $SAFE_IP" ntfy.sh/xxxxxxxxxxx

		# Save ffmpeg PID
		echo $! > "$PIDFILE"

	elif echo "$line" | grep -q "$DISCONNECT_PATTERN"; then
		echo "$(date): VNC client disconnected, stopping ffmpeg"

		if [ -f "$PIDFILE" ]; then
			PID=$(cat "$PIDFILE")
			if ps -p $PID > /dev/null; then
				kill $PID
				echo "ffmpeg process $PID killed"
			fi
			rm -f "$PIDFILE"
		fi
	fi
done

This script starts the VNC server on port 5901, with a resolution of 1024x768, and requires no password. It then monitors the VNC log file.

If the string “Connections: accepted” appears in the file, this means someone has connected to the VNC server. A recording is started with ffmpeg and the file saved with the IP address, time and date in the filename.

Once the string “VNCSConnST: closing” appeared in the VNC log file, this means the VNC connection disconnected, and the recording was then saved.

I also have a curl command run on each connection which sends the IP address to a ntfy.sh service. This notified me on my phone when someone connected, and allowed me to stop the server if it became a bot in a botnet for example. I eventually plan on using my cloud providers snapshot service to revert the machine after each connection to a clean state, i however did not get this fully working, so the manual intervention was required.

This script was made to run as a service, so it would start on startup. I created the following file:

1
/etc/systemd/system/vnc-record.service

With the following contents:

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]  
Description=Poll Service VNC  
After=network.target  
  
[Service]  
Type=simple  
User=fred  
ExecStart=/bin/bash /home/john/poll.sh  
Restart=on-failure  
  
[Install]  
WantedBy=multi-user.target

Made it executable:

1
chmod 644 /etc/systemd/system/vnc-record.service

Reload systemd:

1
2
sudo systemctl daemon-reexec
sudo systemctl daemon-reload

Enable the service:

1
systemctl enable vnc-record.service

Then manually start it:

1
systemctl start vnc-record.service

The ubuntu server was then all ready to accept VNC connections and make recordings.

The Result

I left the VNC honeypot online for 1 week. On average there were around 30 connections each day. Almost all of these were bots connecting for around 5 seconds before disconnecting. No cursor movements or typing. Then there were 4 connections in which someone connected and interacted with the VNC session. In all cases this consisted of them running commands like nproc and top to identify system resources and running services. In 2 cases, they downloaded and execute scripts which connected the device to a botnet. A recording of the interaction can be seen below:

Overall it was quite a fun project. I intend in the future to try the same again with a Windows server and RDP. Be sure to check back for more details sorrounding that. Feel free to email me at j@meswoolley.co.uk if you want to ask any questions, or contact me on twitter @xtrato.

This post is licensed under CC BY 4.0 by the author.