From 72c217d74a745e2916b7010e04ab7408c267c773 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 3 Apr 2021 18:03:13 +0200 Subject: [PATCH] reverted to the old exec way this branch will contain a version of us which doesn't use a subshell as a proxy but directly applies the privilege escalation to the command --- TODO | 11 ++++++++++- us.c | 44 ++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/TODO b/TODO index 01fe41b..d0dbedc 100644 --- a/TODO +++ b/TODO @@ -4,4 +4,13 @@ * SHELL -> to the target user's SHELL * HOME -> to the target user's HOME -- Reconsider executing programs in a subshell +- fork before exec, that is because processes might try to kill us or the + command but since they may run under elevated privileges they will get + permission denied error. If we remain the parent processes, unprivileged + proceses can send signals to us and we will relay them to our children + running at the same privilege as us. This is useful when: + - The child command hangs and we want to cose it, kinda + problematic but we could run kill with us as well + - The parent shell dies and children need to be killed, then + since one of their children (us) has higher privileges + they can't kill us and we would end up as zombies diff --git a/us.c b/us.c index 40ab1c6..09778b2 100644 --- a/us.c +++ b/us.c @@ -103,22 +103,35 @@ int main (int argc, char *argv[]) shell = "/bin/sh"; /* Set argc and argv */ - char *command = NULL; - int size, popind = optind; - if (argc - optind) { - for (size = 0; optind < argc; optind++) - size += strlen(argv[optind]) + 1; - command = malloc(sizeof(char) * size + 1); - if (!command) { + int c_argc = argc - optind; + char **c_argv; + if (c_argc) { + c_argv = malloc(sizeof(char *) * (c_argc + 1)); + if (!c_argv) { fprintf(stderr, "malloc: %s\n", strerror(errno)); exit(errno); } - memset(command, 0, size + 1); - for (optind = popind; optind < argc; optind++) { - strcat(command, argv[optind]); - strcat(command, " "); + for (int i = 0; optind < argc; optind++, i++) { + c_argv[i] = strdup(argv[optind]); + if (!c_argv[i]) { + fprintf(stderr, "strdup: %s\n", strerror(errno)); + exit(errno); + } + } + } else { + c_argc = 1; + c_argv = malloc(sizeof(char *) * (c_argc + 1)); + if (!c_argv) { + fprintf(stderr, "malloc: %s\n", strerror(errno)); + exit(errno); + } + c_argv[0] = strdup(shell); + if (!c_argv[0]) { + fprintf(stderr, "strdup: %s\n", strerror(errno)); + exit(errno); } } + c_argv[c_argc] = NULL; /* Authenticate */ if (authenticate(uname) != PAM_SUCCESS) @@ -135,17 +148,16 @@ int main (int argc, char *argv[]) /* Execute the command */ int err; - if (command) - err = execl(shell, shell, "-c", command, (char *)NULL); - else - err = execl(shell, shell, (char *)NULL); + err = execvp(c_argv[0], c_argv); if (err == -1) fprintf(stderr, "execl: %s\n", strerror(errno)); /* Cleanup and return */ fail_end: /* Free up the copied argv */ - free(command); + for (int i=0; c_argv[i]; i++) + free(c_argv[i]); + free(c_argv); return errno; }