Безопасность компьютерных систем 2018/SECCOMP
Материал из Wiki - Факультет компьютерных наук
Версия от 15:17, 13 ноября 2018; Gamajun (обсуждение | вклад)
Содержание
Linux seccomp
Ссылки для изучения:
- Рекомендуемая основная презентация (пригодится для выполнения бонусного задания к заданию 3): http://events.linuxfoundation.org/sites/events/files/slides/limiting_kernel_attack_surface_with_seccomp-ContainerCon.eu_2016-Kerrisk.pdf
- https://eigenstate.org/notes/seccomp
- 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 */ }
}