diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | honeypot.c | 41 | ||||
-rw-r--r-- | seccomp-bpf.h | 44 |
3 files changed, 82 insertions, 5 deletions
@@ -1 +1 @@ -honeypot: honeypot.c telnet.h +honeypot: honeypot.c telnet.h seccomp-bpf.h @@ -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 <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +#include <sys/prctl.h> + +#include <linux/unistd.h> +#include <linux/audit.h> +#include <linux/filter.h> +#include <linux/seccomp.h> + +#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) |