• linux下系统调用劫持ioctl


    实验环境:linux 2.6.32   64位系统


    采用lkm(动态加载内核模块)方式劫持ioctl系统调用,系统调用过程如图所示(以open为例子)


    实验代码:(头文件有不需要的,但是懒得改了,在系统开发时依赖 kernel-devel开发工具)

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/sched.h>
    #include <linux/fs.h>
    #include <linux/file.h>
    #include <linux/fs_struct.h>
    #include <linux/fdtable.h>
    #include <linux/string.h>
    #include <linux/mm.h>
    #include <linux/syscalls.h>
    #include <linux/list.h>
    #include <linux/jiffies.h>
    #include <linux/cdev.h>
    #include <linux/path.h>
    #include <linux/time.h>
    #include <linux/stat.h>
    #include <net/sock.h>
    #include <net/inet_sock.h>
    #include <linux/cdrom.h>
    #include <linux/types.h>
    #include <linux/security.h>
    #include <linux/export.h>
    #include <linux/uaccess.h>
    #include <linux/writeback.h>
    #include <linux/buffer_head.h>
    #include <linux/falloc.h>
    #include <asm/cpufeature.h>
    #include <asm/unistd.h>
    #include <asm/uaccess.h>
    #include <asm/ioctls.h>
    #include <linux/compiler.h>
    #include <linux/posix_types.h>
    #include <linux/syscalls.h>
    #include <linux/export.h>
    #include <linux/fs.h>
    #include <linux/mm.h>
    #include <linux/mmzone.h>
    #include <linux/time.h>
    #include <linux/sched.h>
    #include <linux/slab.h>
    #include <linux/vmalloc.h>
    #include <linux/file.h>
    #include <linux/fdtable.h>
    #include <linux/bitops.h>
    #include <linux/interrupt.h>
    #include <linux/spinlock.h>
    #include <linux/rcupdate.h>
    #include <linux/workqueue.h>


    #include <linux/syscalls.h>
    #include <linux/mm.h>
    #include <linux/smp_lock.h>
    #include <linux/capability.h>
    #include <linux/file.h>
    #include <linux/fs.h>
    #include <linux/security.h>
    #include <linux/module.h>
    #include <linux/uaccess.h>
    #include <linux/writeback.h>
    #include <linux/buffer_head.h>
    #include <linux/falloc.h>
    #include <linux/ioctl.h>
    #include <asm/ioctls.h>

    //通过内核符号表查找到的sys_call_table的地址
    //  grep sys_call_table /boot/System.map-`uname -r` 
    unsigned long **sys_call_table = (unsigned long **)0xffffffff81600520;
    //unsigned long *orig_mkdir = NULL;  
    //unsigned long *orig_ioctl = NULL;
    asmlinkage long (*orig_ioctl)(unsigned int fd, unsigned int cmd,
    unsigned long arg);
    //为了可以对sys_call_table所在内存页,进行读写,需要重新设置页的属性。
    /* make the page writable */
    int make_rw(unsigned long address)
    {
            unsigned int level;
            pte_t *pte = lookup_address(address, &level);//查找地址所在的内存页面
            if (pte->pte & ~_PAGE_RW) //设置读写属性
                    pte->pte |=  _PAGE_RW;
            return 0;
    }
    /* make the page write protected */
    int make_ro(unsigned long address)
    {
            unsigned int level;
            pte_t *pte = lookup_address(address, &level);
            pte->pte &= ~_PAGE_RW; //设置只读属性
            return 0;
    }
    //mkdir的函数原型,这个函数的原型要和系统的一致
    /*asmlinkage long hacked_mkdir(const char __user *pathname, int mode)
    {
            printk("mkdir pathname: %s ", pathname);
            printk(KERN_ALERT "mkdir do nothing! ");
            return 0; //everything is ok, but he new systemcall does nothing*/
    //}
    // you should change inside code according your kernel version
    asmlinkage long hacked_ioctl(unsigned int fd, unsigned int cmd,
    unsigned long arg){
    printk("hacking ");
    if(cmd == CDROMEJECT){
    printk("HiveMe Hack! ");
    return 0;
    }

    return orig_ioctl(fd,cmd,arg);
    }


    //也是内核初始化函数
    static int syscall_init_module(void)
    {
            printk(KERN_ALERT "sys_call_table: 0x%p ", sys_call_table);
          //  orig_mkdir = (unsigned long *)(sys_call_table[__NR_mkdir]); //获取原来的系统调用地址
            orig_ioctl = (unsigned long *)(sys_call_table[__NR_ioctl]);
         //   printk(KERN_ALERT "orig_mkdir: 0x%p ", orig_mkdir);
    printk(KERN_ALERT "orig_ioctl: 0x%p ", orig_ioctl);
            make_rw((unsigned long)sys_call_table); //修改页属性
        //    sys_call_table[__NR_mkdir] = (unsigned long *)hacked_mkdir; //设置新的系统调用地址
        //    printk("mkdir ");
          sys_call_table[__NR_ioctl] = (unsigned long *)hacked_ioctl;
    printk("ioctl ");
           // make_ro((unsigned long)sys_call_table);
            return 0;
    }

    //内核注销函数
    static void syscall_cleanup_module(void)
    {
            printk(KERN_ALERT "Module syscall unloaded. ");


            make_rw((unsigned long)sys_call_table);
          //  sys_call_table[__NR_mkdir] = (unsigned long *)orig_mkdir;
    sys_call_table[__NR_ioctl] = (unsigned long *)orig_ioctl;
            /*set mkdir syscall to the origal one*/
            make_ro((unsigned long)sys_call_table);
    }
    module_init(syscall_init_module);
    module_exit(syscall_cleanup_module);
    MODULE_LICENSE("GPL");
    MODULE_DESCRIPTION("hack syscall");
    代码源自其他网友,进行了部分修改,如原作者需要特殊标注请与我联系



  • 相关阅读:
    Python学习笔记21:数据库操作(sqlite3)
    JAVA的extends使用方法
    thinkphp5的Illegal string offset 'id'错误
    thinkphp5项目--个人博客(五)
    语法错误: unexpected ''); ?></span></span></h2> ' (T_CONSTANT_ENCAPSED_STRING), expecting ',' or ';'
    thinkphp5.0的验证码安装和相关错误
    thinkphp5项目--个人博客(四)
    thinkphp5项目--个人博客(三)
    NAS是什么
    百度编辑器简介及如何使用
  • 原文地址:https://www.cnblogs.com/hiveme/p/8194834.html
Copyright © 2020-2023  润新知