isup.c - sup - small tool for privilege escalation Err bitreich.org 70 hgit clone git://bitreich.org/sup git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sup URL:git://bitreich.org/sup git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sup bitreich.org 70 1Log /scm/sup/log.gph bitreich.org 70 1Files /scm/sup/files.gph bitreich.org 70 1Refs /scm/sup/refs.gph bitreich.org 70 1Tags /scm/sup/tag bitreich.org 70 1README /scm/sup/file/README.gph bitreich.org 70 1LICENSE /scm/sup/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 isup.c (2238B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 /* See LICENSE file for copyright and license details. */ Err bitreich.org 70 i 2 Err bitreich.org 70 i 3 #include Err bitreich.org 70 i 4 #include Err bitreich.org 70 i 5 #include Err bitreich.org 70 i 6 #include Err bitreich.org 70 i 7 #include Err bitreich.org 70 i 8 Err bitreich.org 70 i 9 #include "arg.h" Err bitreich.org 70 i 10 #include "sha256.h" Err bitreich.org 70 i 11 Err bitreich.org 70 i 12 #define nelem(x) (sizeof (x) / sizeof *(x)) Err bitreich.org 70 i 13 #define CHUNK 1048576 /* 1MiB */ Err bitreich.org 70 i 14 Err bitreich.org 70 i 15 struct rule_t { Err bitreich.org 70 i 16 const int uid; Err bitreich.org 70 i 17 const char *cmd; Err bitreich.org 70 i 18 const char *path; Err bitreich.org 70 i 19 const char *hash; Err bitreich.org 70 i 20 }; Err bitreich.org 70 i 21 Err bitreich.org 70 i 22 #include "config.h" Err bitreich.org 70 i 23 Err bitreich.org 70 i 24 char *argv0; Err bitreich.org 70 i 25 Err bitreich.org 70 i 26 static void die(char *msg) Err bitreich.org 70 i 27 { Err bitreich.org 70 i 28 fprintf(stderr, "%s\n", msg); Err bitreich.org 70 i 29 exit(1); Err bitreich.org 70 i 30 } Err bitreich.org 70 i 31 Err bitreich.org 70 i 32 static uint32 getsha(const char *path, unsigned char *dest) Err bitreich.org 70 i 33 { Err bitreich.org 70 i 34 static sha256_context sha; Err bitreich.org 70 i 35 unsigned char buf[CHUNK]; Err bitreich.org 70 i 36 uint32 len, tot = 0; Err bitreich.org 70 i 37 FILE *fd; Err bitreich.org 70 i 38 Err bitreich.org 70 i 39 fd = fopen(path, "r"); Err bitreich.org 70 i 40 if (!fd) Err bitreich.org 70 i 41 die("Can not read binary file."); Err bitreich.org 70 i 42 Err bitreich.org 70 i 43 sha256_starts(&sha); Err bitreich.org 70 i 44 Err bitreich.org 70 i 45 while ((len = fread(buf, 1, CHUNK, fd))) { Err bitreich.org 70 i 46 sha256_update(&sha, buf, len); Err bitreich.org 70 i 47 tot += len; Err bitreich.org 70 i 48 } Err bitreich.org 70 i 49 fclose(fd); Err bitreich.org 70 i 50 Err bitreich.org 70 i 51 sha256_finish(&sha, dest); Err bitreich.org 70 i 52 return tot; Err bitreich.org 70 i 53 } Err bitreich.org 70 i 54 Err bitreich.org 70 i 55 int main(int argc, char *argv[]) Err bitreich.org 70 i 56 { Err bitreich.org 70 i 57 unsigned int c, i, lflag = 0; Err bitreich.org 70 i 58 unsigned char digest[32]; Err bitreich.org 70 i 59 char output[65]; Err bitreich.org 70 i 60 struct stat st; Err bitreich.org 70 i 61 Err bitreich.org 70 i 62 ARGBEGIN { Err bitreich.org 70 i 63 case 'l': Err bitreich.org 70 i 64 lflag = 1; Err bitreich.org 70 i 65 break; Err bitreich.org 70 i 66 default: Err bitreich.org 70 i 67 die("Usage: sup [-l] command [ args ... ]"); Err bitreich.org 70 i 68 } ARGEND; Err bitreich.org 70 i 69 Err bitreich.org 70 i 70 if (lflag) { Err bitreich.org 70 i 71 printf("List of compiled authorizations:\n"); Err bitreich.org 70 i 72 for (i = 0; i < nelem(rules); i++) Err bitreich.org 70 i 73 printf("\nuser: %d\ncmd: %s\nbinary: %s\nsha256: %s\n", Err bitreich.org 70 i 74 rules[i].uid, rules[i].cmd, rules[i].path, Err bitreich.org 70 i 75 rules[i].hash); Err bitreich.org 70 i 76 return 0; Err bitreich.org 70 i 77 } Err bitreich.org 70 i 78 Err bitreich.org 70 i 79 if (argc < 1) Err bitreich.org 70 i 80 die("Usage: sup [-l] command [ args ... ]"); Err bitreich.org 70 i 81 Err bitreich.org 70 i 82 for (i = 0; i < nelem(rules); i++) { Err bitreich.org 70 i 83 if (!strcmp(argv[0], rules[i].cmd)) { Err bitreich.org 70 i 84 Err bitreich.org 70 i 85 if (rules[i].uid != getuid() && rules[i].uid != -1) Err bitreich.org 70 i 86 die("Unauthorized user."); Err bitreich.org 70 i 87 Err bitreich.org 70 i 88 if (stat(rules[i].path, &st) == -1) Err bitreich.org 70 i 89 die("Can not stat program."); Err bitreich.org 70 i 90 Err bitreich.org 70 i 91 if (st.st_mode & 0022) Err bitreich.org 70 i 92 die("Can not run writable binaries."); Err bitreich.org 70 i 93 Err bitreich.org 70 i 94 if (getsha(rules[i].path, digest) != st.st_size) Err bitreich.org 70 i 95 die("Binary file differs from size read."); Err bitreich.org 70 i 96 Err bitreich.org 70 i 97 for (c = 0; c < 32; c++) Err bitreich.org 70 i 98 sprintf(output + (c * 2), "%02x", digest[c]); Err bitreich.org 70 i 99 output[64] = '\0'; Err bitreich.org 70 i 100 Err bitreich.org 70 i 101 if (strncmp(rules[i].hash, output, 64)) Err bitreich.org 70 i 102 die("Checksums do not match."); Err bitreich.org 70 i 103 Err bitreich.org 70 i 104 if (setgid(SETGID) < 0) Err bitreich.org 70 i 105 die("setgid failed"); Err bitreich.org 70 i 106 if (setuid(SETUID) < 0) Err bitreich.org 70 i 107 die("setuid failed"); Err bitreich.org 70 i 108 Err bitreich.org 70 i 109 if (execv(rules[i].path, argv) < 0) Err bitreich.org 70 i 110 die("execv failed."); Err bitreich.org 70 i 111 } Err bitreich.org 70 i 112 } Err bitreich.org 70 i 113 die("Unauthorized command."); Err bitreich.org 70 i 114 } Err bitreich.org 70 .