From a3686893c77a0ebe37043a6a52504e077e9abd6b Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 17 Jan 2013 09:48:13 +0100 Subject: Use seccomp bpf filter. --- Makefile | 2 +- honeypot.c | 41 +++++++++++++++++++++++++++++++++++++---- seccomp-bpf.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 seccomp-bpf.h diff --git a/Makefile b/Makefile index 0b87cac..16a3197 100644 --- a/Makefile +++ b/Makefile @@ -1 +1 @@ -honeypot: honeypot.c telnet.h +honeypot: honeypot.c telnet.h seccomp-bpf.h diff --git a/honeypot.c b/honeypot.c index 02fc17a..7b5c768 100644 --- a/honeypot.c +++ b/honeypot.c @@ -64,6 +64,8 @@ * a protocol, and not just raw text transmission) */ #include "telnet.h" +#include "seccomp-bpf.h" + FILE *input = 0; FILE *output = 0; @@ -435,7 +437,36 @@ void drop_privileges() limit.rlim_cur = limit.rlim_max = 100; setrlimit(RLIMIT_NPROC, &limit); - prctl(PR_SET_NO_NEW_PRIVS, 1); + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { + perror("prctl(NO_NEW_PRIVS"); + exit(EXIT_FAILURE); + } +} + +void seccomp_enable_filter() +{ + struct sock_filter filter[] = { + VALIDATE_ARCHITECTURE, + EXAMINE_SYSCALL, + ALLOW_SYSCALL(rt_sigreturn), + ALLOW_SYSCALL(rt_sigprocmask), + ALLOW_SYSCALL(rt_sigaction), + ALLOW_SYSCALL(nanosleep), + ALLOW_SYSCALL(exit_group), + ALLOW_SYSCALL(exit), + ALLOW_SYSCALL(read), + ALLOW_SYSCALL(write), + ALLOW_SYSCALL(alarm), + KILL_PROCESS + }; + struct sock_fprog prog = { + .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), + .filter = filter + }; + if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { + perror("prctl(SECCOMP)"); + exit(EXIT_FAILURE); + } } void handle_connection(int fd, char *ipaddr) @@ -443,12 +474,12 @@ void handle_connection(int fd, char *ipaddr) char username[1024]; char password[1024]; struct rlimit limit; - + limit.rlim_cur = limit.rlim_max = 90; setrlimit(RLIMIT_CPU, &limit); limit.rlim_cur = limit.rlim_max = 0; setrlimit(RLIMIT_NPROC, &limit); - + input = fdopen(fd, "r"); if (!input) { perror("fdopen"); @@ -459,6 +490,8 @@ void handle_connection(int fd, char *ipaddr) perror("fdopen"); _exit(EXIT_FAILURE); } + + seccomp_enable_filter(); /* Set the alarm handler to quit on bad telnet clients. */ if (signal(SIGALRM, SIGALRM_handler) == SIG_ERR) { @@ -470,7 +503,7 @@ void handle_connection(int fd, char *ipaddr) perror("signal"); _exit(EXIT_FAILURE); } - + negotiate_telnet(); /* Quit after a minute and a half. */ diff --git a/seccomp-bpf.h b/seccomp-bpf.h new file mode 100644 index 0000000..f2a259c --- /dev/null +++ b/seccomp-bpf.h @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define syscall_nr (offsetof(struct seccomp_data, nr)) +#define arch_nr (offsetof(struct seccomp_data, arch)) + +#if defined(__i386__) +# define REG_SYSCALL REG_EAX +# define ARCH_NR AUDIT_ARCH_I386 +#elif defined(__x86_64__) +# define REG_SYSCALL REG_RAX +# define ARCH_NR AUDIT_ARCH_X86_64 +#else +# warning "Platform does not support seccomp filter yet" +# define REG_SYSCALL 0 +# define ARCH_NR 0 +#endif + +#define VALIDATE_ARCHITECTURE \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) + +#define EXAMINE_SYSCALL \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr) + +#define ALLOW_SYSCALL(name) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) + +#define KILL_PROCESS \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) -- cgit v1.2.3-59-g8ed1b