secuestro del kernel de linux

/* ============================================================================
 Name        : hellomod.c
 Author      : Hava
 Version     : 0.0.0.0
 Copyright   : Copyright by 2011
 Description : Hello World in C, Ansi-style 
 ============================================================================
 */
 
/*hellomod.c*/
 
// hello model for Linux 2.6
 
/*
 *  some import the model include
 * */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
/* 
 * the function define address is over here
 * this h file is in kernel/arch/x86/include/asm/unistd.h
 * is include two file unistd_32.h & unistd_64.h
 * you can check the unistd_32.h to find the system call function entrance
 */
#include <asm/unistd.h>
#include <asm/uaccess.h>
/*
 * This include is base for the string
 */
#include <linux/string.h>
#include <linux/syscalls.h>
//#include <linux/sched.h>
//#include <linux/mm.h>
 
#define NAME_MAX 255
 
//UID
static int uid;
module_param(uid,int,0777);
 
/*
 * Set the linux kernel module infomation
 * */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Õ½Åô");
MODULE_DESCRIPTION("Hello the model");
 
/*
 * Global Variables declaration
 * */
unsigned long * sys_call_table = NULL;
unsigned int original_cr0 = NULL;
 
asmlinkage int (* original_mkdir)(const char *,int);
asmlinkage int (* original_unlink)(const char *);
asmlinkage long (* original_unlinkat)(int, const char *,int);
asmlinkage long (* original_rename)(const char *, const char *);
asmlinkage long (* original_renameat)(int, const char *, int, const char *);
 
/*
 * The Struct of the idt the sizeof 6
 * bits  0 to 15 : limit    ->16
 * bits 16 to 47 : base     ->32
 */
struct struct_idtr {
    unsigned short limit;
    unsigned int base;
};
 
/*
 * The Struct of the idt the sizeof 8
 * bits  0 to 15 : handler offset low   ->16
 * bits 16 to 31 : segment selector ->16
 * bits 32 to 37 : reserved     ->}8
 * bits 37 to 39 : 0            ->
 * bits 40 to 47 : flags/type       ->8
 * bits 48 to 63 : handler offset high  ->16
 */
struct struct_idt
{
    unsigned short offset_low;
    unsigned short segment_selector;
    unsigned char reserved;
    unsigned char flags;
    unsigned short offset_high;
};
 
unsigned long * getSyscallTable(void)
{
    /* in x86 cpu idtr is Interrupt descriptor table register */
    unsigned char idtr [6] = {0,0,0,0,0,0};
    /*Interrupt descriptor table*/
    struct struct_idt * idt;
    /*address of system_call*/
    unsigned long system_call;
     
    unsigned char * memoryaddr;
 
    //for the while
    int i = 0;
 
    unsigned char * syscall_key = "\xff\x14\x85";
 
    unsigned char * pointer = NULL;
 
    printk("<1>Begin to Get the System call Table address");
    /* get the interrupt descriptor table register */
    asm("sidt %0" : "=m" (idtr));
    printk("<1>sidt idtr:%x %x %x %x %x %x",idtr[0],idtr[1],idtr[2],idtr[3],idtr[4],idtr[5]);
     
    idt=(struct struct_idt *)(*(unsigned long *)&idtr[2]+8*0x80);
    printk("<1>Struct idt address :%x" ,idt);
 
    /* Exchange of high and low */
    system_call = (idt->offset_high << 16) | idt->offset_low;
    printk("<1>Get the system call address :%x" ,system_call);
     
    memoryaddr=(char *)system_call;
    printk("<1>The system call address to the array:%x" ,memoryaddr);
     
    /*
     * the system_call find \xff\x14\x85 + 3 = system_call_table
     */
    for(i=0;i<(128-2);i++)
    {
        if(memoryaddr[i]==syscall_key[0]&&memoryaddr[i+1]==syscall_key[1]&&memoryaddr[i+2]==syscall_key[2])
            break;
    }
     
    printk("<1>Find the memory the key after the system call address , %d" ,i);   
    printk("<1>The memory the key address , %x" ,&memoryaddr[i]);
    pointer = &memoryaddr[i];
    pointer = pointer + 3;
 
    printk("<1>The pointer address , %x" ,pointer);
 
    printk("<1>End and return the System call Table address, is %x" ,*(unsigned long*)pointer);
    return *(unsigned long *)pointer;
}
 
asmlinkage int hacked_mkdir(const char * pathname, int mode)
{
    printk("<1>mkdir pathname :%s and the mode :%d" , pathname , mode);
    printk("<1>hijack mkdir");
    return original_mkdir(pathname,mode);
}
 
//int _unlink( const char * pathname ); 
asmlinkage int hacked_unlink(const char * pathname)
{
    printk("<1>unlink pathname :%s", pathname);
    printk("<1>hijack unlink");
 
    return original_unlink(pathname);
}
 
//kernels/2.6.32-71.el6.i686/include/linux/syscalls.h:asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag);
//asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag);
asmlinkage long hacked_unlinkat(int dfd, const char * pathname, int flag)
{
    char rmfilename[NAME_MAX];
    long rename = 0;
    long unlinkat = 0;
    printk("<1>unlinkat dfd :%d" , dfd);
    printk("<1>unlinkat pathname :%s" , pathname);
    printk("<1>unlinkat flag :%d" , flag);
    printk("<1>hijack unlinkat");
 
    printk("<1>unlinkat filename: %s by uid: %d",pathname,uid);
 
    printk("<1>Begin rename");
 
    strcpy(rmfilename,pathname);
    printk("<1>copy the filename :%s" , rmfilename);
    printk("<1>Add Exension :%s",strcat(rmfilename,".Exension"));
    printk("<1>Add Exension:%s",strcat(pathname,".Exension"));
    //rename = sys_rename(pathname,strcat(pathname,".Exension"));
    printk("<1>After add exension filename is :%s", rmfilename);
    //rename = original_rename(pathname,rmfilename);
    //printk("<1>rename %ld", rename);
    //printk("<1>show errno msg :%s" , strerror(rename));
    unlinkat = original_unlinkat(dfd,pathname,flag);
    printk("<1>unlinkat %ld",unlinkat);
    return unlinkat;
}
 
//asmlinkage long sys_renameat(int olddfd, const char __user * oldname, int newdfd, const char __user * newname);
//asmlinkage long hacked_rename(const char __user * oldname, const char __user * newname)
//{
//  printk("<1>sys_rename :%s,%s",oldname,newname);
//  original_rename(oldname,newname);
//}
/*
 * clear WP bit of CR0, and return the original value
 */
 
unsigned int clear_and_return_cr0(void)
{
    unsigned int cr0 = 0;
    unsigned int ret;
    /*get cr0*/
    asm volatile ("movl %%cr0, %%eax" : "=a"(cr0));
 
    ret = cr0;
 
    /* clear the 20 bit of CR0, a.k.a WP bit */
    cr0 &= 0xfffeffff;
    /*set cr0*/
    asm volatile ("movl %%eax, %%cr0" : : "a"(cr0));
 
    return ret;
}
 
unsigned int get_cr0(void)
{
    unsigned int cr0 = 0;
    /*get cr0*/
    asm volatile ("movl %%cr0, %%eax" : "=a"(cr0));
 
    return cr0;
}
 
/* set CR0 with new value */
void set_cr0(unsigned int cr0)
{
    /*set cr0*/
    asm volatile ("movl %%eax, %%cr0" : : "a"(cr0));
}
 
void init_cr0(void)
{
    unsigned int cr0 = NULL;
    /* clear the 20 bit of CR0, a.k.a WP bit */
    cr0 &= 0xfffeffff;
    /*set cr0*/
    asm volatile ("movl %%eax, %%cr0" : : "a"(cr0));
}
/*
 * model init and exit
 * */
static int __init mod_init(void)
{
    mm_segment_t old_fs;
 
    printk("<1><>Hello Model Init!\n");
    sys_call_table = getSyscallTable();
 
    original_cr0 = clear_and_return_cr0();
    old_fs = get_fs();
    set_fs(KERNEL_DS);
    if(sys_call_table != NULL)
    {
        //mkdir
        printk("<1>System_Call_Table address: %lx ", sys_call_table);
        printk("<1>function call number by mkdir: %d", __NR_mkdir);
        printk("<1>function call number by read: %d", __NR_read);
 
        printk("<1>function call address by mkdir: %x", sys_call_table[__NR_mkdir]);
        original_mkdir=(int(*)(const char*,int))sys_call_table[__NR_mkdir];
        printk("<1>get the Original Address : %x", original_mkdir);
        sys_call_table[__NR_mkdir]=(unsigned long)hacked_mkdir;
 
        //unlink
        printk("<1>function call number by unlink: %d", __NR_unlink);
        printk("<1>function call address by unlink: %x", sys_call_table[__NR_unlink]);
        original_unlink=(int(*)(const char*))sys_call_table[__NR_unlink];
        printk("<1>get the Original Address : %x", original_unlink);
        sys_call_table[__NR_unlink]=(unsigned long)hacked_unlink;
 
        //unlinkat
        printk("<1>function call number by unlinkat: %d", __NR_unlinkat);
        printk("<1>function call address by unlinkat: %x", sys_call_table[__NR_unlinkat]);
        original_unlinkat=(int(*)(const char*))sys_call_table[__NR_unlinkat];
        printk("<1>get the Original Address : %x", original_unlinkat);
        sys_call_table[__NR_unlinkat]=(unsigned long)hacked_unlinkat;
 
        //rename
        //printk("<1>function call number by rename: %d", __NR_rename);
        //printk("<1>function call address by rename: %x", sys_call_table[__NR_rename]);
        //original_rename=(int(*)(const char*))sys_call_table[__NR_rename];
        //printk("<1>get the Original Address : %x", original_rename);
        //sys_call_table[__NR_rename]=(unsigned long)hacked_rename;
 
        //renameat
        //printk("<1>function call number by renameat: %d", __NR_renameat);
        //printk("<1>function call address by renameat: %x", sys_call_table[__NR_renameat]);
        //original_renameat=(int(*)(const char*))sys_call_table[__NR_renameat];
        //printk("<1>get the Original Address : %x", original_renameat);
 
        printk("<1>>UID:%d",uid);
 
        printk("<1>hacked");
    }
    set_fs(old_fs);
    set_cr0(original_cr0);
    return 0;
}
 
static void __exit mod_exit(void)
{
    original_cr0 = clear_and_return_cr0();
    sys_call_table[__NR_mkdir]=(unsigned long)original_mkdir;
    sys_call_table[__NR_unlink]=(unsigned long)original_unlink;
    sys_call_table[__NR_unlinkat]=(unsigned long)original_unlinkat;
    //sys_call_table[__NR_rename]=(unsigned long)original_rename;
    set_cr0(original_cr0);
    printk("<1><>Hello Model Exit.20111217\n");
}
 
module_init(mod_init);
module_exit(mod_exit);

El secuestro del kernel de Linux, adecuado para la plataforma Linux, requiere experiencia en el desarrollo del kernel de Linux, adecuado para el kernel de CentOS 6.0. Esta versión es adecuada para 32 bits, 64 bits, calcule los bits de registro o complete los ceros usted mismo.

# Makefile2.6
# 产生hellomod 模块的目标文件
obj-m += hellomod.o
#模块所在的当前路径
CURRENT_PATH := $(shell pwd)
#Linux内核源代码的当前版本
LINUX_KERNEL := $(shell uname -r)
#Linux内核源代码的绝对路径
LINUX_KERNEL_PATH := /usr/src/kernels/$(LINUX_KERNEL) 
all:
    @echo '程序根目录:$(CURRENT_PATH)'
    @echo 'Linux内核版本:$(LINUX_KERNEL)'
    @echo 'Linux src:$(LINUX_KERNEL_PATH)'
    @echo '开始编译模块'
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
    @echo '结束编译模块'
clean:
    @echo '开始清理模块'
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
    @echo '结束清理模块'

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_24436765/article/details/108355316
Recomendado
Clasificación