diff options
-rw-r--r-- | frida_mode/README.md | 2 | ||||
-rw-r--r-- | frida_mode/frida.map | 1 | ||||
-rw-r--r-- | frida_mode/include/seccomp.h | 359 | ||||
-rw-r--r-- | frida_mode/src/entry.c | 2 | ||||
-rw-r--r-- | frida_mode/src/js/api.js | 9 | ||||
-rw-r--r-- | frida_mode/src/js/js_api.c | 8 | ||||
-rw-r--r-- | frida_mode/src/main.c | 3 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp.c | 157 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp_atomic.c | 28 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp_child.c | 69 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp_event.c | 45 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp_filter.c | 258 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp_socket.c | 121 | ||||
-rw-r--r-- | frida_mode/src/seccomp/seccomp_syscall.c | 335 | ||||
-rw-r--r-- | frida_mode/ts/lib/afl.ts | 14 |
15 files changed, 1411 insertions, 0 deletions
diff --git a/frida_mode/README.md b/frida_mode/README.md index 45d90ceb..165f8089 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -197,6 +197,8 @@ gdb \ --args <my-executable> [my arguments] ``` +* `AFL_FRIDA_SECCOMP_FILE` - Write a log of any syscalls made by the target to +the specified file. * `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries stored along-side branch instructions which provide a cache to avoid having to call back into FRIDA to find the next block. Default is 32. diff --git a/frida_mode/frida.map b/frida_mode/frida.map index e753570f..0fc48aa6 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -26,6 +26,7 @@ js_api_set_persistent_return; js_api_set_prefetch_backpatch_disable; js_api_set_prefetch_disable; + js_api_set_seccomp_file; js_api_set_stalker_callback; js_api_set_stalker_ic_entries; js_api_set_stats_file; diff --git a/frida_mode/include/seccomp.h b/frida_mode/include/seccomp.h new file mode 100644 index 00000000..2c037ff7 --- /dev/null +++ b/frida_mode/include/seccomp.h @@ -0,0 +1,359 @@ +#ifndef _SECCOMP_H +#define _SECCOMP_H + +#include <linux/seccomp.h> + +#include "frida-gumjs.h" + +#define SECCOMP_SOCKET_SEND_FD 0x1D3 +#define SECCOMP_SOCKET_RECV_FD 0x1D4 + +#define SECCOMP_OUTPUT_FILE_FD 0x1D5 +#define SECCOMP_PARENT_EVENT_FD 0x1D6 + +enum { + + SYS_READ = 0, + SYS_WRITE = 1, + SYS_OPEN = 2, + SYS_CLOSE = 3, + SYS_STAT = 4, + SYS_FSTAT = 5, + SYS_LSTAT = 6, + SYS_POLL = 7, + SYS_LSEEK = 8, + SYS_MMAP = 9, + SYS_MPROTECT = 10, + SYS_MUNMAP = 11, + SYS_BRK = 12, + SYS_RT_SIGACTION = 13, + SYS_RT_SIGPROCMASK = 14, + SYS_RT_SIGRETURN = 15, + SYS_IOCTL = 16, + SYS_PREAD64 = 17, + SYS_PWRITE64 = 18, + SYS_READV = 19, + SYS_WRITEV = 20, + SYS_ACCESS = 21, + SYS_PIPE = 22, + SYS_SELECT = 23, + SYS_SCHED_YIELD = 24, + SYS_MREMAP = 25, + SYS_MSYNC = 26, + SYS_MINCORE = 27, + SYS_MADVISE = 28, + SYS_SHMGET = 29, + SYS_SHMAT = 30, + SYS_SHMCTL = 31, + SYS_DUP = 32, + SYS_DUP2 = 33, + SYS_PAUSE = 34, + SYS_NANOSLEEP = 35, + SYS_GETITIMER = 36, + SYS_ALARM = 37, + SYS_SETITIMER = 38, + SYS_GETPID = 39, + SYS_SENDFILE = 40, + SYS_SOCKET = 41, + SYS_CONNECT = 42, + SYS_ACCEPT = 43, + SYS_SENDTO = 44, + SYS_RECVFROM = 45, + SYS_SENDMSG = 46, + SYS_RECVMSG = 47, + SYS_SHUTDOWN = 48, + SYS_BIND = 49, + SYS_LISTEN = 50, + SYS_GETSOCKNAME = 51, + SYS_GETPEERNAME = 52, + SYS_SOCKETPAIR = 53, + SYS_SETSOCKOPT = 54, + SYS_GETSOCKOPT = 55, + SYS_CLONE = 56, + SYS_FORK = 57, + SYS_VFORK = 58, + SYS_EXECVE = 59, + SYS_EXIT = 60, + SYS_WAIT4 = 61, + SYS_KILL = 62, + SYS_UNAME = 63, + SYS_SEMGET = 64, + SYS_SEMOP = 65, + SYS_SEMCTL = 66, + SYS_SHMDT = 67, + SYS_MSGGET = 68, + SYS_MSGSND = 69, + SYS_MSGRCV = 70, + SYS_MSGCTL = 71, + SYS_FCNTL = 72, + SYS_FLOCK = 73, + SYS_FSYNC = 74, + SYS_FDATASYNC = 75, + SYS_TRUNCATE = 76, + SYS_FTRUNCATE = 77, + SYS_GETDENTS = 78, + SYS_GETCWD = 79, + SYS_CHDIR = 80, + SYS_FCHDIR = 81, + SYS_RENAME = 82, + SYS_MKDIR = 83, + SYS_RMDIR = 84, + SYS_CREAT = 85, + SYS_LINK = 86, + SYS_UNLINK = 87, + SYS_SYMLINK = 88, + SYS_READLINK = 89, + SYS_CHMOD = 90, + SYS_FCHMOD = 91, + SYS_CHOWN = 92, + SYS_FCHOWN = 93, + SYS_LCHOWN = 94, + SYS_UMASK = 95, + SYS_GETTIMEOFDAY = 96, + SYS_GETRLIMIT = 97, + SYS_GETRUSAGE = 98, + SYS_SYSINFO = 99, + SYS_TIMES = 100, + SYS_PTRACE = 101, + SYS_GETUID = 102, + SYS_SYSLOG = 103, + SYS_GETGID = 104, + SYS_SETUID = 105, + SYS_SETGID = 106, + SYS_GETEUID = 107, + SYS_GETEGID = 108, + SYS_SETPGID = 109, + SYS_GETPPID = 110, + SYS_GETPGRP = 111, + SYS_SETSID = 112, + SYS_SETREUID = 113, + SYS_SETREGID = 114, + SYS_GETGROUPS = 115, + SYS_SETGROUPS = 116, + SYS_SETRESUID = 117, + SYS_GETRESUID = 118, + SYS_SETRESGID = 119, + SYS_GETRESGID = 120, + SYS_GETPGID = 121, + SYS_SETFSUID = 122, + SYS_SETFSGID = 123, + SYS_GETSID = 124, + SYS_CAPGET = 125, + SYS_CAPSET = 126, + SYS_RT_SIGPENDING = 127, + SYS_RT_SIGTIMEDWAIT = 128, + SYS_RT_SIGQUEUEINFO = 129, + SYS_RT_SIGSUSPEND = 130, + SYS_SIGALTSTACK = 131, + SYS_UTIME = 132, + SYS_MKNOD = 133, + SYS_USELIB = 134, + SYS_PERSONALITY = 135, + SYS_USTAT = 136, + SYS_STATFS = 137, + SYS_FSTATFS = 138, + SYS_SYSFS = 139, + SYS_GETPRIORITY = 140, + SYS_SETPRIORITY = 141, + SYS_SCHED_SETPARAM = 142, + SYS_SCHED_GETPARAM = 143, + SYS_SCHED_SETSCHEDULER = 144, + SYS_SCHED_GETSCHEDULER = 145, + SYS_SCHED_GET_PRIORITY_MAX = 146, + SYS_SCHED_GET_PRIORITY_MIN = 147, + SYS_SCHED_RR_GET_INTERVAL = 148, + SYS_MLOCK = 149, + SYS_MUNLOCK = 150, + SYS_MLOCKALL = 151, + SYS_MUNLOCKALL = 152, + SYS_VHANGUP = 153, + SYS_MODIFY_LDT = 154, + SYS_PIVOT_ROOT = 155, + SYS__SYSCTL = 156, + SYS_PRCTL = 157, + SYS_ARCH_PRCTL = 158, + SYS_ADJTIMEX = 159, + SYS_SETRLIMIT = 160, + SYS_CHROOT = 161, + SYS_SYNC = 162, + SYS_ACCT = 163, + SYS_SETTIMEOFDAY = 164, + SYS_MOUNT = 165, + SYS_UMOUNT2 = 166, + SYS_SWAPON = 167, + SYS_SWAPOFF = 168, + SYS_REBOOT = 169, + SYS_SETHOSTNAME = 170, + SYS_SETDOMAINNAME = 171, + SYS_IOPL = 172, + SYS_IOPERM = 173, + SYS_CREATE_MODULE = 174, + SYS_INIT_MODULE = 175, + SYS_DELETE_MODULE = 176, + SYS_GET_KERNEL_SYMS = 177, + SYS_QUERY_MODULE = 178, + SYS_QUOTACTL = 179, + SYS_NFSSERVCTL = 180, + SYS_GETPMSG = 181, + SYS_PUTPMSG = 182, + SYS_AFS_SYSCALL = 183, + SYS_TUXCALL = 184, + SYS_SECURITY = 185, + SYS_GETTID = 186, + SYS_READAHEAD = 187, + SYS_SETXATTR = 188, + SYS_LSETXATTR = 189, + SYS_FSETXATTR = 190, + SYS_GETXATTR = 191, + SYS_LGETXATTR = 192, + SYS_FGETXATTR = 193, + SYS_LISTXATTR = 194, + SYS_LLISTXATTR = 195, + SYS_FLISTXATTR = 196, + SYS_REMOVEXATTR = 197, + SYS_LREMOVEXATTR = 198, + SYS_FREMOVEXATTR = 199, + SYS_TKILL = 200, + SYS_TIME = 201, + SYS_FUTEX = 202, + SYS_SCHED_SETAFFINITY = 203, + SYS_SCHED_GETAFFINITY = 204, + SYS_SET_THREAD_AREA = 205, + SYS_IO_SETUP = 206, + SYS_IO_DESTROY = 207, + SYS_IO_GETEVENTS = 208, + SYS_IO_SUBMIT = 209, + SYS_IO_CANCEL = 210, + SYS_GET_THREAD_AREA = 211, + SYS_LOOKUP_DCOOKIE = 212, + SYS_EPOLL_CREATE = 213, + SYS_EPOLL_CTL_OLD = 214, + SYS_EPOLL_WAIT_OLD = 215, + SYS_REMAP_FILE_PAGES = 216, + SYS_GETDENTS64 = 217, + SYS_SET_TID_ADDRESS = 218, + SYS_RESTART_SYSCALL = 219, + SYS_SEMTIMEDOP = 220, + SYS_FADVISE64 = 221, + SYS_TIMER_CREATE = 222, + SYS_TIMER_SETTIME = 223, + SYS_TIMER_GETTIME = 224, + SYS_TIMER_GETOVERRUN = 225, + SYS_TIMER_DELETE = 226, + SYS_CLOCK_SETTIME = 227, + SYS_CLOCK_GETTIME = 228, + SYS_CLOCK_GETRES = 229, + SYS_CLOCK_NANOSLEEP = 230, + SYS_EXIT_GROUP = 231, + SYS_EPOLL_WAIT = 232, + SYS_EPOLL_CTL = 233, + SYS_TGKILL = 234, + SYS_UTIMES = 235, + SYS_VSERVER = 236, + SYS_MBIND = 237, + SYS_SET_MEMPOLICY = 238, + SYS_GET_MEMPOLICY = 239, + SYS_MQ_OPEN = 240, + SYS_MQ_UNLINK = 241, + SYS_MQ_TIMEDSEND = 242, + SYS_MQ_TIMEDRECEIVE = 243, + SYS_MQ_NOTIFY = 244, + SYS_MQ_GETSETATTR = 245, + SYS_KEXEC_LOAD = 246, + SYS_WAITID = 247, + SYS_ADD_KEY = 248, + SYS_REQUEST_KEY = 249, + SYS_KEYCTL = 250, + SYS_IOPRIO_SET = 251, + SYS_IOPRIO_GET = 252, + SYS_INOTIFY_INIT = 253, + SYS_INOTIFY_ADD_WATCH = 254, + SYS_INOTIFY_RM_WATCH = 255, + SYS_MIGRATE_PAGES = 256, + SYS_OPENAT = 257, + SYS_MKDIRAT = 258, + SYS_MKNODAT = 259, + SYS_FCHOWNAT = 260, + SYS_FUTIMESAT = 261, + SYS_NEWFSTATAT = 262, + SYS_UNLINKAT = 263, + SYS_RENAMEAT = 264, + SYS_LINKAT = 265, + SYS_SYMLINKAT = 266, + SYS_READLINKAT = 267, + SYS_FCHMODAT = 268, + SYS_FACCESSAT = 269, + SYS_PSELECT6 = 270, + SYS_PPOLL = 271, + SYS_UNSHARE = 272, + SYS_SET_ROBUST_LIST = 273, + SYS_GET_ROBUST_LIST = 274, + SYS_SPLICE = 275, + SYS_TEE = 276, + SYS_SYNC_FILE_RANGE = 277, + SYS_VMSPLICE = 278, + SYS_MOVE_PAGES = 279, + SYS_UTIMENSAT = 280, + SYS_EPOLL_PWAIT = 281, + SYS_SIGNALFD = 282, + SYS_TIMERFD_CREATE = 283, + SYS_EVENTFD = 284, + SYS_FALLOCATE = 285, + SYS_TIMERFD_SETTIME = 286, + SYS_TIMERFD_GETTIME = 287, + SYS_ACCEPT4 = 288, + SYS_SIGNALFD4 = 289, + SYS_EVENTFD2 = 290, + SYS_EPOLL_CREATE1 = 291, + SYS_DUP3 = 292, + SYS_PIPE2 = 293, + SYS_INOTIFY_INIT1 = 294, + SYS_PREADV = 295, + SYS_PWRITEV = 296, + SYS_RT_TGSIGQUEUEINFO = 297, + SYS_PERF_EVENT_OPEN = 298, + SYS_RECVMMSG = 299, + SYS_FANOTIFY_INIT = 300, + SYS_FANOTIFY_MARK = 301, + SYS_PRLIMIT64 = 302 + +}; + +extern char *seccomp_filename; + +typedef void (*seccomp_child_func_t)(int event_fd, void *ctx); + +typedef void (*seccomp_filter_callback_t)(struct seccomp_notif * req, + struct seccomp_notif_resp *resp, + GumReturnAddressArray * frames); + +void seccomp_config(void); +void seccomp_init(void); +void seccomp_on_fork(void); +void seccomp_print(char *format, ...); + +void seccomp_atomic_set(volatile bool *ptr, bool val); +bool seccomp_atomic_try_set(volatile bool *ptr, bool val); +void seccomp_atomic_wait(volatile bool *ptr, bool val); + +void seccomp_child_run(seccomp_child_func_t child_func, void *ctx, pid_t *child, + int *event_fd); +void seccomp_child_wait(int event_fd); + +int seccomp_event_create(void); +void seccomp_event_signal(int fd); +void seccomp_event_wait(int fd); +void seccomp_event_destroy(int fd); + +int seccomp_filter_install(pid_t child); +void seccomp_filter_child_install(void); +void seccomp_filter_run(int fd, seccomp_filter_callback_t callback); + +void seccomp_socket_create(int *sock); +void seccomp_socket_send(int sockfd, int fd); +int seccomp_socket_recv(int sockfd); + +char *seccomp_syscall_lookup(int id); + +#endif + diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c index 3ec8f5be..186ddd3a 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -8,6 +8,7 @@ #include "instrument.h" #include "persistent.h" #include "ranges.h" +#include "seccomp.h" #include "stalker.h" #include "stats.h" #include "util.h" @@ -26,6 +27,7 @@ static void entry_launch(void) { /* Child here */ entry_run = TRUE; instrument_on_fork(); + seccomp_on_fork(); stats_on_fork(); } diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index cf422ba9..40bb4a16 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -191,6 +191,14 @@ class Afl { static setPrefetchDisable() { Afl.jsApiSetPrefetchDisable(); } + /** + * See `AFL_FRIDA_SECCOMP_FILE`. This function takes a single `string` as + * an argument. + */ + static setSeccompFile(file) { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetSeccompFile(buf); + } /* * Set a function to be called for each instruction which is instrumented * by AFL FRIDA mode. @@ -271,6 +279,7 @@ Afl.jsApiSetPersistentHook = Afl.jsApiGetFunction("js_api_set_persistent_hook", Afl.jsApiSetPersistentReturn = Afl.jsApiGetFunction("js_api_set_persistent_return", "void", ["pointer"]); Afl.jsApiSetPrefetchBackpatchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_backpatch_disable", "void", []); Afl.jsApiSetPrefetchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_disable", "void", []); +Afl.jsApiSetSeccompFile = Afl.jsApiGetFunction("js_api_set_seccomp_file", "void", ["pointer"]); Afl.jsApiSetStalkerCallback = Afl.jsApiGetFunction("js_api_set_stalker_callback", "void", ["pointer"]); Afl.jsApiSetStalkerIcEntries = Afl.jsApiGetFunction("js_api_set_stalker_ic_entries", "void", ["uint32"]); Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["pointer"]); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 49ca3baa..9dba79aa 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -7,6 +7,7 @@ #include "persistent.h" #include "prefetch.h" #include "ranges.h" +#include "seccomp.h" #include "stalker.h" #include "stats.h" #include "util.h" @@ -171,6 +172,13 @@ js_api_set_instrument_unstable_coverage_file(char *path) { } +__attribute__((visibility("default"))) void js_api_set_seccomp_file( + char *file) { + + seccomp_filename = g_strdup(file); + +} + __attribute__((visibility("default"))) void js_api_set_stdout(char *file) { output_stdout = g_strdup(file); diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index 91687046..c0de9c6b 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -25,6 +25,7 @@ #include "persistent.h" #include "prefetch.h" #include "ranges.h" +#include "seccomp.h" #include "stalker.h" #include "stats.h" #include "util.h" @@ -177,6 +178,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) { persistent_config(); prefetch_config(); ranges_config(); + seccomp_config(); stalker_config(); stats_config(); @@ -191,6 +193,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) { lib_init(); persistent_init(); prefetch_init(); + seccomp_init(); stalker_init(); ranges_init(); stats_init(); diff --git a/frida_mode/src/seccomp/seccomp.c b/frida_mode/src/seccomp/seccomp.c new file mode 100644 index 00000000..7683cd71 --- /dev/null +++ b/frida_mode/src/seccomp/seccomp.c @@ -0,0 +1,157 @@ +#include <execinfo.h> +#include <fcntl.h> +#include <linux/seccomp.h> +#include <stdio.h> +#include <unistd.h> + +#include "frida-gumjs.h" + +#include "debug.h" + +#include "seccomp.h" +#include "util.h" + +char *seccomp_filename = NULL; + +static void seccomp_vprint(int fd, char *format, va_list ap) { + + char buffer[4096] = {0}; + int len; + + if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; } + + len = strnlen(buffer, sizeof(buffer)); + IGNORED_RETURN(write(fd, buffer, len)); + +} + +void seccomp_print(char *format, ...) { + + va_list ap; + va_start(ap, format); + seccomp_vprint(SECCOMP_OUTPUT_FILE_FD, format, ap); + va_end(ap); + +} + +static void seccomp_filter_callback(struct seccomp_notif * req, + struct seccomp_notif_resp *resp, + GumReturnAddressArray * frames) { + + GumDebugSymbolDetails details = {0}; + if (req->data.nr == SYS_OPENAT) { + + seccomp_print("SYS_OPENAT: (%s)\n", (char *)req->data.args[1]); + + } + + seccomp_print( + "\nID (%#llx) for PID %d - %d (%s) [0x%llx 0x%llx 0x%llx 0x%llx 0x%llx " + "0x%llx ]\n", + req->id, req->pid, req->data.nr, seccomp_syscall_lookup(req->data.nr), + req->data.args[0], req->data.args[1], req->data.args[2], + req->data.args[3], req->data.args[4], req->data.args[5]); + + seccomp_print("FRAMES: (%u)\n", frames->len); + char **syms = backtrace_symbols(frames->items, frames->len); + if (syms == NULL) { FATAL("Failed to get symbols"); } + + for (guint i = 0; i < frames->len; i++) { + + if (gum_symbol_details_from_address(frames->items[i], &details)) { + + seccomp_print("\t%3d. %s!%s\n", i, details.module_name, + details.symbol_name); + + } else { + + seccomp_print("\t%3d. %s\n", i, syms[i]); + + } + + } + + free(syms); + + resp->error = 0; + resp->val = 0; + resp->id = req->id; + resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; + +} + +static void seccomp_child(int signal_parent, void *ctx) { + + int sock_fd = *((int *)ctx); + int fd = seccomp_socket_recv(sock_fd); + + if (close(sock_fd) < 0) { FATAL("child - close"); } + + seccomp_event_signal(signal_parent); + seccomp_filter_child_install(); + seccomp_filter_run(fd, seccomp_filter_callback); + +} + +void seccomp_on_fork(void) { + + int sock[2] = {-1, -1}; + pid_t child = -1; + int child_fd = -1; + + if (seccomp_filename == NULL) { return; } + + seccomp_socket_create(sock); + seccomp_child_run(seccomp_child, sock, &child, &child_fd); + + if (dup2(child_fd, SECCOMP_PARENT_EVENT_FD) < 0) { FATAL("dup2"); } + + if (close(child_fd) < 0) { FATAL("seccomp_on_fork - close (1)"); } + + if (close(sock[STDIN_FILENO]) < 0) { FATAL("grandparent - close (2)"); } + + int fd = seccomp_filter_install(child); + seccomp_socket_send(sock[STDOUT_FILENO], fd); + + if (close(sock[STDOUT_FILENO]) < 0) { FATAL("grandparent - close (3)"); } + + if (close(fd) < 0) { FATAL("grandparent - close (4)"); } + + seccomp_child_wait(SECCOMP_PARENT_EVENT_FD); + +} + +void seccomp_config(void) { + + seccomp_filename = getenv("AFL_FRIDA_SECCOMP_FILE"); + +} + +void seccomp_init(void) { + + char *path = NULL; + int fd; + + OKF("Seccomp - file [%s]", seccomp_filename); + + if (seccomp_filename == NULL) { return; } + + path = g_canonicalize_filename(seccomp_filename, g_get_current_dir()); + + OKF("Seccomp - path [%s]", path); + + fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + if (dup2(fd, SECCOMP_OUTPUT_FILE_FD) < 0) { + + FATAL("Failed to duplicate seccomp output file"); + + } + + if (close(fd) < 0) { FATAL("Failed to close seccomp output file fd"); } + + g_free(path); + +} + diff --git a/frida_mode/src/seccomp/seccomp_atomic.c b/frida_mode/src/seccomp/seccomp_atomic.c new file mode 100644 index 00000000..1720a726 --- /dev/null +++ b/frida_mode/src/seccomp/seccomp_atomic.c @@ -0,0 +1,28 @@ +#include <stdbool.h> +#include <stdio.h> + +#include "debug.h" + +void seccomp_atomic_set(volatile bool *ptr, bool val) { + + if (!__sync_bool_compare_and_swap(ptr, !val, val)) { + + FATAL("Failed to set event"); + + } + +} + +bool seccomp_atomic_try_set(volatile bool *ptr, bool val) { + + return __sync_bool_compare_and_swap(ptr, !val, val); + +} + +void seccomp_atomic_wait(volatile bool *ptr, bool val) { + + while (!__sync_bool_compare_and_swap(ptr, val, !val)) + ; + +} + diff --git a/frida_mode/src/seccomp/seccomp_child.c b/frida_mode/src/seccomp/seccomp_child.c new file mode 100644 index 00000000..4d494137 --- /dev/null +++ b/frida_mode/src/seccomp/seccomp_child.c @@ -0,0 +1,69 @@ +#include <fcntl.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/prctl.h> +#include <sys/types.h> +#include <unistd.h> + +#include "debug.h" + +#include "seccomp.h" + +#define SECCOMP_CHILD_STACK_SIZE (1UL << 20) + +typedef void (*seccomp_child_func_t)(int event_fd, void *ctx); + +typedef struct { + + seccomp_child_func_t func; + int event_fd; + void * ctx; + +} seccomp_child_func_ctx_t; + +static int seccomp_child_func(void *ctx) { + + seccomp_child_func_ctx_t *args = (seccomp_child_func_ctx_t *)ctx; + args->func(args->event_fd, args->ctx); + _exit(0); + return 0; + +} + +void seccomp_child_run(seccomp_child_func_t child_func, void *ctx, pid_t *child, + int *event_fd) { + + int fd = seccomp_event_create(); + + seccomp_child_func_ctx_t *child_ctx = + malloc(sizeof(seccomp_child_func_ctx_t)); + child_ctx->func = child_func; + child_ctx->ctx = ctx; + child_ctx->event_fd = fd; + + int flags = CLONE_VM | CLONE_UNTRACED; + + char *stack = + (char *)mmap(NULL, SECCOMP_CHILD_STACK_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (stack == MAP_FAILED) { FATAL("mmap"); } + + pid_t child_pid = clone(seccomp_child_func, &stack[SECCOMP_CHILD_STACK_SIZE], + flags, child_ctx, NULL, NULL, NULL); + if (child_pid < 0) { FATAL("clone"); } + + if (child != NULL) { *child = child_pid; } + if (event_fd != NULL) { *event_fd = fd; } + +} + +void seccomp_child_wait(int event_fd) { + + seccomp_event_wait(event_fd); + seccomp_event_destroy(event_fd); + +} + diff --git a/frida_mode/src/seccomp/seccomp_event.c b/frida_mode/src/seccomp/seccomp_event.c new file mode 100644 index 00000000..ecb9be32 --- /dev/null +++ b/frida_mode/src/seccomp/seccomp_event.c @@ -0,0 +1,45 @@ +#include <stdint.h> +#include <stdio.h> +#include <sys/eventfd.h> +#include <unistd.h> + +#include "debug.h" + +#include "seccomp.h" + +int seccomp_event_create(void) { + + int fd = eventfd(0, 0); + if (fd < 0) { FATAL("seccomp_event_create"); } + return fd; + +} + +void seccomp_event_signal(int fd) { + + uint64_t val = 1; + if (write(fd, &val, sizeof(uint64_t)) != sizeof(uint64_t)) { + + FATAL("seccomp_event_signal"); + + } + +} + +void seccomp_event_wait(int fd) { + + uint64_t val = 1; + if (read(fd, &val, sizeof(uint64_t)) != sizeof(uint64_t)) { + + FATAL("seccomp_event_wait"); + + } + +} + +void seccomp_event_destroy(int fd) { + + if (close(fd) < 0) { FATAL("seccomp_event_destroy"); } + +} + diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c new file mode 100644 index 00000000..c16e7ebd --- /dev/null +++ b/frida_mode/src/seccomp/seccomp_filter.c @@ -0,0 +1,258 @@ +#include <alloca.h> +#include <errno.h> +#include <execinfo.h> +#include <linux/filter.h> +#include <linux/seccomp.h> +#include <sys/ioctl.h> +#include <sys/prctl.h> +#include <sys/syscall.h> +#include <signal.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "debug.h" + +#include "frida-gumjs.h" + +#include "seccomp.h" +#include "util.h" + +#define SECCOMP_FILTER_NUM_FRAMES 512 + +extern void gum_linux_parse_ucontext(const ucontext_t *uc, GumCpuContext *ctx); + +static struct sock_filter filter[] = { + + /* Allow us sendmsg to SECCOMP_FD */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_sendmsg, 0, 3), + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, + (offsetof(struct seccomp_data, args[0]))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_SOCKET_SEND_FD, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow close */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_close, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow sigreturn */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rt_sigreturn, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow sigprocmaksk */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rt_sigprocmask, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow console output*/ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_lseek, 2, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_fstat, 1, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_write, 0, 4), + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, + (offsetof(struct seccomp_data, args[0]))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, STDERR_FILENO, 1, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, STDOUT_FILENO, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow waiting for the child */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_read, 0, 3), + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, + (offsetof(struct seccomp_data, args[0]))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_PARENT_EVENT_FD, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow us to make anonymous maps */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mmap, 0, 3), + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, + (offsetof(struct seccomp_data, args[4]))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, -1, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow msync/mincore used by cmplog */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_msync, 1, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mincore, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* + * Allow tgkill (SIGKILL, SIGSTOP) used in persistent mode. Also + * allow seccomp to send (SIGUSR1) to the child to collect trace. + */ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_tgkill, 0, 5), + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, + (offsetof(struct seccomp_data, args[2]))), + /* Used by seccomp to signal the child to collect a callstack*/ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SIGUSR1, 2, 0), + /* Used when handling faults */ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SIGKILL, 1, 0), + /* Used by target app of interest */ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SIGSTOP, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow getpid / gettid */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getpid, 1, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_gettid, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow exit_group */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_exit_group, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Allow brk */ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_brk, 0, 1), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), + + /* Send the rest to user-mode to filter */ + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_USER_NOTIF)}; + +static volatile bool seccomp_filter_parent_done = false; +static volatile bool seccomp_filter_child_done = false; +static pid_t seccomp_filter_child = -1; +static GumCpuContext seccomp_filter_cpu_context = {0}; +static GumReturnAddressArray seccomp_filter_frames = {.len = 0, .items = {0}}; +static GumBacktracer * seccomp_filter_backtracer = NULL; + +static void seccomp_filter_child_handler(int sig, siginfo_t *info, + void *ucontext) { + + GumCpuContext cpu_context; + if (seccomp_filter_backtracer == NULL) { + + seccomp_filter_backtracer = gum_backtracer_make_fuzzy(); + + } + + gum_backtracer_generate(seccomp_filter_backtracer, + &seccomp_filter_cpu_context, &seccomp_filter_frames); + + seccomp_atomic_set(&seccomp_filter_child_done, true); + +} + +static void seccomp_filter_parent_handler(int sig, siginfo_t *info, + void *ucontext) { + + UNUSED_PARAMETER(sig); + UNUSED_PARAMETER(info); + + ucontext_t *uc = (ucontext_t *)ucontext; + gum_linux_parse_ucontext(uc, &seccomp_filter_cpu_context); + + if (tgkill(seccomp_filter_child, seccomp_filter_child, SIGUSR1) < 0) { + + FATAL("kill"); + + } + + seccomp_atomic_wait(&seccomp_filter_child_done, true); + seccomp_atomic_set(&seccomp_filter_parent_done, true); + +} + +void seccomp_filter_child_install(void) { + + const struct sigaction sa = {.sa_sigaction = seccomp_filter_child_handler, + .sa_flags = SA_SIGINFO | SA_RESTART}; + if (sigaction(SIGUSR1, &sa, NULL) < 0) { FATAL("sigaction"); } + +} + +int seccomp_filter_install(pid_t child) { + + seccomp_filter_child = child; + + const struct sigaction sa = {.sa_sigaction = seccomp_filter_parent_handler, + .sa_flags = SA_SIGINFO | SA_RESTART}; + + struct sock_fprog filter_prog = { + + .len = sizeof(filter) / sizeof(struct sock_filter), .filter = filter}; + + if (sigaction(SIGUSR1, &sa, NULL) < 0) { FATAL("sigaction"); } + + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { + + FATAL("PR_SET_NO_NEW_PRIVS %d", errno); + + } + + int fd = syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, + SECCOMP_FILTER_FLAG_NEW_LISTENER, &filter_prog); + if (fd < 0) { FATAL("SYS_seccomp %d", fd); } + + return fd; + +} + +void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) { + + struct seccomp_notif * req = NULL; + struct seccomp_notif_resp *resp = NULL; + struct seccomp_notif_sizes sizes; + + if (syscall(SYS_seccomp, SECCOMP_GET_NOTIF_SIZES, 0, &sizes) == -1) { + + FATAL("seccomp-SECCOMP_GET_NOTIF_SIZES"); + + } + + if (sizes.seccomp_notif != sizeof(struct seccomp_notif)) { + + FATAL("size - seccomp_notif"); + + } + + if (sizes.seccomp_notif_resp != sizeof(struct seccomp_notif_resp)) { + + FATAL("size - seccomp_notif"); + + } + + req = alloca(sizes.seccomp_notif); + resp = alloca(sizes.seccomp_notif_resp); + + while (true) { + + memset(req, 0, sizes.seccomp_notif); + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0) { + + if (errno == EINTR) { continue; } + FATAL("SECCOMP_IOCTL_NOTIF_RECV: %d\n", fd); + + } + + if (seccomp_atomic_try_set(&seccomp_filter_parent_done, false)) { + + callback(req, resp, &seccomp_filter_frames); + + } else { + + if (kill(req->pid, SIGUSR1) < 0) { FATAL("kill"); } + + } + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0) { + + if (errno == ENOENT) { continue; } + OKF("SECCOMP_IOCTL_NOTIF_SEND"); + continue; + + } + + } + +} + diff --git a/frida_mode/src/seccomp/seccomp_socket.c b/frida_mode/src/seccomp/seccomp_socket.c new file mode 100644 index 00000000..ca42e158 --- /dev/null +++ b/frida_mode/src/seccomp/seccomp_socket.c @@ -0,0 +1,121 @@ +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> +#include <unistd.h> + +#include "debug.h" + +#include "seccomp.h" + +union cmsg { + + char buf[CMSG_SPACE(sizeof(int))]; + struct cmsghdr hdr; + +}; + +void seccomp_socket_create(int *sock) { + + int tmp_sock[2] = {-1, -1}; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, tmp_sock) < 0) { + + FATAL("socketpair"); + + } + + if (dup2(tmp_sock[STDIN_FILENO], SECCOMP_SOCKET_RECV_FD) < 0) { + + FATAL("seccomp_socket_create - dup2 (1)"); + + } + + if (dup2(tmp_sock[STDOUT_FILENO], SECCOMP_SOCKET_SEND_FD) < 0) { + + FATAL("seccomp_socket_create - dup2 (1)"); + + } + + if (close(tmp_sock[STDIN_FILENO]) < 0) { + + FATAL("seccomp_socket_create - close (1)"); + + } + + if (close(tmp_sock[STDOUT_FILENO]) < 0) { + + FATAL("seccomp_socket_create - close (2)"); + + } + + sock[STDIN_FILENO] = SECCOMP_SOCKET_RECV_FD; + sock[STDOUT_FILENO] = SECCOMP_SOCKET_SEND_FD; + +} + +void seccomp_socket_send(int sockfd, int fd) { + + int data = 12345; + struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)}; + union cmsg control_msg = {.hdr = { + + .cmsg_len = CMSG_LEN(sizeof(int)), + .cmsg_level = SOL_SOCKET, + .cmsg_type = SCM_RIGHTS, + + }}; + + struct msghdr message = {.msg_control = control_msg.buf, + .msg_controllen = sizeof(control_msg.buf), + .msg_flags = 0, + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_name = NULL, + .msg_namelen = 0}; + + memcpy(CMSG_DATA(&control_msg.hdr), &fd, sizeof(int)); + + if (sendmsg(sockfd, &message, 0) == -1) { FATAL("sendmsg"); } + +} + +int seccomp_socket_recv(int sockfd) { + + int data; + struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)}; + union cmsg control_msg = {0}; + struct msghdr message = {.msg_control = control_msg.buf, + .msg_controllen = sizeof(control_msg.buf), + .msg_flags = 0, + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_name = NULL, + .msg_namelen = 0}; + + int fd; + + if (recvmsg(sockfd, &message, 0) < 0) { FATAL("recvmsg"); } + + if (control_msg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) { + + FATAL("control_msg.hdr.cmsg_len"); + + } + + if (control_msg.hdr.cmsg_level != SOL_SOCKET) { + + FATAL("control_msg.hdr.cmsg_level"); + + } + + if (control_msg.hdr.cmsg_type != SCM_RIGHTS) { + + FATAL("control_msg.hdr.cmsg_type"); + + } + + memcpy(&fd, CMSG_DATA(&control_msg.hdr), sizeof(int)); + + return fd; + +} + diff --git a/frida_mode/src/seccomp/seccomp_syscall.c b/frida_mode/src/seccomp/seccomp_syscall.c new file mode 100644 index 00000000..b2c084c8 --- /dev/null +++ b/frida_mode/src/seccomp/seccomp_syscall.c @@ -0,0 +1,335 @@ +#include <limits.h> +#include <stdio.h> + +#include "debug.h" + +#include "seccomp.h" + +typedef struct { + + int id; + char name[PATH_MAX]; + +} syscall_entry_t; + +static syscall_entry_t seccomp_syscall_table[] = { + + {SYS_READ, "SYS_READ"}, + {SYS_WRITE, "SYS_WRITE"}, + {SYS_OPEN, "SYS_OPEN"}, + {SYS_CLOSE, "SYS_CLOSE"}, + {SYS_STAT, "SYS_STAT"}, + {SYS_FSTAT, "SYS_FSTAT"}, + {SYS_LSTAT, "SYS_LSTAT"}, + {SYS_POLL, "SYS_POLL"}, + {SYS_LSEEK, "SYS_LSEEK"}, + {SYS_MMAP, "SYS_MMAP"}, + {SYS_MPROTECT, "SYS_MPROTECT"}, + {SYS_MUNMAP, "SYS_MUNMAP"}, + {SYS_BRK, "SYS_BRK"}, + {SYS_RT_SIGACTION, "SYS_RT_SIGACTION"}, + {SYS_RT_SIGPROCMASK, "SYS_RT_SIGPROCMASK"}, + {SYS_RT_SIGRETURN, "SYS_RT_SIGRETURN"}, + {SYS_IOCTL, "SYS_IOCTL"}, + {SYS_PREAD64, "SYS_PREAD64"}, + {SYS_PWRITE64, "SYS_PWRITE64"}, + {SYS_READV, "SYS_READV"}, + {SYS_WRITEV, "SYS_WRITEV"}, + {SYS_ACCESS, "SYS_ACCESS"}, + {SYS_PIPE, "SYS_PIPE"}, + {SYS_SELECT, "SYS_SELECT"}, + {SYS_SCHED_YIELD, "SYS_SCHED_YIELD"}, + {SYS_MREMAP, "SYS_MREMAP"}, + {SYS_MSYNC, "SYS_MSYNC"}, + {SYS_MINCORE, "SYS_MINCORE"}, + {SYS_MADVISE, "SYS_MADVISE"}, + {SYS_SHMGET, "SYS_SHMGET"}, + {SYS_SHMAT, "SYS_SHMAT"}, + {SYS_SHMCTL, "SYS_SHMCTL"}, + {SYS_DUP, "SYS_DUP"}, + {SYS_DUP2, "SYS_DUP2"}, + {SYS_PAUSE, "SYS_PAUSE"}, + {SYS_NANOSLEEP, "SYS_NANOSLEEP"}, + {SYS_GETITIMER, "SYS_GETITIMER"}, + {SYS_ALARM, "SYS_ALARM"}, + {SYS_SETITIMER, "SYS_SETITIMER"}, + {SYS_GETPID, "SYS_GETPID"}, + {SYS_SENDFILE, "SYS_SENDFILE"}, + {SYS_SOCKET, "SYS_SOCKET"}, + {SYS_CONNECT, "SYS_CONNECT"}, + {SYS_ACCEPT, "SYS_ACCEPT"}, + {SYS_SENDTO, "SYS_SENDTO"}, + {SYS_RECVFROM, "SYS_RECVFROM"}, + {SYS_SENDMSG, "SYS_SENDMSG"}, + {SYS_RECVMSG, "SYS_RECVMSG"}, + {SYS_SHUTDOWN, "SYS_SHUTDOWN"}, + {SYS_BIND, "SYS_BIND"}, + {SYS_LISTEN, "SYS_LISTEN"}, + {SYS_GETSOCKNAME, "SYS_GETSOCKNAME"}, + {SYS_GETPEERNAME, "SYS_GETPEERNAME"}, + {SYS_SOCKETPAIR, "SYS_SOCKETPAIR"}, + {SYS_SETSOCKOPT, "SYS_SETSOCKOPT"}, + {SYS_GETSOCKOPT, "SYS_GETSOCKOPT"}, + {SYS_CLONE, "SYS_CLONE"}, + {SYS_FORK, "SYS_FORK"}, + {SYS_VFORK, "SYS_VFORK"}, + {SYS_EXECVE, "SYS_EXECVE"}, + {SYS_EXIT, "SYS_EXIT"}, + {SYS_WAIT4, "SYS_WAIT4"}, + {SYS_KILL, "SYS_KILL"}, + {SYS_UNAME, "SYS_UNAME"}, + {SYS_SEMGET, "SYS_SEMGET"}, + {SYS_SEMOP, "SYS_SEMOP"}, + {SYS_SEMCTL, "SYS_SEMCTL"}, + {SYS_SHMDT, "SYS_SHMDT"}, + {SYS_MSGGET, "SYS_MSGGET"}, + {SYS_MSGSND, "SYS_MSGSND"}, + {SYS_MSGRCV, "SYS_MSGRCV"}, + {SYS_MSGCTL, "SYS_MSGCTL"}, + {SYS_FCNTL, "SYS_FCNTL"}, + {SYS_FLOCK, "SYS_FLOCK"}, + {SYS_FSYNC, "SYS_FSYNC"}, + {SYS_FDATASYNC, "SYS_FDATASYNC"}, + {SYS_TRUNCATE, "SYS_TRUNCATE"}, + {SYS_FTRUNCATE, "SYS_FTRUNCATE"}, + {SYS_GETDENTS, "SYS_GETDENTS"}, + {SYS_GETCWD, "SYS_GETCWD"}, + {SYS_CHDIR, "SYS_CHDIR"}, + {SYS_FCHDIR, "SYS_FCHDIR"}, + {SYS_RENAME, "SYS_RENAME"}, + {SYS_MKDIR, "SYS_MKDIR"}, + {SYS_RMDIR, "SYS_RMDIR"}, + {SYS_CREAT, "SYS_CREAT"}, + {SYS_LINK, "SYS_LINK"}, + {SYS_UNLINK, "SYS_UNLINK"}, + {SYS_SYMLINK, "SYS_SYMLINK"}, + {SYS_READLINK, "SYS_READLINK"}, + {SYS_CHMOD, "SYS_CHMOD"}, + {SYS_FCHMOD, "SYS_FCHMOD"}, + {SYS_CHOWN, "SYS_CHOWN"}, + {SYS_FCHOWN, "SYS_FCHOWN"}, + {SYS_LCHOWN, "SYS_LCHOWN"}, + {SYS_UMASK, "SYS_UMASK"}, + {SYS_GETTIMEOFDAY, "SYS_GETTIMEOFDAY"}, + {SYS_GETRLIMIT, "SYS_GETRLIMIT"}, + {SYS_GETRUSAGE, "SYS_GETRUSAGE"}, + {SYS_SYSINFO, "SYS_SYSINFO"}, + {SYS_TIMES, "SYS_TIMES"}, + {SYS_PTRACE, "SYS_PTRACE"}, + {SYS_GETUID, "SYS_GETUID"}, + {SYS_SYSLOG, "SYS_SYSLOG"}, + {SYS_GETGID, "SYS_GETGID"}, + {SYS_SETUID, "SYS_SETUID"}, + {SYS_SETGID, "SYS_SETGID"}, + {SYS_GETEUID, "SYS_GETEUID"}, + {SYS_GETEGID, "SYS_GETEGID"}, + {SYS_SETPGID, "SYS_SETPGID"}, + {SYS_GETPPID, "SYS_GETPPID"}, + {SYS_GETPGRP, "SYS_GETPGRP"}, + {SYS_SETSID, "SYS_SETSID"}, + {SYS_SETREUID, "SYS_SETREUID"}, + {SYS_SETREGID, "SYS_SETREGID"}, + {SYS_GETGROUPS, "SYS_GETGROUPS"}, + {SYS_SETGROUPS, "SYS_SETGROUPS"}, + {SYS_SETRESUID, "SYS_SETRESUID"}, + {SYS_GETRESUID, "SYS_GETRESUID"}, + {SYS_SETRESGID, "SYS_SETRESGID"}, + {SYS_GETRESGID, "SYS_GETRESGID"}, + {SYS_GETPGID, "SYS_GETPGID"}, + {SYS_SETFSUID, "SYS_SETFSUID"}, + {SYS_SETFSGID, "SYS_SETFSGID"}, + {SYS_GETSID, "SYS_GETSID"}, + {SYS_CAPGET, "SYS_CAPGET"}, + {SYS_CAPSET, "SYS_CAPSET"}, + {SYS_RT_SIGPENDING, "SYS_RT_SIGPENDING"}, + {SYS_RT_SIGTIMEDWAIT, "SYS_RT_SIGTIMEDWAIT"}, + {SYS_RT_SIGQUEUEINFO, "SYS_RT_SIGQUEUEINFO"}, + {SYS_RT_SIGSUSPEND, "SYS_RT_SIGSUSPEND"}, + {SYS_SIGALTSTACK, "SYS_SIGALTSTACK"}, + {SYS_UTIME, "SYS_UTIME"}, + {SYS_MKNOD, "SYS_MKNOD"}, + {SYS_USELIB, "SYS_USELIB"}, + {SYS_PERSONALITY, "SYS_PERSONALITY"}, + {SYS_USTAT, "SYS_USTAT"}, + {SYS_STATFS, "SYS_STATFS"}, + {SYS_FSTATFS, "SYS_FSTATFS"}, + {SYS_SYSFS, "SYS_SYSFS"}, + {SYS_GETPRIORITY, "SYS_GETPRIORITY"}, + {SYS_SETPRIORITY, "SYS_SETPRIORITY"}, + {SYS_SCHED_SETPARAM, "SYS_SCHED_SETPARAM"}, + {SYS_SCHED_GETPARAM, "SYS_SCHED_GETPARAM"}, + {SYS_SCHED_SETSCHEDULER, "SYS_SCHED_SETSCHEDULER"}, + {SYS_SCHED_GETSCHEDULER, "SYS_SCHED_GETSCHEDULER"}, + {SYS_SCHED_GET_PRIORITY_MAX, "SYS_SCHED_GET_PRIORITY_MAX"}, + {SYS_SCHED_GET_PRIORITY_MIN, "SYS_SCHED_GET_PRIORITY_MIN"}, + {SYS_SCHED_RR_GET_INTERVAL, "SYS_SCHED_RR_GET_INTERVAL"}, + {SYS_MLOCK, "SYS_MLOCK"}, + {SYS_MUNLOCK, "SYS_MUNLOCK"}, + {SYS_MLOCKALL, "SYS_MLOCKALL"}, + {SYS_MUNLOCKALL, "SYS_MUNLOCKALL"}, + {SYS_VHANGUP, "SYS_VHANGUP"}, + {SYS_MODIFY_LDT, "SYS_MODIFY_LDT"}, + {SYS_PIVOT_ROOT, "SYS_PIVOT_ROOT"}, + {SYS__SYSCTL, "SYS__SYSCTL"}, + {SYS_PRCTL, "SYS_PRCTL"}, + {SYS_ARCH_PRCTL, "SYS_ARCH_PRCTL"}, + {SYS_ADJTIMEX, "SYS_ADJTIMEX"}, + {SYS_SETRLIMIT, "SYS_SETRLIMIT"}, + {SYS_CHROOT, "SYS_CHROOT"}, + {SYS_SYNC, "SYS_SYNC"}, + {SYS_ACCT, "SYS_ACCT"}, + {SYS_SETTIMEOFDAY, "SYS_SETTIMEOFDAY"}, + {SYS_MOUNT, "SYS_MOUNT"}, + {SYS_UMOUNT2, "SYS_UMOUNT2"}, + {SYS_SWAPON, "SYS_SWAPON"}, + {SYS_SWAPOFF, "SYS_SWAPOFF"}, + {SYS_REBOOT, "SYS_REBOOT"}, + {SYS_SETHOSTNAME, "SYS_SETHOSTNAME"}, + {SYS_SETDOMAINNAME, "SYS_SETDOMAINNAME"}, + {SYS_IOPL, "SYS_IOPL"}, + {SYS_IOPERM, "SYS_IOPERM"}, + {SYS_CREATE_MODULE, "SYS_CREATE_MODULE"}, + {SYS_INIT_MODULE, "SYS_INIT_MODULE"}, + {SYS_DELETE_MODULE, "SYS_DELETE_MODULE"}, + {SYS_GET_KERNEL_SYMS, "SYS_GET_KERNEL_SYMS"}, + {SYS_QUERY_MODULE, "SYS_QUERY_MODULE"}, + {SYS_QUOTACTL, "SYS_QUOTACTL"}, + {SYS_NFSSERVCTL, "SYS_NFSSERVCTL"}, + {SYS_GETPMSG, "SYS_GETPMSG"}, + {SYS_PUTPMSG, "SYS_PUTPMSG"}, + {SYS_AFS_SYSCALL, "SYS_AFS_SYSCALL"}, + {SYS_TUXCALL, "SYS_TUXCALL"}, + {SYS_SECURITY, "SYS_SECURITY"}, + {SYS_GETTID, "SYS_GETTID"}, + {SYS_READAHEAD, "SYS_READAHEAD"}, + {SYS_SETXATTR, "SYS_SETXATTR"}, + {SYS_LSETXATTR, "SYS_LSETXATTR"}, + {SYS_FSETXATTR, "SYS_FSETXATTR"}, + {SYS_GETXATTR, "SYS_GETXATTR"}, + {SYS_LGETXATTR, "SYS_LGETXATTR"}, + {SYS_FGETXATTR, "SYS_FGETXATTR"}, + {SYS_LISTXATTR, "SYS_LISTXATTR"}, + {SYS_LLISTXATTR, "SYS_LLISTXATTR"}, + {SYS_FLISTXATTR, "SYS_FLISTXATTR"}, + {SYS_REMOVEXATTR, "SYS_REMOVEXATTR"}, + {SYS_LREMOVEXATTR, "SYS_LREMOVEXATTR"}, + {SYS_FREMOVEXATTR, "SYS_FREMOVEXATTR"}, + {SYS_TKILL, "SYS_TKILL"}, + {SYS_TIME, "SYS_TIME"}, + {SYS_FUTEX, "SYS_FUTEX"}, + {SYS_SCHED_SETAFFINITY, "SYS_SCHED_SETAFFINITY"}, + {SYS_SCHED_GETAFFINITY, "SYS_SCHED_GETAFFINITY"}, + {SYS_SET_THREAD_AREA, "SYS_SET_THREAD_AREA"}, + {SYS_IO_SETUP, "SYS_IO_SETUP"}, + {SYS_IO_DESTROY, "SYS_IO_DESTROY"}, + {SYS_IO_GETEVENTS, "SYS_IO_GETEVENTS"}, + {SYS_IO_SUBMIT, "SYS_IO_SUBMIT"}, + {SYS_IO_CANCEL, "SYS_IO_CANCEL"}, + {SYS_GET_THREAD_AREA, "SYS_GET_THREAD_AREA"}, + {SYS_LOOKUP_DCOOKIE, "SYS_LOOKUP_DCOOKIE"}, + {SYS_EPOLL_CREATE, "SYS_EPOLL_CREATE"}, + {SYS_EPOLL_CTL_OLD, "SYS_EPOLL_CTL_OLD"}, + {SYS_EPOLL_WAIT_OLD, "SYS_EPOLL_WAIT_OLD"}, + {SYS_REMAP_FILE_PAGES, "SYS_REMAP_FILE_PAGES"}, + {SYS_GETDENTS64, "SYS_GETDENTS64"}, + {SYS_SET_TID_ADDRESS, "SYS_SET_TID_ADDRESS"}, + {SYS_RESTART_SYSCALL, "SYS_RESTART_SYSCALL"}, + {SYS_SEMTIMEDOP, "SYS_SEMTIMEDOP"}, + {SYS_FADVISE64, "SYS_FADVISE64"}, + {SYS_TIMER_CREATE, "SYS_TIMER_CREATE"}, + {SYS_TIMER_SETTIME, "SYS_TIMER_SETTIME"}, + {SYS_TIMER_GETTIME, "SYS_TIMER_GETTIME"}, + {SYS_TIMER_GETOVERRUN, "SYS_TIMER_GETOVERRUN"}, + {SYS_TIMER_DELETE, "SYS_TIMER_DELETE"}, + {SYS_CLOCK_SETTIME, "SYS_CLOCK_SETTIME"}, + {SYS_CLOCK_GETTIME, "SYS_CLOCK_GETTIME"}, + {SYS_CLOCK_GETRES, "SYS_CLOCK_GETRES"}, + {SYS_CLOCK_NANOSLEEP, "SYS_CLOCK_NANOSLEEP"}, + {SYS_EXIT_GROUP, "SYS_EXIT_GROUP"}, + {SYS_EPOLL_WAIT, "SYS_EPOLL_WAIT"}, + {SYS_EPOLL_CTL, "SYS_EPOLL_CTL"}, + {SYS_TGKILL, "SYS_TGKILL"}, + {SYS_UTIMES, "SYS_UTIMES"}, + {SYS_VSERVER, "SYS_VSERVER"}, + {SYS_MBIND, "SYS_MBIND"}, + {SYS_SET_MEMPOLICY, "SYS_SET_MEMPOLICY"}, + {SYS_GET_MEMPOLICY, "SYS_GET_MEMPOLICY"}, + {SYS_MQ_OPEN, "SYS_MQ_OPEN"}, + {SYS_MQ_UNLINK, "SYS_MQ_UNLINK"}, + {SYS_MQ_TIMEDSEND, "SYS_MQ_TIMEDSEND"}, + {SYS_MQ_TIMEDRECEIVE, "SYS_MQ_TIMEDRECEIVE"}, + {SYS_MQ_NOTIFY, "SYS_MQ_NOTIFY"}, + {SYS_MQ_GETSETATTR, "SYS_MQ_GETSETATTR"}, + {SYS_KEXEC_LOAD, "SYS_KEXEC_LOAD"}, + {SYS_WAITID, "SYS_WAITID"}, + {SYS_ADD_KEY, "SYS_ADD_KEY"}, + {SYS_REQUEST_KEY, "SYS_REQUEST_KEY"}, + {SYS_KEYCTL, "SYS_KEYCTL"}, + {SYS_IOPRIO_SET, "SYS_IOPRIO_SET"}, + {SYS_IOPRIO_GET, "SYS_IOPRIO_GET"}, + {SYS_INOTIFY_INIT, "SYS_INOTIFY_INIT"}, + {SYS_INOTIFY_ADD_WATCH, "SYS_INOTIFY_ADD_WATCH"}, + {SYS_INOTIFY_RM_WATCH, "SYS_INOTIFY_RM_WATCH"}, + {SYS_MIGRATE_PAGES, "SYS_MIGRATE_PAGES"}, + {SYS_OPENAT, "SYS_OPENAT"}, + {SYS_MKDIRAT, "SYS_MKDIRAT"}, + {SYS_MKNODAT, "SYS_MKNODAT"}, + {SYS_FCHOWNAT, "SYS_FCHOWNAT"}, + {SYS_FUTIMESAT, "SYS_FUTIMESAT"}, + {SYS_NEWFSTATAT, "SYS_NEWFSTATAT"}, + {SYS_UNLINKAT, "SYS_UNLINKAT"}, + {SYS_RENAMEAT, "SYS_RENAMEAT"}, + {SYS_LINKAT, "SYS_LINKAT"}, + {SYS_SYMLINKAT, "SYS_SYMLINKAT"}, + {SYS_READLINKAT, "SYS_READLINKAT"}, + {SYS_FCHMODAT, "SYS_FCHMODAT"}, + {SYS_FACCESSAT, "SYS_FACCESSAT"}, + {SYS_PSELECT6, "SYS_PSELECT6"}, + {SYS_PPOLL, "SYS_PPOLL"}, + {SYS_UNSHARE, "SYS_UNSHARE"}, + {SYS_SET_ROBUST_LIST, "SYS_SET_ROBUST_LIST"}, + {SYS_GET_ROBUST_LIST, "SYS_GET_ROBUST_LIST"}, + {SYS_SPLICE, "SYS_SPLICE"}, + {SYS_TEE, "SYS_TEE"}, + {SYS_SYNC_FILE_RANGE, "SYS_SYNC_FILE_RANGE"}, + {SYS_VMSPLICE, "SYS_VMSPLICE"}, + {SYS_MOVE_PAGES, "SYS_MOVE_PAGES"}, + {SYS_UTIMENSAT, "SYS_UTIMENSAT"}, + {SYS_EPOLL_PWAIT, "SYS_EPOLL_PWAIT"}, + {SYS_SIGNALFD, "SYS_SIGNALFD"}, + {SYS_TIMERFD_CREATE, "SYS_TIMERFD_CREATE"}, + {SYS_EVENTFD, "SYS_EVENTFD"}, + {SYS_FALLOCATE, "SYS_FALLOCATE"}, + {SYS_TIMERFD_SETTIME, "SYS_TIMERFD_SETTIME"}, + {SYS_TIMERFD_GETTIME, "SYS_TIMERFD_GETTIME"}, + {SYS_ACCEPT4, "SYS_ACCEPT4"}, + {SYS_SIGNALFD4, "SYS_SIGNALFD4"}, + {SYS_EVENTFD2, "SYS_EVENTFD2"}, + {SYS_EPOLL_CREATE1, "SYS_EPOLL_CREATE1"}, + {SYS_DUP3, "SYS_DUP3"}, + {SYS_PIPE2, "SYS_PIPE2"}, + {SYS_INOTIFY_INIT1, "SYS_INOTIFY_INIT1"}, + {SYS_PREADV, "SYS_PREADV"}, + {SYS_PWRITEV, "SYS_PWRITEV"}, + {SYS_RT_TGSIGQUEUEINFO, "SYS_RT_TGSIGQUEUEINFO"}, + {SYS_PERF_EVENT_OPEN, "SYS_PERF_EVENT_OPEN"}, + {SYS_RECVMMSG, "SYS_RECVMMSG"}, + {SYS_FANOTIFY_INIT, "SYS_FANOTIFY_INIT"}, + {SYS_FANOTIFY_MARK, "SYS_FANOTIFY_MARK"}, + {SYS_PRLIMIT64, "SYS_PRLIMIT64"}, + +}; + +char *seccomp_syscall_lookup(int id) { + + if (id < 0) { FATAL("Invalid id: %d", id); } + if ((uint32_t)id >= sizeof(seccomp_syscall_table) / sizeof(syscall_entry_t)) { + + FATAL("Invalid id: %d", id); + + } + + return seccomp_syscall_table[id].name; + +} + diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index c722f558..8a1ebf1b 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -225,6 +225,15 @@ class Afl { Afl.jsApiSetPrefetchDisable(); } + /** + * See `AFL_FRIDA_SECCOMP_FILE`. This function takes a single `string` as + * an argument. + */ + public static setSeccompFile(file: string): void { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetSeccompFile(buf); + } + /* * Set a function to be called for each instruction which is instrumented * by AFL FRIDA mode. @@ -387,6 +396,11 @@ class Afl { "void", []); + private static readonly jsApiSetSeccompFile = Afl.jsApiGetFunction( + "js_api_set_seccomp_file", + "void", + ["pointer"]); + private static readonly jsApiSetStalkerCallback = Afl.jsApiGetFunction( "js_api_set_stalker_callback", "void", |