Task3 :把secret data放在内核空间中
这是Meltdown Attack的第三个实验,原实验教程在此:
https://seedsecuritylabs.org/Labs_16.04/System/Meltdown_Attack/
本次实验是为Meltdown Attack做准备。主要目的是把secret data放在内核空间。以便后续我们以用户态获取到内核态的信息。就有点像插个旗子在内核,然后等我们后面去拿。
实现熔断攻击需要满足两个条件:
- 我们需要知道目标secret data的地址。下面代码的内核模块将secret data的地址保存在了内核信息缓冲区中,这样使用dmesg 就可以访问到了。现实中的meltdown攻击就必须自己去找到这个地址,或者猜这个地址。
- secret data需要在cache中。为了实现这点,只需要使用这个数据一次就可以了。首先,创建一个data entry
/proc/secret_data
,为用户级程序与内核模块的交互提供了机会。当用户级的程序读取这个entry,就会唤醒内核模块中的read_proc()
函数。而这个函数会加载secret变量,从而将secret缓存到cache中去。PS:read_proc()
函数不会返回secret的值,不然就没有意义使用熔断攻击来获取重要信息了。
static char secret[8] = {’S’, ’E’, ’E’, ’D’, ’L’, ’a’, ’b’, ’s’};
static struct proc_dir_entry *secret_entry;
static char* secret_buffer;
static int test_proc_open(struct inode *inode, struct file *file)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,0,0)
return single_open(file, NULL, PDE(inode)->data);
#else
return single_open(file, NULL, PDE_DATA(inode));
#endif
}
static ssize_t read_proc(struct file *filp, char *buffer,
size_t length, loff_t *offset)
{
memcpy(secret_buffer, &secret, 8); //1
return 8;
}
static const struct file_operations test_proc_fops =
{
.owner = THIS_MODULE,
.open = test_proc_open,
.read = read_proc,
.llseek = seq_lseek,
.release = single_release,
};
static __init int test_proc_init(void)
{
// write message in kernel message buffer
printk("secret data address:%p\n", &secret); //2
secret_buffer = (char*)vmalloc(8);
// create data entry in /proc
secret_entry = proc_create_data("secret_data",
0444, NULL, &test_proc_fops, NULL); //3
if (secret_entry) return 0;
return -ENOMEM;
}
static __exit void test_proc_cleanup(void)
{
remove_proc_entry("secret_data", NULL);
}
module_init(test_proc_init);
module_exit(test_proc_cleanup);
Makefile
KVERS = $(shell uname -r)
# Kernel modules
obj-m += MeltdownKernel.o
build: kernel_modules
kernel_modules:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
clean:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
编译和执行
$ make
$ sudo insmod MeltdownKernel.ko
$ dmesg | grep ’secret data address’
secret data address: 0xf9c6c000
执行make后,文件夹应该会多出很多内核模块文件,如下图。
执行insmod命令,就将写好的模块载入内核。
这时候,使用dmesg
命令就可以查看到secret data的地址了。
PS:secret data address 每个人生成的都不一样,后续实验还会用到。