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