stabbish

:)
git clone https://git.sr.ht/~ashymad/stabbish
Log | Files | Refs | README | LICENSE

main.c (1671B)


      1 #define _GNU_SOURCE 1
      2 
      3 #include <malloc.h>
      4 #include <stdbool.h>
      5 #include <stdio.h>
      6 #include <string.h>
      7 #include <sys/mman.h>
      8 #include <unistd.h>
      9 
     10 #include "busybox/busybox.inc.h"
     11 #include "magic.h"
     12 #include "payload.h"
     13 #include "utils.h"
     14 
     15 int main(int argc, char **argv) {
     16   static int try_return = -1;
     17 
     18   bool start_shell = argc > 1 && strcmp(argv[1], "--stabbish-shell") == 0;
     19   if (start_shell)
     20     shift(1);
     21 
     22   fd busybox = try(memfd_create("busybox", 0));
     23   fd rcfile = try(memfd_create("rcfile", 0));
     24   fd payload = try(get_payload("/proc/self/exe"));
     25 
     26   setenv("ENV", pasprintf("/dev/fd/%i", rcfile), 1);
     27   setenv("BUSYBOX", pasprintf("/dev/fd/%i", busybox), 1);
     28 
     29   if (payload == ENOPAYLOAD) {
     30     try(dprintf(rcfile, "echo No payload present, starting shell."));
     31   } else {
     32     setenv("PAYLOAD", pasprintf("/dev/fd/%i", payload), 1);
     33   }
     34 
     35   try(write(busybox, _inc_busybox, _inc_busybox_size));
     36 
     37   if (start_shell || payload == ENOPAYLOAD) {
     38     argv[0] = strdup("ash");
     39     return fexecve(busybox, argv, environ);
     40   }
     41 
     42   struct magic magic = magic_detect(payload);
     43   if (magic.tool) {
     44     fd extracted = try(memfd_create("extracted", 0));
     45     char *tool = strdup(magic.tool);
     46     struct stdstream std = {payload, extracted, -1};
     47 
     48     lseek(payload, SEEK_SET, 0);
     49     try(memexecv(busybox, (char *[]){tool, NULL}, NULL, std));
     50     dup2(extracted, payload);
     51     free(tool);
     52   }
     53 
     54   char **bb_argv = malloc(sizeof(char *) * (argc + 4));
     55   bb_argv[0] = strdup("ash");
     56   bb_argv[1] = strdup("-c");
     57   bb_argv[2] = pasprintf(". /dev/fd/%i", payload);
     58   for (int i = 0; i <= argc; i++) {
     59     bb_argv[i + 3] = argv[i];
     60   }
     61 
     62   return fexecve(busybox, bb_argv, environ);
     63 }