275 lines
13 KiB
Plaintext
275 lines
13 KiB
Plaintext
|
|
Subject: X Security - A Crash Course by runeb@stud.cs.uit.no
|
|
|
|
Crash Course in X Windows Security
|
|
|
|
1. Motivation / introduction
|
|
2. How open X displays are found
|
|
3. The local-host problem
|
|
4. Snooping techniques - dumping windows
|
|
5. Snooping techniques - reading keyboard
|
|
6. Xterm - secure keyboard option
|
|
7. Trojan X programs [xlock and xdm]
|
|
8. X Security tools - xauth MIT-MAGIC-COOKIE
|
|
9. Concluding remarks
|
|
|
|
1. Motivation / introduction
|
|
|
|
X windows pose a security risk. Through a network, anyone can connect to
|
|
an open X display, read the keyboard, dump the screen and windows and
|
|
start applications on the unprotected display. Even if this is a known
|
|
fact throughout the computer security world, few attempts on informing
|
|
the user community of the security risks involved have been made. This
|
|
article deals with some of the aspects of X windows security. It is in no
|
|
sense a complete guide to the subject, but rather an introduction to a
|
|
not-so-known field of computer security. Knowledge of the basics of the X
|
|
windows system is necessary, I haven't bothered including an introductory
|
|
section to explain the fundamentals. I wrote some code during the
|
|
research for this article, but none of it is included herein. If the
|
|
lingual flow of English seem mayhap strange and erroneous from byte to
|
|
byte, this is due to the fact that I'm Scandinavian. Bare with it. :)
|
|
|
|
2. How open X displays are found
|
|
|
|
An open X display is in formal terms an X server that has its access
|
|
control disabled. Disabling access control is normally done with the
|
|
xhost command.
|
|
|
|
$ xhost +
|
|
|
|
allows connections from any host. A single host can be allowed connection
|
|
with the command
|
|
|
|
$ xhost + ZZZ.ZZZ.ZZZ.ZZZ
|
|
|
|
where Z is the IP address or host-name. Access control can be enabled by
|
|
issuing an
|
|
|
|
$ xhost -
|
|
|
|
command. In this case no host but the local-host can connect to the
|
|
display. Period. It is as simple as that - if the display runs in 'xhost
|
|
-' state, you are safe from programs that scans and attaches to
|
|
unprotected X displays. You can check the access control of your display
|
|
by simply typing xhost from a shell. Sadly enough, most sites run their X
|
|
displays with access control disabled as default. They are therefore easy
|
|
prey for the various scanner programs circulating on the net.
|
|
|
|
Anyone with a bit of knowledge about Xlib and sockets programming can
|
|
write an X scanner in a couple of hours. The task is normally
|
|
accomplished by probing the port that is reserved for X windows, number
|
|
6000. If anything is alive at that port, the scanner calls
|
|
XOpenDisplay("IP-ADDRESS:0.0") that will return a pointer to the display
|
|
structure, if and only if the target display has its access control
|
|
disabled. If access control is enabled, XOpenDisplay returns 0 and
|
|
reports that the display could not be opened.
|
|
|
|
E.g:
|
|
|
|
Xlib: connection to "display:0.0" refused by server
|
|
Xlib: Client is not authorized to connect to Server
|
|
|
|
The probing of port 6000 is necessary because of the fact that calling
|
|
XOpenDisplay() on a host that runs no X server will simply hang the
|
|
calling process. So much for unix programming conventions. :)
|
|
|
|
I wrote a program called xscan that could scan an entire subnet or scan
|
|
the entries in /etc/hosts for open X displays. My remark about most sites
|
|
running X displays with access control disabled, originates from running
|
|
xscan towards several sites on the internet.
|
|
|
|
3. The localhost problem
|
|
|
|
Running your display with access control enabled by using 'xhost -' will
|
|
guard you from XOpenDisplay attempts through port number 6000. But there
|
|
is one way an eavesdropper can bypass this protection. If he can log into
|
|
your host, he can connect to the display of the localhost. The trick is
|
|
fairly simple. By issuing these few lines, dumping the screen of the host
|
|
'target' is accomplished:
|
|
|
|
$ rlogin target
|
|
$ xwd -root -display localhost:0.0 > ~/snarfed.xwd
|
|
$ exit
|
|
$ xwud -in ~/snarfed.xwd
|
|
|
|
And voila, we have a screendump of the root window of the X server
|
|
target.
|
|
|
|
Of course, an intruder must have an account on your system and be able to
|
|
log into the host where the specific X server runs. On sites with a lot
|
|
of X terminals, this means that no X display is safe from those with
|
|
access. If you can run a process on a host, you can connect to (any of)
|
|
its X displays.
|
|
|
|
Every Xlib routine has the Display structure as it's first argument. By
|
|
successfully opening a display, you can manipulate it with every Xlib
|
|
call available. For an intruder, the most 'important' ways of
|
|
manipulating is grabbing windows and keystrokes.
|
|
|
|
4. Snooping techniques - dumping windows
|
|
|
|
The most natural way of snarfing a window from an X server is by using
|
|
the X11R5 utility xwd or X Window System dumping utility. To get a grip
|
|
of the program, here's a small excerpt from the man page
|
|
|
|
DESCRIPTION
|
|
Xwd is an X Window System window dumping utility. Xwd allows Xusers
|
|
to store window images in a specially formatted dump file. This file
|
|
can then be read by various other X utilities for redisplay, printing,
|
|
editing, formatting, archiving, image processing, etc. The target
|
|
window is selected by clicking the pointer in the desired window. The
|
|
keyboard bell is rung once at the beginning of the dump and twice when
|
|
the dump is completed.
|
|
|
|
Shortly, xwd is a tool for dumping X windows into a format readable by
|
|
another program, xwud. To keep the trend, here's an excerpt from the man
|
|
page of xwud:
|
|
|
|
|
|
DESCRIPTION
|
|
Xwud is an X Window System image undumping utility. Xwud allows X
|
|
users to display in a window an image saved in a specially formatted
|
|
dump file, such as produced by xwd(1).
|
|
|
|
I will not go in detail of how to use these programs, as they are both
|
|
self-explanatory and easy to use. Both the entire root window, a
|
|
specified window (by name) can be dumped, or a specified screen. As a
|
|
'security measure' xwd will beep the terminal it is dumping from, once
|
|
when xwd is started, and once when it is finished (regardless of the xset
|
|
b off command). But with the source code available, it is a matter of
|
|
small modification to compile a version of xwd that doesn't beep or
|
|
otherwise identifies itself - on the process list e.g. If we wanted to
|
|
dump the root window or any other window from a host, we could simply
|
|
pick a window from the process list, which often gives away the name of
|
|
the window through the -name flag. As before mentioned, to dump the
|
|
entire screen from a host:
|
|
|
|
$ xwd -root localhost:0.0 > file
|
|
|
|
the output can be directed to a file, and read with
|
|
|
|
$ xwud -in file
|
|
|
|
or just piped straight to the xwud command.
|
|
|
|
Xterm windows are a different thing. You can not specify the name of an
|
|
xterm and then dump it. They are somehow blocked towards the X_Getimage
|
|
primitive used by xwd, so the following
|
|
|
|
$ xwd -name xterm
|
|
|
|
will result in an error. However, the entire root window (with Xterms and
|
|
all) can still be dumped and watched by xwud. Some protection.
|
|
|
|
|
|
5. Snooping techniques - reading keyboard
|
|
|
|
If you can connect to a display, you can also log and store every
|
|
keystroke that passes through the X server. A program circulating the
|
|
net, called xkey, does this trick. A kind of higher-level version of the
|
|
infamous ttysnoop.c. I wrote my own, who could read the keystrokes of a
|
|
specific window ID (not just every keystroke, as my version of xkey).
|
|
The window ID's of a specific root-window, can be acquired with a call to
|
|
XQueryTree(), that will return the XWindowAttributes of every window
|
|
present. The window manager must be able to control every window-ID and
|
|
what keys are pressed down at what time. By use of the window-manager
|
|
functions of Xlib, KeyPress events can be captured, and KeySyms can be
|
|
turned into characters by continuous calls to XLookupString.
|
|
|
|
You can even send KeySym's to a Window. An intruder may therefore not
|
|
only snoop on your activity, he can also send keyboard events to
|
|
processes, like they were typed on the keyboard. Reading/writing
|
|
keyboard events to an xterm window opens new horizons in process
|
|
manipulation from remote. Luckily, xterm has good protection techniques
|
|
for prohibiting access to the keyboard events.
|
|
|
|
|
|
6. Xterm - Secure keyboard option
|
|
|
|
A lot of passwords is typed in an xterm window. It is therefore crucial
|
|
that the user has full control over which processes can read and write to
|
|
an xterm. The permission for the X server to send events to an Xterm
|
|
window, is set at compile time. The default is false, meaning that all
|
|
SendEvent requests from the X server to an xterm window is discarded. You
|
|
can overwrite the compile-time setting with a standard resource
|
|
definition in the .Xdefaults file:
|
|
|
|
xterm*allowSendEvents True
|
|
|
|
or by selecting Allow Sendevents on the Xterm Main Options
|
|
menu. (Accessed by pressing CTRL and the left mouse button But this is
|
|
_not_ recommended. Neither by me, nor the man page. ;) Read access is a
|
|
different thing.
|
|
|
|
Xterms mechanism for hindering other X clients to read the keyboard
|
|
during entering of sensitive data, passwords etc. is by using the
|
|
XGrabKeyboard() call. Only one process can grab the keyboard at any one
|
|
time. To activate the Secure Keyboard option, choose the Main Options
|
|
menu in your Xterm window (CTRL+Left mouse button) and select Secure
|
|
Keyboard. If the colors of your xterm window inverts, the keyboard is
|
|
now Grabbed, and no other X client can read the KeySyms.
|
|
|
|
The versions of Xterm X11R5 without patch26 also contain a rather nasty
|
|
and very well known security hole that enables any user to become root
|
|
through clever use of symbolic links to the password file. The Xterm
|
|
process need to be setuid for this hole to be exploitable. Refer to the
|
|
Cert Advisory: CA-93:17.xterm.logging.vulnerability.
|
|
|
|
|
|
7. Trojan X clients - xlock and X based logins
|
|
|
|
Can you think of a more suitable program for installing a
|
|
password-grabbing trojan horse than xlock? I myself cannot. With a few
|
|
lines added to the getPassword routine in xlock.c, the password of every
|
|
user using the trojan version of xlock can be stashed away in a file for
|
|
later use by an intruder. The changes are so minimal, only a couple of
|
|
bytes will tell the real version from the trojan version.
|
|
|
|
If a user has a writable homedir and a ./ in her PATH environment
|
|
variable, she is vulnerable to this kind of attack. Getting the password
|
|
is achieved by placing a trojan version of Xlock in the users homedir and
|
|
waiting for an invocation. The functionality of the original Xlock is
|
|
contained in the trojan version. The trojan version can even tidy up and
|
|
destroy itself after one succesfull attempt, and the user will not know
|
|
that his password has been captured.
|
|
|
|
Xlock, like every password-prompting program, should be regarded with
|
|
suspicion if it shows up in places it should not be, like in your own
|
|
homedir.
|
|
|
|
Spoofed X based logins however are a bit more tricky for the intruder to
|
|
accomplish. He must simulate the login screen of the login program ran
|
|
by XDM. The only way to ensure that you get the proper XDM login program
|
|
(if you want to be really paranoid) is to restart the X-terminal,
|
|
whatever key combination that will be for the terminal in question.
|
|
|
|
8. X Security tools - xauth MIT-MAGIC-COOKIE
|
|
|
|
To avoid unathorized connections to your X display, the command xauth for
|
|
encrypted X connections is widely used. When you login, xdm creates a
|
|
file .Xauthority in your homedir. This file is binary, and readable only
|
|
through the xauth command. If you issue the command
|
|
|
|
$ xauth list
|
|
|
|
you will get an output of:
|
|
|
|
your.display.ip:0 MIT-MAGIC-COOKIE-1 73773549724b76682f726d42544a684a
|
|
|
|
display name authorization type key
|
|
|
|
The .Xauthority file sometimes contains information from older sessions,
|
|
but this is not important, as a new key is created at every login
|
|
session. To access a display with xauth active - you must have the
|
|
current access key.
|
|
|
|
If you want to open your display for connections from a particular user,
|
|
you must inform him of your key. He must then issue the command
|
|
|
|
$ xauth add your.display.ip:0 MIT-MAGIC-COOKIE-1 73773549724b7668etc.
|
|
|
|
Now, only that user (including yourself) can connect to your display.
|
|
Xauthority is simple and powerful, and eliminates many of the security
|
|
problems with X.
|
|
|