|
|
sup.c - sup - small tool for privilege escalation |
|
|
 |
git clone git://bitreich.org/sup git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sup (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
 |
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 } |
|