Revert "fix: static build + new syscall spoofer"

This reverts commit 197cc3098d.
This commit is contained in:
2026-05-17 19:58:50 +02:00
parent 65da1f0093
commit ebbccfb7ae
2 changed files with 34 additions and 158 deletions

View File

@@ -72,11 +72,11 @@ host: $(HOST_EXE) $(HOST_EXE_SPOOFER)
# Build the main challenge executable # Build the main challenge executable
$(HOST_EXE): $(HOST_SRC) | $(BUILD_DIR) $(HOST_EXE): $(HOST_SRC) | $(BUILD_DIR)
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -static $(HOST_INCLUDE) $(HOST_SRC) -o $@ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_INCLUDE) $(HOST_SRC) -o $@
# Build the spoofer # Build the spoofer
$(HOST_EXE_SPOOFER): $(HOST_SRC_SPOOFER) | $(BUILD_DIR) $(HOST_EXE_SPOOFER): $(HOST_SRC_SPOOFER) | $(BUILD_DIR)
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -static $^ -o $@ -ldl $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -shared -fPIC $^ -o $@ -ldl
# Build the encryptor # Build the encryptor
$(HOST_EXE_ENCRYPTOR): $(HOST_SRC_ENCRYPTOR) | $(BUILD_DIR) $(HOST_EXE_ENCRYPTOR): $(HOST_SRC_ENCRYPTOR) | $(BUILD_DIR)

View File

@@ -1,164 +1,40 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <dlfcn.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/uio.h>
#include <sys/syscall.h>
#include <fcntl.h>
static void write_mem(pid_t pid, unsigned long addr, const char *buf, size_t len) static FILE *(*real_fopen)(const char *path, const char *mode) = NULL;
{
struct iovec local = {(void *)buf, len}; static void init_real_fopen(void) {
struct iovec remote = {(void *)addr, len}; if (!real_fopen) {
if (process_vm_writev(pid, &local, 1, &remote, 1, 0) < 0) real_fopen = dlsym(RTLD_NEXT, "fopen");
{ if (!real_fopen) {
perror("spoofer: process_vm_writev"); fprintf(stderr, "proc_redirect: dlsym(fopen) failed: %s\n", dlerror());
abort(); abort();
}
} }
} }
static int read_string(pid_t pid, unsigned long addr, char *buf, size_t max) FILE *fopen(const char *path, const char *mode) {
{ init_real_fopen();
struct iovec local = {buf, max};
struct iovec remote = {(void *)addr, max}; if (path && strncmp(path, "/proc/", 6) == 0) {
ssize_t n = process_vm_readv(pid, &local, 1, &remote, 1, 0); const char *rel_suffix = path + 1;
if (n < 0) size_t len = strlen(rel_suffix) + 4;
return -1; char *new_path = malloc(len);
buf[n < (ssize_t)max ? (size_t)n : max - 1] = '\0'; if (!new_path) {
buf[strnlen(buf, max - 1)] = '\0'; fprintf(stderr, "proc_redirect: malloc failed\n");
return 0; abort();
} }
new_path[0] = '.';
static void handle_openat(pid_t pid, struct user_regs_struct *regs) new_path[1] = '/';
{ new_path[2] = '.';
unsigned long path_ptr = regs->rsi; strcpy(new_path + 3, rel_suffix);
char orig[4096] = {0};
if (read_string(pid, path_ptr, orig, sizeof(orig)) < 0) FILE *f = real_fopen(new_path, mode);
return; free(new_path);
if (strncmp(orig, "/proc/", 6) != 0) return f;
return; }
char newpath[4096]; return real_fopen(path, mode);
snprintf(newpath, sizeof(newpath), ".%s", orig + 1);
/* Scratch space below the red zone, safe from any live stack frame */
unsigned long scratch = regs->rsp - 256 - sizeof(newpath);
write_mem(pid, scratch, newpath, strlen(newpath) + 1);
struct user_regs_struct r = *regs;
r.rsi = scratch;
if (ptrace(PTRACE_SETREGS, pid, NULL, &r) < 0)
perror("spoofer: PTRACE_SETREGS");
else
fprintf(stderr, "spoofer: redirected '%s' -> '%s'\n", orig, newpath);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "usage: %s <program> [args...]\n", argv[0]);
return 1;
}
pid_t pid = fork();
if (pid < 0)
{
perror("fork");
return 1;
}
if (pid == 0)
{
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0)
{
perror("spoofer: PTRACE_TRACEME");
_exit(1);
}
execvp(argv[1], argv + 1);
perror("spoofer: execvp");
_exit(1);
}
int status;
if (waitpid(pid, &status, 0) < 0)
{
perror("waitpid");
return 1;
}
if (!WIFSTOPPED(status))
{
fprintf(stderr, "spoofer: unexpected initial status %d\n", status);
return 1;
}
if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
(void *)(long)(PTRACE_O_TRACESYSGOOD | PTRACE_O_EXITKILL)) < 0)
{
perror("spoofer: PTRACE_SETOPTIONS");
return 1;
}
int in_syscall = 0;
while (1)
{
if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0)
{
perror("spoofer: PTRACE_SYSCALL");
break;
}
if (waitpid(pid, &status, 0) < 0)
{
perror("waitpid");
break;
}
if (WIFEXITED(status) || WIFSIGNALED(status))
break;
if (!WIFSTOPPED(status))
continue;
int sig = WSTOPSIG(status);
if (sig == (SIGTRAP | 0x80))
{
if (!in_syscall)
{
struct user_regs_struct regs;
if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) == 0)
{
if (regs.orig_rax == SYS_openat)
{
handle_openat(pid, &regs);
}
else if (regs.orig_rax == SYS_open)
{
/* SYS_open: rdi=path — copy to rsi so handle_openat works */
regs.rsi = regs.rdi;
handle_openat(pid, &regs);
}
}
}
in_syscall ^= 1;
}
else
{
/* Forward real signals to the tracee */
ptrace(PTRACE_SYSCALL, pid, NULL, (void *)(long)sig);
in_syscall = 0;
continue;
}
}
if (WIFEXITED(status))
return WEXITSTATUS(status);
if (WIFSIGNALED(status))
return 128 + WTERMSIG(status);
return 0;
} }