简介
好久都没搞linux的kernel了,记录一下
Makefile
CONFIG_MODULE_SIG=n
obj-m += hook_test.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
CONFIG_MODULE_SIG=n
是针对module verification failed: signature and/or required key missing - tainting kernel
的最简单方法,或者直接进行签名
常用命令
- 插入模块
insmod
- 查看模块
lsmod
- 查看信息
dmesg
- 卸载模块
rmmod
- 载入模块
modprobe -a
对于printk
直接输出到termianl
dmesg -wH &
然后运行模块
对于指定等级的输出
dmesg -wH | grep ERR &
在内核源码中使用
printk(KERN_EMERG "ERROR!\n");
对于syscall的hook
#include<linux/init.h>
#include<linux/module.h>
#include<linux/moduleparam.h>
#include<linux/unistd.h>
#include<linux/sched.h>
#include<linux/syscalls.h>
#include<linux/string.h>
#include<linux/fs.h>
#include<linux/fdtable.h>
#include<linux/uaccess.h>
#include <linux/kallsyms.h>
#include<linux/rtc.h>
#include<linux/vmalloc.h>
#include <linux/slab.h>
//module macros
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("hook sys_mkdir");
//module constructor/destructor
typedef unsigned long (*sys_call_ptr_t)(void);
sys_call_ptr_t *_sys_call_table = NULL;
typedef asmlinkage long (*old_mkdir_t)(const char __user *pathname, umode_t mode);
old_mkdir_t old_mkdir = NULL;
// hooked mkdir function
asmlinkage long hooked_mkdir(const char __user *pathname, umode_t mode) {
printk("hooked sys_mkdir(), mkdir name: ");
printk(pathname);
old_mkdir(pathname, mode);
}
// memory protection shinanigans
unsigned int level;
pte_t *pte;
//obtain sys_call_table
static int get_sys_call_table(void){
unsigned long tmp_sys_call_table = 0;
int ans = 0;
tmp_sys_call_table = kallsyms_lookup_name("sys_call_table");
if(tmp_sys_call_table != 0)
{
ans = 1;
_sys_call_table = tmp_sys_call_table;
printk("[+] find sys_call_table: 0x%lx\n", tmp_sys_call_table);
}
return ans;
}
// initialize the module
static int hooked_init(void) {
printk("+ Loading hook_mkdir module\n");
if(!get_sys_call_table()){
return 0;
}
// now we can hook syscalls ...such as uname
// first, save the old gate (fptr)
old_mkdir = (old_mkdir_t) _sys_call_table[__NR_mkdir];
// unprotect sys_call_table memory page
pte = lookup_address((unsigned long) _sys_call_table, &level);
// change PTE to allow writing
set_pte_atomic(pte, pte_mkwrite(*pte));
printk("+ unprotected kernel memory page containing sys_call_table\n");
// now overwrite the __NR_uname entry with address to our uname
_sys_call_table[__NR_mkdir] = (sys_call_ptr_t) hooked_mkdir;
printk("+ sys_mkdir hooked!\n");
return 0;
}
static void hooked_exit(void) {
if(old_mkdir != NULL) {
// restore sys_call_table to original state
_sys_call_table[__NR_mkdir] = (sys_call_ptr_t) old_mkdir;
// reprotect page
set_pte_atomic(pte, pte_clear_flags(*pte, _PAGE_RW));
}
printk("+ Unloading hook_mkdir module\n");
}
/*entry/exit macros*/
module_init(hooked_init);
module_exit(hooked_exit);
对于vdso的hook
利用漏洞
- 利用内核漏洞rce改到用户态可写,然后修改vdso
- 利用内核任意写漏洞进行修改vdso
前提是,你得有能用的内核洞!!!!!
修改源码
直接修改linux内核源码,重新编译
修改sources.list
sed -i 's/# deb-src/deb-src/g' /etc/apt/sources.list;
获取源码
apt-cache search linux-source
apt-get source linux-source-5.4.0
or
apt-get install linux-source-5.4.0
编译过程
sudo su;
apt-get install -y build-essential kernel-package bison libncurses5-dev libssl-dev build-essential openssl zlibc minizip libidn11-dev libidn11;
make mrproper && make clean && make menuconfig;
make -j8;
make modules_install;
make install;
reboot;
ubuntu18以上加上
apt-get install flex libelf-dev;
需要精简一点的话
make localmodconfig
make menuconfig
联合起来
make mrproper && make clean && make localmodconfig && time make -j40 && make modules_install && make install && reboot
make mrproper && make clean && make localmodconfig && time make -j32 && make modules_install && make install && reboot
make mrproper && make clean && make localmodconfig && time make -j24 && make modules_install && make install && reboot
make mrproper && make clean && make localmodconfig && time make -j16 && make modules_install && make install && reboot
make mrproper && make clean && make localmodconfig && time make -j12 && make modules_install && make install && reboot
make mrproper && make clean && make localmodconfig && time make -j8 && make modules_install && make install && reboot
顺便丢一个编译时间的表,以后参考,都是ubuntu20.04.1
,可能有其他因素影响,比如硬盘io
CPU | 编译线程数 | 时间 |
---|---|---|
E5-2660v2*2 | 40 | 326 |
I7-8700K | 12 | 243 |
I7-4790(hdd) | 8 | 2471 |