Безопасность компьютерных систем 2018/SECCOMP

Материал из Wiki - Факультет компьютерных наук
Перейти к: навигация, поиск

Linux seccomp

Ссылки для изучения:

  1. Рекомендуемая основная презентация (пригодится для выполнения бонусного задания к заданию 3): http://events.linuxfoundation.org/sites/events/files/slides/limiting_kernel_attack_surface_with_seccomp-ContainerCon.eu_2016-Kerrisk.pdf
  2. https://eigenstate.org/notes/seccomp
  3. Kafel - язык для конструирования политик seccomp (not an official Google product) https://github.com/google/kafel

Тестовый пример 1

 #include <stdio.h>
 #include <unistd.h>
 #include <linux/seccomp.h>
 #include <sys/prctl.h>
 int main () {
 pid_t pid;
 printf("Step 1: no restrictions yet\n");
 prctl (PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
 printf ("Step 2: entering the strict mode. Only read(), write(), exit() and sigreturn() syscalls    are allowed\n");
 pid = getpid ();
 printf ("!!YOU SHOULD NOT SEE THIS!! My PID = %d", pid);
 return 0;
 }

Тестовый пример 2

 #include <stdio.h>
 #include <seccomp.h>
 #include <unistd.h>
 #include <sys/fcntl.h>
 #include <errno.h>
 int main() {
   pid_t pid;
   scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_TRAP);
   seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
   seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
   seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0);
   seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
   printf ("No restrictions yet\n");
   seccomp_load(ctx);
   pid = getpid();
   printf("!! YOU SHOULD NOT SEE THIS!! My PID is%d\n", pid);
   return 0;
 }

Тестовый пример 3

 #include <stdlib.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/prctl.h>
 #include <sys/syscall.h>
 #include <sys/socket.h>
 #include <sys/fcntl.h>
 #include <linux/filter.h>
 #include <linux/seccomp.h>
 #include <linux/audit.h>
 #include <asm/unistd_64.h>
 static void install_filter ( void ) {
 struct sock_filter filter [] = {
 BPF_STMT ( BPF_LD | BPF_W | BPF_ABS ,
 ( offsetof ( struct seccomp_data , arch ))) ,
 BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K ,
 AUDIT_ARCH_X86_64 , 1 , 0) ,
 BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_KILL ) ,
 BPF_STMT ( BPF_LD | BPF_W | BPF_ABS ,
 ( offsetof ( struct seccomp_data , nr ))) ,
 BPF_JUMP ( BPF_JMP | BPF_JEQ | BPF_K , __NR_open ,
1 , 0) ,
 BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_ALLOW ) ,
 BPF_STMT ( BPF_RET | BPF_K , SECCOMP_RET_KILL )
 };
 struct sock_fprog prog = {
 .len = ( unsigned short ) ( sizeof ( filter ) /
 sizeof ( filter [0])) ,
 . filter = filter ,
 };
 syscall( __NR_seccomp , SECCOMP_SET_MODE_FILTER , 0 , & prog );
}
 int main (int argc , char ** argv ) {
  prctl ( PR_SET_NO_NEW_PRIVS , 1 , 0 , 0 , 0);
  install_filter ();
  open ( "/tmp/a" , O_RDONLY );
  printf ( "We shouldn ’t see this message \n" );
 exit ( EXIT_SUCCESS );
 }

Тестовый пример 4

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/socket.h>

#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/audit.h>

#define ArchField offsetof(struct seccomp_data, arch)

#define Allow(syscall) \
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_##syscall, 0, 1), \
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)

struct sock_filter filter[] = {
    /* validate arch */
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ArchField),
    BPF_JUMP( BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_X86_64, 1, 0),
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),

    /* load syscall */
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),

    /* list of allowed syscalls */
    Allow(exit_group),  /* exits a processs */
    Allow(brk),     /* for malloc(), inside libc */
    Allow(mmap),        /* also for malloc() */
    Allow(munmap),      /* for free(), inside libc */
    Allow(write),       /* called by printf */
    Allow(fstat),       /* called by printf */

    /* and if we don't match above, die */
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
};
struct sock_fprog filterprog = {
    .len = sizeof(filter)/sizeof(filter[0]),
    .filter = filter
};

int main(int argc, char **argv) {
    char buf[1024];

    /* set up the restricted environment */
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
        perror("Could not start seccomp:");
        exit(1);
    }
    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &filterprog) == -1) {
        perror("Could not start seccomp:");
        exit(1);
    }

    /* printf only writes to stdout, but for some reason it stats it. */
    printf("hello there!\n");

    if (argc > 1 && strcmp(argv[1], "haxor") == 0) {
        int fd = socket(AF_INET6, SOCK_STREAM, 0);
        /* ...and start sending spam */
    }
}