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:
I left a server online with VNC wide open to see how it would be interacted with. This is one of the more interesting interactions: pic.twitter.com/VILOXrXTEj
— James Woolley (@Xtrato) June 6, 2025
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.