SMOLNET PORTAL home about changes
iRewrite C code and add SHA256 support. - 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
1commit cec5f362b273867f23126ccb7a756905c640c856	/scm/sup/commit/cec5f362b273867f23126ccb7a756905c640c856.gph	bitreich.org	70
1parent 96b227c7bf3acc15c0de695b074f2b32fcabe21e	/scm/sup/commit/96b227c7bf3acc15c0de695b074f2b32fcabe21e.gph	bitreich.org	70
hAuthor: parazyd <parazyd@dyne.org>	URL:mailto:parazyd@dyne.org	bitreich.org	70
iDate:   Tue,  2 Jul 2019 13:00:38 +0200	Err	bitreich.org	70
i	Err	bitreich.org	70
iRewrite C code and add SHA256 support.	Err	bitreich.org	70
i	Err	bitreich.org	70
iDiffstat:	Err	bitreich.org	70
i  M config.def.h                        |      33 +++++++++++++++++++------------	Err	bitreich.org	70
i  M sup.c                               |     158 ++++++++++++++++---------------	Err	bitreich.org	70
i	Err	bitreich.org	70
i2 files changed, 103 insertions(+), 88 deletions(-)	Err	bitreich.org	70
i---	Err	bitreich.org	70
1diff --git a/config.def.h b/config.def.h	/scm/sup/file/config.def.h.gph	bitreich.org	70
i@@ -1,20 +1,27 @@	Err	bitreich.org	70
i-#define USER 1000	Err	bitreich.org	70
i-#define GROUP -1	Err	bitreich.org	70
i+/* See LICENSE file for copyright and license details. */	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+/* User and group to run as */	Err	bitreich.org	70
i #define SETUID 0	Err	bitreich.org	70
i #define SETGID 0	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-#define CHROOT ""	Err	bitreich.org	70
i-#define CHRDIR ""	Err	bitreich.org	70
i+/* sup authorizations	Err	bitreich.org	70
i+ *	Err	bitreich.org	70
i+ * The format is as follows:	Err	bitreich.org	70
i+ * - UID allowed to run the command (-1 means anyone)	Err	bitreich.org	70
i+ * - Alias/command used to call the executable	Err	bitreich.org	70
i+ * - Path to the executable to run	Err	bitreich.org	70
i+ * - SHA256 checksum of the executable	Err	bitreich.org	70
i+ */	Err	bitreich.org	70
i+static struct rule_t rules[] = {	Err	bitreich.org	70
i+        { 1000, "ls", "/bin/ls",	Err	bitreich.org	70
i+                "87e8fd7d813c135875aca43a4da43d3ced41d325ed2931906444471b4e93e017" },	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-#define ENFORCE 1	Err	bitreich.org	70
i+        { -1, "grep", "/bin/grep",	Err	bitreich.org	70
i+                "fedeb344d1be24f4a340591cd25ed81f7e46ea12772f563c9c9f43773028e23a" },	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-static struct rule_t rules[] = {	Err	bitreich.org	70
i-        { USER, GROUP, "whoami", "/usr/bin/whoami" },	Err	bitreich.org	70
i-        { USER, GROUP, "ifconfig", "/sbin/ifconfig" },	Err	bitreich.org	70
i-        { USER, GROUP, "ls", "/bin/ls" },	Err	bitreich.org	70
i-        { USER, GROUP, "wifi", "/root/wifi.sh" },	Err	bitreich.org	70
i-        { USER, GROUP, "cp", "*"}, // allow to run this program in PATH	Err	bitreich.org	70
i-        { USER, GROUP, "*", "*"}, // allow to run any program in PATH	Err	bitreich.org	70
i-        { 0 },	Err	bitreich.org	70
i+        { 1000, "tar", "/bin/tar",	Err	bitreich.org	70
i+                "fedeb344d1be24f4a340591cd25ed81f7e46ea12772f563c9c9f43773028e23a" },	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        { 1001, "test", "./a.out",	Err	bitreich.org	70
i+                "254260b676a44f1529f7c855f0126a57a3fbd7ec8a74de08835f08e8e6ed21be" },	Err	bitreich.org	70
i };	Err	bitreich.org	70
1diff --git a/sup.c b/sup.c	/scm/sup/file/sup.c.gph	bitreich.org	70
i@@ -1,103 +1,111 @@	Err	bitreich.org	70
i-/* pancake <nopcode.org> -- Copyleft 2009-2011 */	Err	bitreich.org	70
i+/* See LICENSE file for copyright and license details. */	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-#include <errno.h>	Err	bitreich.org	70
i-#include <unistd.h>	Err	bitreich.org	70
i #include <stdio.h>	Err	bitreich.org	70
i-#include <string.h>	Err	bitreich.org	70
i #include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i #include <sys/stat.h>	Err	bitreich.org	70
i+#include <unistd.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include "arg.h"	Err	bitreich.org	70
i+#include "sha256.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-#define HELP "sup [-hlv] [cmd ..]"	Err	bitreich.org	70
i-#define VERSION "sup 0.1 pancake <nopcode.org> copyleft 2011"	Err	bitreich.org	70
i+#define nelem(x) (sizeof (x) / sizeof *(x))	Err	bitreich.org	70
i 	Err	bitreich.org	70
i struct rule_t {	Err	bitreich.org	70
i-        int uid;	Err	bitreich.org	70
i-        int gid;	Err	bitreich.org	70
i+        const int uid;	Err	bitreich.org	70
i         const char *cmd;	Err	bitreich.org	70
i         const char *path;	Err	bitreich.org	70
i+        const char *hash;	Err	bitreich.org	70
i };	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #include "config.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-static int die(int ret, const char *org, const char *str) {	Err	bitreich.org	70
i-        fprintf (stderr, "%s%s%s\n", org?org:"", org?": ":"", str);	Err	bitreich.org	70
i-        return ret;	Err	bitreich.org	70
i+char *argv0;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void die(char *msg) {	Err	bitreich.org	70
i+        fprintf(stderr, "%s\n", msg);	Err	bitreich.org	70
i+        exit(1);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-static char *getpath(const char *str) {	Err	bitreich.org	70
i-        struct stat st;	Err	bitreich.org	70
i-        static char file[4096];	Err	bitreich.org	70
i-        char *p, *path = getenv ("PATH");	Err	bitreich.org	70
i-        if (path)	Err	bitreich.org	70
i-        for (p = path; *p; p++) {	Err	bitreich.org	70
i-                if (*p==':' && (p>path&&*(p-1)!='\\')) {	Err	bitreich.org	70
i-                        *p = 0;	Err	bitreich.org	70
i-                        snprintf (file, sizeof (file)-1, "%s/%s", path, str);	Err	bitreich.org	70
i-                        if (!lstat (file, &st))	Err	bitreich.org	70
i-                                return file;	Err	bitreich.org	70
i-                        *p = ':';	Err	bitreich.org	70
i-                        path = p+1;	Err	bitreich.org	70
i-                }	Err	bitreich.org	70
i+#define CHUNK 1048576 /* 1MiB */	Err	bitreich.org	70
i+static uint32 getsha(const char *path, unsigned char *dest) {	Err	bitreich.org	70
i+        static sha256_context sha;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        unsigned char buf[CHUNK];	Err	bitreich.org	70
i+        uint32 len, tot = 0;	Err	bitreich.org	70
i+        FILE *fd;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        fd = fopen(path, "r");	Err	bitreich.org	70
i+        if (!fd)	Err	bitreich.org	70
i+                die("Can not read binary file.");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        sha256_starts(&sha);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        while ((len = fread(buf, 1, CHUNK, fd))) {	Err	bitreich.org	70
i+                sha256_update(&sha, buf, len);	Err	bitreich.org	70
i+                tot += len;	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i-        return NULL;	Err	bitreich.org	70
i+        fclose(fd);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        sha256_finish(&sha, dest);	Err	bitreich.org	70
i+        return tot;	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-int main(int argc, char **argv) {	Err	bitreich.org	70
i-        const char *cmd;	Err	bitreich.org	70
i-        int i, uid, gid, ret;	Err	bitreich.org	70
i+int main(int argc, char *argv[]) {	Err	bitreich.org	70
i+        unsigned int c, i, lflag = 0;	Err	bitreich.org	70
i+        unsigned char digest[32];	Err	bitreich.org	70
i+        char output[65];	Err	bitreich.org	70
i+        struct stat st;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        if (argc < 2 || !strcmp (argv[1], "-h"))	Err	bitreich.org	70
i-                return die (1, NULL, HELP);	Err	bitreich.org	70
i+        ARGBEGIN {	Err	bitreich.org	70
i+                case 'l':	Err	bitreich.org	70
i+                        lflag = 1;	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                default:	Err	bitreich.org	70
i+                        die("Usage: sup [-l] command [ args ... ]");	Err	bitreich.org	70
i+        } ARGEND;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        if (!strcmp (argv[1], "-v"))	Err	bitreich.org	70
i-                return die (1, NULL, VERSION);	Err	bitreich.org	70
i+        if (lflag) {	Err	bitreich.org	70
i+                printf("List of compiled authorizations:\n");	Err	bitreich.org	70
i+                for (i = 0; i < nelem(rules); i++)	Err	bitreich.org	70
i+                        printf("\nuser: %d\ncmd: %s\nbinary: %s\nsha256: %s\n",	Err	bitreich.org	70
i+                                        rules[i].uid, rules[i].cmd, rules[i].path, rules[i].hash);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        if (!strcmp (argv[1], "-l")) {	Err	bitreich.org	70
i-                for (i = 0; rules[i].cmd != NULL; i++)	Err	bitreich.org	70
i-                        printf ("%d %d %10s %s\n", rules[i].uid, rules[i].gid,	Err	bitreich.org	70
i-                                rules[i].cmd, rules[i].path);	Err	bitreich.org	70
i                 return 0;	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        uid = getuid ();	Err	bitreich.org	70
i-        gid = getgid ();	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        for (i = 0; rules[i].cmd != NULL; i++) {	Err	bitreich.org	70
i-                if (*rules[i].cmd=='*' || !strcmp (argv[1], rules[i].cmd)) {	Err	bitreich.org	70
i-#if ENFORCE        	Err	bitreich.org	70
i-                        struct stat st;	Err	bitreich.org	70
i-                        if (*rules[i].path=='*') {	Err	bitreich.org	70
i-                                if (*argv[1]=='.' || *argv[1]=='/')	Err	bitreich.org	70
i-                                        cmd = argv[1];	Err	bitreich.org	70
i-                                else if (!(cmd = getpath (argv[1])))	Err	bitreich.org	70
i-                                        return die (1, "execv", "cannot find program");	Err	bitreich.org	70
i-                        } else cmd = rules[i].path;	Err	bitreich.org	70
i-                        if (lstat (cmd, &st) == -1)	Err	bitreich.org	70
i-                                return die (1, "lstat", "cannot stat program");	Err	bitreich.org	70
i-                        if (st.st_mode & 0222)	Err	bitreich.org	70
i-                                return die (1, "stat", "cannot run writable binaries.");	Err	bitreich.org	70
i-#endif	Err	bitreich.org	70
i-                        if (uid != SETUID && rules[i].uid != -1 && rules[i].uid != uid)	Err	bitreich.org	70
i-                                return die (1, "urule", "user does not match");	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-                        if (gid != SETGID && rules[i].gid != -1 && rules[i].gid != gid)	Err	bitreich.org	70
i-                                return die (1, "grule", "group id does not match");	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-                        if (setuid (SETUID) == -1 || setgid (SETGID) == -1 ||	Err	bitreich.org	70
i-                            seteuid (SETUID) == -1 || setegid (SETGID) == -1)	Err	bitreich.org	70
i-                                return die (1, "set[e][ug]id", strerror (errno));	Err	bitreich.org	70
i-#ifdef CHROOT	Err	bitreich.org	70
i-                        if (*CHROOT)	Err	bitreich.org	70
i-                                if (chdir (CHROOT) == -1 || chroot (".") == -1)	Err	bitreich.org	70
i-                                        return die (1, "chroot", strerror (errno));	Err	bitreich.org	70
i-                        if (*CHRDIR)	Err	bitreich.org	70
i-                                if (chdir (CHRDIR) == -1)	Err	bitreich.org	70
i-                                        return die (1, "chdir", strerror (errno));	Err	bitreich.org	70
i-#endif	Err	bitreich.org	70
i-                        ret = execv (cmd, argv+1);	Err	bitreich.org	70
i-                        return die (ret, "execv", strerror (errno));	Err	bitreich.org	70
i+        if (argc < 1)	Err	bitreich.org	70
i+                die("Usage: sup [-l] command [ args ... ]");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (i = 0; i < nelem(rules); i++) {	Err	bitreich.org	70
i+                if (!strcmp(argv[0], rules[i].cmd)) {	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (rules[i].uid != getuid() && rules[i].uid != -1)	Err	bitreich.org	70
i+                                die("Unauthorized user.");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (stat(rules[i].path, &st) == -1)	Err	bitreich.org	70
i+                                die("Can not stat program.");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (st.st_mode & 0022)	Err	bitreich.org	70
i+                                die("Can not run binaries others can write.");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (getsha(rules[i].path, digest) != st.st_size)	Err	bitreich.org	70
i+                                die("Binary file differs from size read.");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        for (c = 0; c < 32; c++)	Err	bitreich.org	70
i+                                sprintf(output + (c*2), "%02x", digest[c]);	Err	bitreich.org	70
i+                        output[64] = '\0';	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (strncmp(rules[i].hash, output, 64))	Err	bitreich.org	70
i+                                die("Checksums do not match.");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (setgid(SETGID) < 0) die("setgid failed");	Err	bitreich.org	70
i+                        if (setuid(SETUID) < 0) die("setuid failed");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        if (execv(rules[i].path, argv) < 0)	Err	bitreich.org	70
i+                                die("execv failed.");	Err	bitreich.org	70
i                 }	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        return die (1, NULL, "Sorry");	Err	bitreich.org	70
i+        die("Unauthorized command.");	Err	bitreich.org	70
i }	Err	bitreich.org	70
.
Response: text/plain
Original URLgopher://bitreich.org/0/scm/sup/commit/cec5f362b273867f23...
Content-Typetext/plain; charset=utf-8