Advertisement
Guest User

Untitled

a guest
May 5th, 2019
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.23 KB | None | 0 0
  1. // DO NOT USE
  2. // traps and recalls mount/umount syscalls
  3. // gcc -shared -fPIC -o wrapper.so seccomp_trap.c
  4. // LD_PRELOAD=/.../wrapper.so mount ...
  5.  
  6. #define _GNU_SOURCE
  7.  
  8. #include <errno.h>
  9. #include <signal.h>
  10. #include <stddef.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. #include <sys/prctl.h>
  15. #include <sys/syscall.h>
  16.  
  17. #include <linux/audit.h>
  18. #include <linux/filter.h>
  19. #include <linux/seccomp.h>
  20.  
  21. #ifndef SYS_SECCOMP
  22. #define SYS_SECCOMP 1 // /usr/include/asm-generic/siginfo.h
  23. #endif
  24.  
  25. #ifdef __x86_64__
  26. #define MY_ARCH AUDIT_ARCH_X86_64
  27. #else
  28. // x86_64 assembler and register are used here
  29. #error invalid arch
  30. #endif
  31.  
  32. #ifndef imstupid
  33. #error DO NOT FUCKING USE THIS
  34. #endif
  35.  
  36.  
  37. static long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6);
  38.  
  39.  
  40. static void sighandler(int nr, siginfo_t *info, void *ctxptr)
  41. {
  42.     if (info->si_code != SYS_SECCOMP)
  43.         return;
  44.  
  45.     if (!ctxptr)
  46.         return;
  47.  
  48.     ucontext_t *ctx = (ucontext_t *)(ctxptr);
  49.  
  50.     // see SYSTEM V amd64 ABI
  51.    
  52.     int syscall_nr = ctx->uc_mcontext.gregs[REG_RAX];
  53.     if (syscall_nr != __NR_mount && syscall_nr != __NR_umount2) // WTF?
  54.         return;
  55.  
  56.     if (syscall_nr == __NR_mount) {
  57.         char *source = (char*) ctx->uc_mcontext.gregs[REG_RDI];
  58.         char *target = (char*) ctx->uc_mcontext.gregs[REG_RSI];
  59.         char *filesystemtype = (char*) ctx->uc_mcontext.gregs[REG_RDX];
  60.         unsigned long mountflags = ctx->uc_mcontext.gregs[REG_R10];
  61.         void *data = (void*) ctx->uc_mcontext.gregs[REG_R8];
  62.  
  63.         printf("mount(\"%s\", \"%s\", \"%s\", %ld, %p)\n",
  64.                 source, target, filesystemtype, mountflags, data);
  65.  
  66.         long ret = syscall6(__NR_mount,
  67.                 (long)source, (long)target, (long)filesystemtype,
  68.                 mountflags, (long)data, 0);
  69.  
  70.         //result
  71.         ctx->uc_mcontext.gregs[REG_RAX] = ret;
  72.     } else if (syscall_nr == __NR_umount2) {
  73.         char *target = (char*) ctx->uc_mcontext.gregs[REG_RDI];
  74.         int flags = ctx->uc_mcontext.gregs[REG_RSI];
  75.  
  76.         printf("umount2(\"%s\", %d)\n", target, flags);
  77.  
  78.         long ret = syscall6(__NR_umount2, (long)target, flags, 0, 0, 0, 0);
  79.  
  80.         ctx->uc_mcontext.gregs[REG_RAX] = ret;
  81.     }
  82. }
  83.  
  84.  
  85. __attribute__((constructor))
  86. static void install_wrapper(void)
  87. {
  88.     printf("hello\n");
  89.  
  90.     struct sigaction act;
  91.     memset(&act, 0, sizeof(act));
  92.     sigset_t mask;
  93.     sigemptyset(&mask);
  94.     sigaddset(&mask, SIGSYS);
  95.  
  96.     act.sa_sigaction = &sighandler;
  97.     act.sa_flags = SA_SIGINFO;
  98.     if (sigaction(SIGSYS, &act, NULL)) {
  99.         perror("sigaction");
  100.         return;
  101.     }
  102.  
  103.     if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
  104.         perror("sigprocmask");
  105.         return;
  106.     }
  107.  
  108.     unsigned long syscall_area_begin = (unsigned long) &syscall6;
  109.     unsigned long syscall_area_end = syscall_area_begin + 4096;
  110.  
  111.     printf("%lx %lx\n", syscall_area_begin, syscall_area_end);
  112.  
  113.     struct sock_filter filter[] = {
  114.         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, arch)),
  115.         BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, MY_ARCH, 1, 0),
  116.         BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
  117.         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
  118.         BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_mount, 2, 0),
  119.         BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_umount2, 1, 0),
  120.         BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
  121.         BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, instruction_pointer)),
  122.         BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, syscall_area_begin, 0, 2),
  123.         BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, syscall_area_end, 1, 0),
  124.         BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
  125.         BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
  126.     };
  127.  
  128.     struct sock_fprog prog = {
  129.         .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
  130.         .filter = filter,
  131.     };
  132.  
  133.     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
  134.         perror("no_new_privs fail");
  135.         return;
  136.     }
  137.  
  138.     if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
  139.         perror("bpf fail");
  140.         return;
  141.     }
  142. }
  143.  
  144.  
  145. __attribute__((aligned(4096)))
  146. static long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
  147. {
  148.     //https://git.musl-libc.org/cgit/musl/tree/arch/x86_64/syscall_arch.h
  149.     unsigned long ret;
  150.     register long r10 __asm__("r10") = a4;
  151.     register long r8 __asm__("r8") = a5;
  152.     register long r9 __asm__("r9") = a6;
  153.     __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
  154.                           "d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
  155.     return ret;
  156. }
  157. __asm__(".align 4096");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement