April 2001

Reviewing your X Window security

by Boris Loza

Operating System: Solaris

You can impress your boss by showing him how easy it is to view somebody's X session. In order to do this, you only need the native X Window utilities that come with the standard Solaris distribution.

Start by identifying your target machine. Let's suppose you want to check to see whether any user on a machine named unixbox has an unprotected X terminal. Type the following:

$ /usr/openwin/bin/xlsclients -display unixbox:0
The xlsclients utility lists information about the client applications running on a specified display unixbox:0. Note that you don't have to be the root user. After trying different boxes, you finally find something like this on an hrunix box that belongs to Human Resources. So let's see what sessions we can view on the hrunix box:
$ /usr/openwin/bin/xlsclients -display hrunix:0
hrunix     Terminal –session dtrWaOSn -sdtserver
hrunix     /bin/sh /applications/program/soffice
hrunix     /bin/sh /applications/program/soffice
hrunix     dtfile -noview
hrunix     /usr/dt/bin/dtmail
hrunix     /bin/sh /applications/program/soffice
This means that hrunix runs unprotected X sessions. We can tell from this output that hrunix runs xterm, mail, and some Star Office applications.

Our next step is to dump an image of the X Window system window discovered on this box. We'll use xwd, which is an X Window system dumping utility:

$ /usr/openwin/bin/xwd -display hrunix:0
=> -root -out /tmp/Xf
The xwd utility allows X users to store window images in a specially formatted dump file. This file can then be read by various X utilities for redisplay, printing, editing, formatting, archiving, image processing, etc. We're using the -root option, which indicates that the root window should be selected for the window dump.

Next we're going to use xwud, an X Window System image redisplaying the utility. Because the /tmp/Xf file has been specified as an output file for the xwd utility, we type the following:

$ /usr/openwin/bin/xwud -in /tmp/Xf
There you have it. As you can see in Figure A, you now see exactly what was on the hrunix machine.

Figure A: After running xwud, we can display an unprotected X Window session from the human resources computer.
[ Figure A ]

Wow, it looks like we're just in time! You can run a small application xkey from your Linux laptop. Just type the following:

$ xkey hrunix:0
You'll be able to see all keystrokes that are typed by the user of this X terminal.

Now, since you've seen how easy is to get somebody's unprotected X Window session, let's discuss how to prevent this.

Xhost authentication

The most widely used mechanism for X security is maintained via the xhost command. Think of xhost as an access control list containing all hosts that are allowed to access the X server. By typing xhost by itself, you'll see whether X clients are allowed to connect, and from which hosts the connection can come:
$ /usr/openwin/bin/xhost
access control enabled, only authorized 
=>clients can connect
pine.tree.com
This means that only X Window clients from pine.tree.com are authorized to connect to your X server. To disable access control, type:
$ /usr/openwin/bin/xhost +
access control disabled, clients can 
=>connect from any host
This shows the X server is opened to the world. To reset access control, type:
$ /usr/openwin/bin/xhost -
access control enabled, only authorized 
=>clients can connect
With the default setting established to deny access to every other machine, you can add a specific host to the list of machines that are permitted access:
$ /usr/openwin/bin/xhost +oak
oak being added to access control list
This code establishes that any user on the oak computer can connect to your X server. To remove the oak machine from the list of remote computers that are allowed to connect, type:
$ /usr/openwin/bin/xhost -oak
oak being removed from access control list
Be aware that if a client has already connected to your X Window server, removing that client host from your xhost list won't terminate the connection. The change simply prevents future access from that host.

You can also add or remove from the access list specific users associated with specific computers. If you wish to allow only user david from the oak machine to connect to your X Window server, type:

$ /usr/openwin/bin/xhost +oak@david
This adds the user david from oak to your access list. To disallow access, replace the plus sign (+) with a hyphen (-).

The xhost access control mechanism is certainly easy to use. A single program with a simple syntax is required. But host names (and usernames on these hosts) can be spoofed. This is bad if you're on an untrusted network like the Internet. So, let's look at a better X Window security solution.

Magic cookies

You can control user access to the X server through the use of a magic cookie. This security solution doesn't suffer from spoofed addresses as xhost does. Magic cookies authentication requires the account on the remote machine to know a secret key for your display. If the remote user knows this key, he can have complete access to the local display.

If you're using X Display Manager (xdm), the magic cookies are already created for you, even if you don't know about them. They're updated each time you log on. The command you'll use to deal with this authentication scheme is xauth. Enter the following commands to see if you already have some magic cookies:

oak $ /usr/openwin/bin/xauth list
oak.tree.com:0  MIT-MAGIC-COOKIE-1  
=>028dc02e3602cb40d2b0
oak/unix:0  MIT-MAGIC-COOKIE-1  
=>08b60039460d2c008d82
Let's go over the output from the xauth command in detail. It maintains the file .Xauthority in your home directory (unless you specify a different file). The first line specifies the INET Inter Process Communication domain, which is used for remote communication. You can see from the output that a workstation oak.tree.com can allow remote X clients (who know a secret key, of course!) to connect to display oak.tree.com:0, where a display is defined as a set of screens that share a common keyboard and mouse. MIT-MAGIC-COOKIE-1 is the authentication scheme we use here. The last large hex number is randomly generated, and actually is a key that we assume nobody knows except the authorized X clients.

The only difference between the first and last lines is that the latter describes the UNIX Inter Process Communication domain (/unix in oak/unix:0 indicates this) that's used for local X client-server communications only (on the same machine).

Using xauth, you can add and remove hosts from your authorized clients' list. We'll show you how this method works. Assume you want to run an X client on the pine.tree.com machine while displaying its output on the X server on oak.tree.com. On oak, you type:

oak $ /usr/openwin/bin/xauth list
oak.tree.com:0  MIT-MAGIC-COOKIE-1  
=>028dc02e3602cb40d2b0
oak/unix:0  MIT-MAGIC-COOKIE-1
=>08b60039460d2c008d82
You need only be concerned with the first line (INET domain). On pine.tree.com, you type:
pine $ /usr/openwin/bin/xauth
Using authority file /.Xauthority
xauth>
After you get the xauth command line prompt, copy and paste the first line from the output on oak and press [Enter]. Save the changes you've made and exit with the following:
xauth> add oak.tree.com:0  
=>MIT-MAGIC-COOKIE-1  028dc02e3602cb40d2b0
xauth> exit                        
Writing authority file /.Xauthority
You've added the oak.tree.com magic cookie into pine's .Xauthority file. Now pine.tree.com is authorized to communicate with oak's X server.

You can do the same trick with rsh. On pine, set up the ~/.rhost file in the user home directory. This file should contain the following entry:

oak.tree.com
Transfer the cookie to the remote machine pine.tree.com:
oak $ export DISPLAY=`hostname`:0
oak $ xauth nextract - $DISPLAY | 
=>rsh pine nmerge -
This command uses numeric extract and numeric merge options of the xauth utility. For more information about these options, consult the xauth man pages.

Now you're able to run X programs remotely. To test this, try to run any X application, such as follows:

oak $ rsh pine xterm -display $DISPLAY
The xterm terminal from pine.tree.com should be running on oak.tree.com.

In the beginning of this section, we assumed that you already have magic cookies in the .Xauthority file. If you don't, or if this file is empty, you need to create your own magic cookies. Here's an example using the Korn shell:

export randomkey=$(printf %4.5x
=>$(( $RANDOM * $RANDOM *2 )))
xauth add `hostname`:0 . $randomkey
xauth add `hostname`/unix:0 . $randomkey
You can also generate magic cookies using Perl:
export randomkey=`perl -e 'for (1..4) 
=>{srand(time+$$+$seed); 
=>printf("%4.5x", ($seed = 
=>int(rand(65536))));}'`
Make .Xauthority readable/writable by the owner only (use the command chmod 600 .Xauthority). Also, MIT-MAGIC-COOKIE-1 is more secure than the xhosts authentication mechanism, which transfers your magic cookies to the X Window server in clear text. If another person can get your magic cookie, the security is broken. That's why this method isn't preferred in untrusted network environments.

Secure RPC authentication

Instead of storing sensitive data in the .Xauthority file, the Secure Remote Procedure Call (RPC) system relies on its own proven mechanism for storing sensitive information. This provides an extra level of security for your X Window applications.

Using Secure RPC, the X server can check whether the clients really are who they claim to be. You achieve this task by implementing a credential validation mechanism. Solaris can be configured to use so-called DES verifiers to provide X server authentication. The DES authentication mechanism uses private and public keys to encrypt transactions and a random key (called the conversation key) to perform client authentication.

After performing a Secure RPC setup, every user on your Solaris system will have a network name and a public and private key. The key information can be stored in the /etc/publickey file, in the publickey NIS table, or, when using the NIS+ system, in the cred.org_dir table. In each of these cases, the information stored for every network name will consist of the public key and an encrypted version of the secret key (encrypted with the login password of the user). When the user logs on, his secret key will be decrypted using his login password, and will be kept available by the keyserv daemon process.

Configuring Secure RPC for Solaris is beyond the scope of this article. However, we'll show you how to configure your X Server to work with this authentication mechanism.

For all of the authentication systems we've described so far you only need one of the two X control utilities (xhost or xauth), but with Secure RPC you'll need both. Use xhost to control who can manipulate the authentication data within your X server. Further, you need to use xauth to change or view the authentication data to be presented by client applications when they want to connect to your X server (the data stored in your .Xauthority file).

After you configure your Solaris system to work with Secure RPC, you need to start your X environment using SUN-DES-1 instead of the MIT-MAGIC-COOKIE-1 authentication scheme. Add the following entry into the /usr/lib/X11/xdm file:

DisplayManager._0.authName:     SUN-DES-1
This instructs xdm to use the SUN-DES-1 authentication. Delete the ~/.Xauthority file and add the new authentication data for your local server with the following code:
oak $  rm .Xauthority
oak $  xauth add `hostname`/unix:0
 => SUN-DES-1   $LOGNAME@
oak $  xauth add `hostname`:0   
=>SUN-DES-1     $LOGNAME@
oak $  xauth list
oak/unix:0  SUN-DES-1  david@   
oak.tree.com:0  SUN-DES-1  david@
Note that you don't have to generate a random key. Now start the X server with the command xinit -- -auth \ ~/.Xauthority and add yourself to be authorized to connect to the X server with this:
oak $  xhost +david@
Now you must add a remote client into the authentication database. Use the following command:
oak $   xauth add pine:0   SUN-DES-1    $LOGNAME@
Don't forget to instruct the remote server to use Secure RPC as well. After all these preparations, you should be all set.

Conclusion

In this article we've shown you how insecure X communication can be and what to do in order to provide safe X client-server communication. Depending on the level of security you need to implement, use xhost, xauth or Secure RPC X authentication methods. But no matter what, make sure you implement some form of security. Protect your own X server!