trailofbits / krf

A kernelspace syscall interceptor and randomized faulter
https://blog.trailofbits.com/2019/01/17/how-to-write-a-rootkit-without-really-trying/
GNU General Public License v3.0
348 stars 35 forks source link

Syscall support: miscellaneous #6

Open woodruffw opened 5 years ago

woodruffw commented 5 years ago

We should support faulting these syscalls.

That list is not exhaustive; there are definitely others.

Each of the above probably belongs to one or more groups.

layderv commented 4 years ago

How to decide to which groups each syscall belongs?

woodruffw commented 4 years ago

How to decide to which groups each syscall belongs?

The manpages (man 2 <whatever>) should help with that. The major ones are fs (touches the filesystem), io (does any sort of I/O), net (does any sort of networking), proc (does any sort of process management), and time (deals with the system clock). Check out the other syscall specs for reference.

layderv commented 4 years ago

I was going to add these as well:

< src/module/codegen/linux/arch_prctl.yml
proto: int option, unsigned long arg2
parms: option, arg2
errors:
  - EFAULT
  - EINVAL
  - EPERM
profiles:
  - fs
  - proc

< src/module/codegen/linux/iopl.yml
proto: int level
parms: level
errors:
  - ENOSYS
  - EINVAL
  - EPERM
profiles:
  - io
  - proc

With them, I cannot build:


In file included from /src/module/linux/syscalls.h:40:0,
                 from /src/module/linux/syscalls.c:1:
/src/module/linux/syscalls.gen.h:57:19: error: ‘sys_iopl’ undeclared here (not in a function); did you mean ‘sys_ipc’?
 asmlinkage typeof(sys_iopl) krf_sys_iopl;
                   ^~~~~~~~
                   sys_ipc
In file included from /src/module/linux/syscalls.h:40:0,
                 from /src/module/linux/krf.c:10:
/src/module/linux/syscalls.gen.h:57:19: error: ‘sys_iopl’ undeclared here (not in a function); did you mean ‘sys_ipc’?
 asmlinkage typeof(sys_iopl) krf_sys_iopl;
                   ^~~~~~~~
                   sys_ipc
/src/module/linux/syscalls.gen.h:178:19: error: ‘sys_arch_prctl’ undeclared here (not in a function); did you mean ‘__NR_arch_prctl’?
 asmlinkage typeof(sys_arch_prctl) krf_sys_arch_prctl;
                   ^~~~~~~~~~~~~~
                   __NR_arch_prctl
/src/module/linux/syscalls.gen.h:178:19: error: ‘sys_arch_prctl’ undeclared here (not in a function); did you mean ‘__NR_arch_prctl’?
 asmlinkage typeof(sys_arch_prctl) krf_sys_arch_prctl;
                   ^~~~~~~~~~~~~~
                   __NR_arch_prctl
scripts/Makefile.build:330: recipe for target '/src/module/linux/krf.o' failed
make[3]: *** [/src/module/linux/krf.o] Error 1
make[3]: *** Waiting for unfinished jobs....
In file included from /src/module/linux/syscalls.c:10:0:
/src/module/linux/syscalls.gen.x:473:17: error: ‘krf_sys_iopl’ redeclared as different kind of symbol
 long asmlinkage krf_sys_iopl(int level) {
                 ^~~~~~~~~~~~
In file included from /src/module/linux/syscalls.h:40:0,
                 from /src/module/linux/syscalls.c:1:
/src/module/linux/syscalls.gen.h:57:29: note: previous declaration of ‘krf_sys_iopl’ was here
 asmlinkage typeof(sys_iopl) krf_sys_iopl;
                             ^~~~~~~~~~~~
In file included from /src/module/linux/syscalls.c:10:0:
/src/module/linux/syscalls.gen.x: In function ‘krf_sys_iopl’:
/src/module/linux/syscalls.gen.x:477:12: error: called object ‘krf_sys_internal_iopl’ is not a function or function pointer
     return krf_sys_internal_iopl(level);
            ^~~~~~~~~~~~~~~~~~~~~
In file included from /src/module/linux/syscalls/internal.h:33:0,
                 from /src/module/linux/syscalls.c:2:
/src/module/linux/syscalls/internal.gen.h:57:18: note: declared here
 typeof(sys_iopl) krf_sys_internal_iopl;
                  ^~~~~~~~~~~~~~~~~~~~~
In file included from /src/module/linux/syscalls.c:10:0:
/src/module/linux/syscalls.gen.x:479:12: error: called object ‘real_iopl’ is not a function or function pointer
     return real_iopl(level);
            ^~~~~~~~~
/src/module/linux/syscalls.gen.x:474:21: note: declared here
   typeof(sys_iopl) *real_iopl = (void *)krf_sys_call_table[__NR_iopl];
                     ^~~~~~~~~
/src/module/linux/syscalls.gen.x: At top level:
/src/module/linux/syscalls.gen.x:1562:17: error: ‘krf_sys_arch_prctl’ redeclared as different kind of symbol
 long asmlinkage krf_sys_arch_prctl(int option, unsigned long arg2) {
                 ^~~~~~~~~~~~~~~~~~
In file included from /src/module/linux/syscalls.h:40:0,
                 from /src/module/linux/syscalls.c:1:
/src/module/linux/syscalls.gen.h:178:35: note: previous declaration of ‘krf_sys_arch_prctl’ was here
 asmlinkage typeof(sys_arch_prctl) krf_sys_arch_prctl;
                                   ^~~~~~~~~~~~~~~~~~
In file included from /src/module/linux/syscalls.c:10:0:
/src/module/linux/syscalls.gen.x: In function ‘krf_sys_arch_prctl’:
/src/module/linux/syscalls.gen.x:1566:12: error: called object ‘krf_sys_internal_arch_prctl’ is not a function or function pointer
     return krf_sys_internal_arch_prctl(option, arg2);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /src/module/linux/syscalls/internal.h:33:0,
                 from /src/module/linux/syscalls.c:2:
/src/module/linux/syscalls/internal.gen.h:178:24: note: declared here
 typeof(sys_arch_prctl) krf_sys_internal_arch_prctl;
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /src/module/linux/syscalls.c:10:0:
/src/module/linux/syscalls.gen.x:1568:12: error: called object ‘real_arch_prctl’ is not a function or function pointer
     return real_arch_prctl(option, arg2);
            ^~~~~~~~~~~~~~~
/src/module/linux/syscalls.gen.x:1563:27: note: declared here
   typeof(sys_arch_prctl) *real_arch_prctl = (void *)krf_sys_call_table[__NR_arch_prctl];
                           ^~~~~~~~~~~~~~~
/src/module/linux/syscalls.gen.x: In function ‘krf_sys_iopl’:
/src/module/linux/syscalls.gen.x:481:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
/src/module/linux/syscalls.gen.x: In function ‘krf_sys_arch_prctl’:
/src/module/linux/syscalls.gen.x:1570:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

Have you ever seen anything similar?

woodruffw commented 4 years ago

Have you ever seen anything similar?

Not exactly, but some things that it could be:

layderv commented 4 years ago

Have you ever seen anything similar?

Not exactly, but some things that it could be:

* We might be missing an `#include` for the appropriate kernel header for those symbols

* You might be building on a version of the kernel that doesn't include those syscalls. In particular, `iopl(2)` is a 32-bit x86 thing and probably isn't implemented or exposed on 64-bit builds

You're right. If you know of a way to build for x86, I'd go with it; otherwise I will go for a new VM and use that instead

woodruffw commented 4 years ago

You're right. If you know of a way to build for x86, I'd go with it; otherwise I will go for a new VM and use that instead

Hmm, it's possible that KRF doesn't build at all with x86_32 -- it definitely makes assumptions about running on x86 in general, and I've only ever tested and used it on x86_64. I'd say it's okay to table x86_32-specific syscalls for now and focus on other ones; I'll create an issue to track general 32-bit support.

woodruffw commented 4 years ago

To be more explicit here: we should prioritize syscalls of interest like those in gVisor:

https://github.com/google/gvisor/blob/add40fd6ad4c136bc17d1f243ec199c7bf37fa0b/pkg/sentry/syscalls/linux/linux64.go