suterusu是一款跨多个Linux平台的rootkit,打入目标系统后能够完成文件隐藏、进程隐藏、端口隐藏、目录隐藏、文件下载、控制系统读写、远程交互等功能,是初学rootkit的必看材料,附上作者对suterusu的分析blog
除去主模块之外,还可以选择性编译6个扩展模块
keylogger
unlock 锁屏,必须输入指定密码
logfile 键盘记录到指定文件
hookrw 钩住系统读写
dlexec 事件驱动下载or执行二进制
icmp 监控含有特殊字节的icmp
目录结构 1 2 3 4 5 6 7 8 9 10 11 ├── common.h # 宏、函数声明 ├── dlexec.c # 维护下载任务队列 ├── hookrw.c # hook到系统读写 ├── icmp.c # icmp队列处理 ├── keylogger.c # 键盘记录 or 锁屏 ├── keylog.h # 键盘宏 ├── main.c # mod主逻辑 ├── module.c # 阻止后续模块加入 ├── serve.c # tcp server,让受害机通过dlexec下载我们的恶意文件 ├── sock.c # 命令通道,和rootkit交互 └── util.c # hook函数实现(根基)
util 主要功能:
定义了系统函数hook结构体,以链表的形式保存
定义了四个hook操作函数
start:hook对应函数,保存至hook结构体
pause:暂时归还hook,即归还原函数
resume:重新hook,即再用我们的新函数替换系统函数
stop:删除当前hook函数,归还原函数
开启/关闭写保护操作(在四个hook操作函数中用到)
查找当前函数地址(配合main中查询到的symbol_table使用)
data_struct 1 2 3 4 5 6 struct sym_hook { void *addr; unsigned char o_code[HIJACK_SIZE]; unsigned char n_code[HIJACK_SIZE]; struct list_head list ; };
api 1 2 3 4 5 6 7 8 9 write_cr0(unsigned long ) read_cr0() barrier() preempt_enable()void list_add ( struct list_head * new , struct list_head * head) ;void list_del (struct list_head * entry) ;int kallsyms_on_each_symbol (int (*fn)(void *, const char *, struct module *, unsigned long ), void *data)
module 主要功能:函数挂入消息通知队列,当有新模块打入时,将新模块的init和exit函数替换为我们的空函数,达到防止后续模块加入的效果
data_struct
api 1 2 3 4 5 6 7 8 9 10 11 register_module_notifier(struct notifier_block *) unregister_module_notifier(struct notifier_block *) 宏DEFINE_SPINLOCK,定义并初始化spinlock 用法:DEFINE_SPINLOCK(TEST); spin_lock_irqsave 用法:spin_lock_irqsave(&TEST, flags<long int >); spin_unlock_irqrestore 用法:spin_unlock_irqrestore(&TEST, flags<long int >);
内核通知链
Notifier链分析和使用
dlexec 主要功能:维护全局工作队列,将文件下载任务添入队列,文件下载后将文件权限改为777,配合icmp模块使用
data_struct
workqueue_struct 工作队列结构体
work_struct 工作结构体
mm_segment_t
此处主要配合get_fs()
,set_fs(mm_segment_t)
,get_ds()
,内核以此来对用户空间的文件进行操作
iovec 即io vector,struct iovec定义了一个向量元素。通常,这个结构用作一个多元素的数组。对于每一个传输的元素,指针成员iov_base指向一个缓冲区,这个缓冲区是存放的是readv所接收的数据或是writev将要发送的数据。成员iov_len在各种情况下分别确定了接收的最大长度以及实际写入的长度。
msghdr
api 1 2 3 4 5 6 7 8 9 10 create_workqueue() flush_workqueue() destroy_workqueue() queue_work() sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, struct sock **) inet_stream_connect(struct sock *, struct sockaddr *, int addr_len, int flags) sock_recvmsg(struct sock *, struct msghdr *, size_t , int flags) inet_release(struct sock *)
keylogger 主要功能:锁屏和记录按键
这里的密码很有趣,音量升键 上箭头 上箭头 音量降键 ??键 ??键
x 2
data_struct 1 2 3 task_struct keyboard_notifier_paramloff_t
api 1 2 3 4 5 6 7 8 9 10 11 12 register_keyboard_notifier(struct notifier_block *) unregister_keyboard_notifier(struct notifier_block *) 宏DECLARE_WAIT_QUEUE_HEAD wait_event_interruptible () wake_up_interruptible () vfs_write kthread_run kthread_should_stop kthread_stop
sock 主要功能:通过ioctl和mod进行交互,选择不同的接口,传入对应的参数
data_struct
api 1 int ioctl (int fd, unsigned long request, ...) ;
icmp 主要功能:通过netfilter判断操作系统接收到的icmp报文,若icmp报文的magic字段同内置相符,则调用dlexec将对应ip和port挂入下载队列,完成文件传输和执行
data_struct http://staff.ustc.edu.cn/~james/linux/netfilter-4.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 netfilter的钩子操作结构体struct nf_hook_ops { struct list_head list ; nf_hookfn *hook; struct module *owner ; int pf; int hooknum; int priority; }; 上面的nf_hookfn函数参数如下unsigned int watch_icmp ( unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) )
api 1 2 nf_register_hook nf_unregister_hook