书写基于内核的linux键盘纪录器(p9-0e)

2008-04-09 04:00:06来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折


书写基于内核的linux键盘纪录器(p9-0e)

整理:e4gle(大鹰)

来源:http://www.whitecell.org

|=-----------------=[ Writing Linux Kernel Keylogger ]=------------------=|
|=-----------------------------------------------------------------------=|
|=------------------=[ rd <rd@thehackerschoice.com> ]=-------------------=|
|=------------------------=[ June 19th, 2002 ]=--------------------------=|
|=------------------=[ 整理:e4gle <e4gle@whitecell.org> from whitecell.org]=-------------------=|
|=------------------------=[ Aug 12th, 2002 ]=--------------------------=|


--[ Contents

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 - 劫持sys_read/sys_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来表示基于内核的键盘纪录器)广泛采用的手法是中断sys_read或者
sys_write系统调用来对用户的击键进行记录。
显然,这种方法是很不稳定的并且会明显的降低系统的速度,因为我们中断的恰恰是系统使用最
频繁的两个系统调用sys_read,sys_write;sys_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 |
\_____________/ |_________| |_________|

_________ ____________
| |sys_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()函数。
sys_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 *);<----这是本文提到的read函数
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:gcc常用的编译选项对代码的影响

下一篇:详解BMP网页木马