How to implement a "secure" keyboard logger :-) (somewhat long)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello ML,

I recently ported a keyboard logger [0] which is used by different so-called
screenreaders [1] (software with which blind people are able to access a
computer) to the Linux kernel 2.6.

This logger intercepts keycodes by providing a hook which gets called
from kbd_keycode() in drivers/char/keyboard.c and works as follows:

void kbd_keycode(unsigned int keycode, int down, int hw_raw,
		struct pt_regs *regs)
{
        int filter;
        [...]
        filter = kbd_sniff_hook(vc_kbd_led(kbd, VC_CAPSLOCK)
				? shift_state | SNIFF_CAPSLOCK : shift_state,
				keycode + (!down << 7));
        [...]
	if (!filter || type == KT_SHIFT)
		(*k_handler[type])(vc, keysym & 0xff, !down, regs);
        [...]
}

The kbd_sniff_hook() resides in drivers/char/vc_screen.c and looks
basically like this: 

/*
 * Intercept all keycodes, return 1 when keycode should not go 
 * to other drivers/applications, 0 otherwise.
 */
int kbd_sniff_hook(int shift_state, int keycode)
{
        if (keycode == keycode which enters the interception state) {
	        activate_logging();
	} else if (keycode == keycode which deactivates interception) {
	        deactivate_logging();
	}
	if (logging) {
		store_keycode_in_buffer();
	}
	return logging_state;  /* 0 == off, 1 == on */
}

The screenreader software then can register arbitrary keys for
triggering the logging.

The intercepted keycodes are provided through an ioctl interface which
sits on /dev/vcsa0 (from drivers/char/vc_screen.c)

vcs_ioctl(struct inode *inode, struct file *file,
          unsigned int cmd, unsigned long arg)
{
	int retval;

	if (current->euid != 0)
		return -EPERM;

	switch (cmd) {
	case SNIFF_GET_KEYCODE:
	[...]
}

Well, but what the heck is this logging useful for? ... :-)

These screenreaders are normally implemented as deamons which are sitting
in the background with no TTY attached to them, speaking the contents
of the TTY of the process which is attached to the foreground console's
TTY.

Now my question:

It's blatantly obvious, that this aproach is more than insecure, as
every root process can record keypresses when it just is in the mood for
doing so.

I'd wonder now, if some better approachs exist for implementing such a
facility? 

I mean, obvously this patch will never make it in the mainline kernel
as is for sure, but I would like to make it somewhat more "secure" anyway.

I'd like to implement some authentication for this interface, but I am
not at all sure about where to start or what models would be
appropriate for this task. 

Any suggestions will be gratefully appreciated.

Kai

[0] The full patch I am talking about:
    <URL:http://butenuth.onlinehome.de/blinux/sniff-patch-2.6.9.gz>
[1] An example for such an application:
    <URL:http://brass.sf.net>


--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/




[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux