Linux内核攻击Linux 4.6.x的开放系统调用

时间:2016-07-29 05:27:14

标签: linux linux-kernel kernel-module

我试图用我自己的函数替换open系统的linux系统调用。在内核版本2.6之后,不会导出Sys_call_table sysmbol。我从system.map文件硬编码sys_call_table的虚拟地址。

我保存了原始系统调用[NR_OPEN],然后尝试使用system_map中的set_memory_rw函数,因为它不适用于arm linux。我正在为beaglebone编写内核模块。如果我尝试通过函数指针使用system.map文件中给出的虚拟地址来使用该函数,我会得到无法处理内核分页请求的内核oops。

System_call_table是只读的,如果我尝试写入它,它会在str指令中给出内核oops。

我使用以下代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/unistd.h>
#include <asm/memory.h>


MODULE_LICENSE("GPL");              ///< The license type -- this
affects runtime behavior MODULE_AUTHOR("Zohaib");      ///< The author
-- visible when you use modinfo


unsigned long *sys_call_table = (unsigned long *) 0xc0107a28;  int a;
unsigned long phy_addr_sys_call_table,x;

asmlinkage unsigned long int (*vir_to_phy) (unsigned long int x);
static asmlinkage int (*set_mem_rw) (unsigned long int, int); static
asmlinkage int (**write) (unsigned long int, int); static asmlinkage
int (*original_call) (const char*, int, int); int ret;

static asmlinkage int our_sys_open(const char* file, int flags, int
mode) {    printk("A file was opened\n");    return
original_call(file, flags, mode); }

static int __init hello_module(void) {
    // sys_call_table address in System.map

    printk("NEW \n");
    x= virt_to_phys((void*)0xc0115fe0);
    printk(" %p", (void*)(x));
    printk(" \n \n \n DEBUG POINT 1:");
    write=(int (**) (unsigned long int, int))(virt_to_phys((void*)0xc0115fe0));


    printk("\n \n \n DEBUG POINT 2");
    set_mem_rw= *write;


    printk("HI \n");
    printk(" \n \n \n : %p", set_mem_rw);

    a=__NR_open;
    printk(" \n \n \n %i",a);

    original_call = (void*)*(sys_call_table + __NR_open);
    printk("\n \n \n vir_to_phys test \n");

    phy_addr_sys_call_table= virt_to_phys((void*)0xc0107a28);
    printk("\n \n \n vir_to_phys test succeeded: %p", (void*)phy_addr_sys_call_table);

    printk("\n CRASHINNNNNNNNN..... ");
    // this is where it crashes.
    ret=(*set_mem_rw)((unsigned long)phy_addr_sys_call_table,20);

    printk("\n CRASH point no.1 ");

    printk( "\n %lu ", sys_call_table[__NR_open]);
    printk( "\n %p ", original_call);
    printk(" \n DIDN'T CRASH at point no.1 \n");

    printk("CRASH point no.2 \n");

    printk("%p", sys_call_table);
    printk(" \n DIDN'T CRASH at point no.2 \n");


    // read only sys_call_table, cannot write to it if readwrite privilege is not given, gives kernel oops otherwise
    printk(" \n \n %p \n", (our_sys_open));
    *(sys_call_table + __NR_open) = (unsigned long)our_sys_open;

    printk(" \n SUCCEEDED ");

    return 0; }

static void __exit bye_module(void) {    // Restore the original call
    sys_call_table[__NR_open] = original_call;

    printk("BYE"); }

module_init(hello_module); module_exit(bye_module);

0 个答案:

没有答案