1 - 介绍 2 - Linux的keyboard驱动是如何工作的 3 - 基于内核的键盘纪录的原理 3.1 - 中断句柄 3.2 - 函数劫持 3.2.1 - 劫持handle_scancode 3.2.2 - 劫持put_queue 3.2.3 - 劫持receive_buf 3.2.4 - 劫持tty_read 3.2.5 - 劫持syserials_read/syserials_write 4 - vlogger 4.1 - 工作原理 4.2 - 功能及特点 4.3 - 如何使用 5 - 感谢 6 - 参考资料 7 - Keylogger源代码 --[ 1 - 介绍 本文分成两个部分。第一部分给出了linux键盘驱动的工作原理,并且讨论了建立一个基于 内核的键盘纪录器的方法。这部分内容对那些想写一个基于内核的键盘纪录器,或者写一个 自己键盘驱动的朋友会有帮助。 第二部分详细描述了vlogger的每个细节,vlogger是一个强大的基于内核的linux键盘纪录器, 以及如何来使用它。这向技术可以运用在蜜罐系统中,也可以做成一些很有意思的hacker game, 主要用来分析和采集hacker的攻击手法。我们都知道,一些大家熟知的键盘纪录器,如iob, uberkey,unixkeylogger等,它们是基于用户层的。这里介绍的是基于内核层的键盘纪录器。 最早期的基于内核的键盘纪录器是linspy,它发表在phrack杂志第50期。而现代的kkeylogger( 后面我们将用kkeylogger来表示基于内核的键盘纪录器)广泛采用的手法是中断syserials_read或者 syserials_write系统调用来对用户的击键进行记录。 显然,这种方法是很不稳定的并且会明显的降低系统的速度,因为我们中断的恰恰是系统使用最 频繁的两个系统调用syserials_read,syserials_write;syserials_read在每个进程需要读写设备的时候都会用到。 在vlogger里,我用了一个更好的方法,就是劫持tty buffer进程函数,下面会介绍到。 我假定读者熟悉linux的可加载模块的原理和运作过程,如果不熟悉,推荐大家首先阅读我以前写 过的linux kernel simple hacking,或者linux tty hijack,(在http://e4gle.org有下载), 参阅《linux驱动程序设计》来获得相关的理论基础知识。 --[ 2 - linux键盘驱动的工作原理 首先让我们通过以下的结构图来了解一下用户从终端的击键是如何工作的: _____________ _________ _________ / \ put_queue receive_buf tty_read /handle_scancode\-------->tty_queue---------->tty_ldisc-------> \ / buffer \_____________/ _________ _________ _________ ____________ syserials_read --->/dev/ttyX------->user process _________ ____________ Figure 1 首先,当你输入一个键盘值的时候,键盘将会发送相应的scancodes给键盘驱动。一个独立的 击键可以产生一个六个scancodes的队列。 键盘驱动中的handle_scancode()函数解析scancodes流并通过kdb_translate()函数里的 转换表(translation-table)将击键事件和键的释放事件(key release events)转换成连 续的keycode。 比如,'a'的keycode是30。击键’a'的时候便会产生keycode 30。释放a键的时候会产生 keycode 158(128+30)。 然后,这些keycode通过对keymap的查询被转换成相应key符号。这步是一个相当 复杂的过程。 以上操作之后,获得的字符被送入raw tty队列--tty_flip_buffer。 receive_buf()函数周期性的从tty_flip_buffer中获得字符,然后把这些字符送入 tty read队列。 当用户进程需要得到用户的输入的时候,它会在进程的标准输入(stdin)调用read()函数。 syserials_read()函数调用定义在相应的tty设备(如/dev/tty0)的file_operations结构 中指向tty_read的read()函数来读取字符并且返回给用户进程。 /*e4gle add file_operations是文件操作结构,定义了文件操作行为的成员,结构如下,很容易理解: strUCt file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *);
(出处:http://www.sheup.com)
上一页 [1] [2]