it* Find binaries in PATH when specified in path '*' * Check return value of lstat - sup - small tool for privilege escalation Err parazyd.org 70 hgit clone https://git.parazyd.org/sup URL:https://git.parazyd.org/sup parazyd.org 70 1Log /git/sup/log.gph parazyd.org 70 1Files /git/sup/files.gph parazyd.org 70 1Refs /git/sup/refs.gph parazyd.org 70 1README /git/sup/file/README.gph parazyd.org 70 1LICENSE /git/sup/file/LICENSE.gph parazyd.org 70 i--- Err parazyd.org 70 1commit 836d0723d883384c1ea8e1b4c3fd23eced9c8043 /git/sup/commit/836d0723d883384c1ea8e1b4c3fd23eced9c8043.gph parazyd.org 70 1parent 8078fe60673809c9ce32dd85613e9f96d7278742 /git/sup/commit/8078fe60673809c9ce32dd85613e9f96d7278742.gph parazyd.org 70 hAuthor: pancake URL:mailto:unknown parazyd.org 70 iDate: Thu, 31 Mar 2011 20:56:00 +0200 Err parazyd.org 70 i Err parazyd.org 70 i* Find binaries in PATH when specified in path '*' Err parazyd.org 70 i* Check return value of lstat Err parazyd.org 70 iDiffstat: Err parazyd.org 70 i M config.def.h | 3 ++- Err parazyd.org 70 i M sup.c | 47 ++++++++++++++++++++++++------- Err parazyd.org 70 i Err parazyd.org 70 i2 files changed, 39 insertions(+), 11 deletions(-) Err parazyd.org 70 i--- Err parazyd.org 70 1diff --git a/config.def.h b/config.def.h /git/sup/file/config.def.h.gph parazyd.org 70 it@@ -14,6 +14,7 @@ static struct rule_t rules[] = { Err parazyd.org 70 i { USER, GROUP, "ifconfig", "/sbin/ifconfig" }, Err parazyd.org 70 i { USER, GROUP, "ls", "/bin/ls" }, Err parazyd.org 70 i { USER, GROUP, "wifi", "/root/wifi.sh" }, Err parazyd.org 70 i- { USER, GROUP, "", ""}, // allow to run any program Err parazyd.org 70 i+ { USER, GROUP, "cp", "*"}, // allow to run this program in PATH Err parazyd.org 70 i+ { USER, GROUP, "*", "*"}, // allow to run any program in PATH Err parazyd.org 70 i { 0 }, Err parazyd.org 70 i }; Err parazyd.org 70 1diff --git a/sup.c b/sup.c /git/sup/file/sup.c.gph parazyd.org 70 it@@ -1,13 +1,14 @@ Err parazyd.org 70 i-/* pancake -- Copyleft 2009 */ Err parazyd.org 70 i+/* pancake -- Copyleft 2009-2011 */ Err parazyd.org 70 i Err parazyd.org 70 i #include Err parazyd.org 70 i-#include Err parazyd.org 70 i #include Err parazyd.org 70 i+#include Err parazyd.org 70 i #include Err parazyd.org 70 i+#include Err parazyd.org 70 i #include Err parazyd.org 70 i Err parazyd.org 70 i #define HELP "sup [-hlv] [cmd ..]" Err parazyd.org 70 i-#define VERSION "sup 0.1 pancake copyleft 2009" Err parazyd.org 70 i+#define VERSION "sup 0.1 pancake copyleft 2011" Err parazyd.org 70 i Err parazyd.org 70 i struct rule_t { Err parazyd.org 70 i int uid; Err parazyd.org 70 it@@ -19,11 +20,30 @@ struct rule_t { Err parazyd.org 70 i #include "config.h" Err parazyd.org 70 i Err parazyd.org 70 i static int die(int ret, const char *org, const char *str) { Err parazyd.org 70 i- fprintf (stderr, "%s%s%s\n", org, org?": ":"", str); Err parazyd.org 70 i+ fprintf (stderr, "%s%s%s\n", org?org:"", org?": ":"", str); Err parazyd.org 70 i return ret; Err parazyd.org 70 i } Err parazyd.org 70 i Err parazyd.org 70 i+static char *getpath(const char *str) { Err parazyd.org 70 i+ struct stat st; Err parazyd.org 70 i+ static char file[4096]; Err parazyd.org 70 i+ char *p, *path = getenv ("PATH"); Err parazyd.org 70 i+ if (path) Err parazyd.org 70 i+ for (p = path; *p; p++) { Err parazyd.org 70 i+ if (*p==':' && (p>path&&*(p-1)!='\\')) { Err parazyd.org 70 i+ *p = 0; Err parazyd.org 70 i+ snprintf (file, sizeof (file)-1, "%s/%s", path, str); Err parazyd.org 70 i+ if (!lstat (file, &st)) Err parazyd.org 70 i+ return file; Err parazyd.org 70 i+ *p = ':'; Err parazyd.org 70 i+ path = p+1; Err parazyd.org 70 i+ } Err parazyd.org 70 i+ } Err parazyd.org 70 i+ return NULL; Err parazyd.org 70 i+} Err parazyd.org 70 i+ Err parazyd.org 70 i int main(int argc, char **argv) { Err parazyd.org 70 i+ const char *cmd; Err parazyd.org 70 i int i, uid, gid, ret; Err parazyd.org 70 i Err parazyd.org 70 i if (argc < 2 || !strcmp (argv[1], "-h")) Err parazyd.org 70 it@@ -43,18 +63,25 @@ int main(int argc, char **argv) { Err parazyd.org 70 i gid = getgid (); Err parazyd.org 70 i Err parazyd.org 70 i for (i = 0; rules[i].cmd != NULL; i++) { Err parazyd.org 70 i- if (!rules[i].cmd[0] || !strcmp (argv[1], rules[i].cmd)) { Err parazyd.org 70 i+ if (*rules[i].cmd=='*' || !strcmp (argv[1], rules[i].cmd)) { Err parazyd.org 70 i #if ENFORCE Err parazyd.org 70 i struct stat st; Err parazyd.org 70 i- lstat (rules[i].path, &st); Err parazyd.org 70 i+ if (*rules[i].path=='*') { Err parazyd.org 70 i+ if (*argv[1]=='.' || *argv[1]=='/') Err parazyd.org 70 i+ cmd = argv[1]; Err parazyd.org 70 i+ else if (!(cmd = getpath (argv[1]))) Err parazyd.org 70 i+ return die (1, "execv", "cannot find program"); Err parazyd.org 70 i+ } else cmd = rules[i].path; Err parazyd.org 70 i+ if (lstat (cmd, &st) == -1) Err parazyd.org 70 i+ return die (1, "lstat", "cannot stat program"); Err parazyd.org 70 i if (st.st_mode & 0222) Err parazyd.org 70 i- return die (1, "stat", "Cannot run writable binaries."); Err parazyd.org 70 i+ return die (1, "stat", "cannot run writable binaries."); Err parazyd.org 70 i #endif Err parazyd.org 70 i if (uid != SETUID && rules[i].uid != -1 && rules[i].uid != uid) Err parazyd.org 70 i- return die (1, "urule", "User does not match"); Err parazyd.org 70 i+ return die (1, "urule", "user does not match"); Err parazyd.org 70 i Err parazyd.org 70 i if (gid != SETGID && rules[i].gid != -1 && rules[i].gid != gid) Err parazyd.org 70 i- return die (1, "grule", "Group id does not match"); Err parazyd.org 70 i+ return die (1, "grule", "group id does not match"); Err parazyd.org 70 i Err parazyd.org 70 i if (setuid (SETUID) == -1 || setgid (SETGID) == -1 || Err parazyd.org 70 i seteuid (SETUID) == -1 || setegid (SETGID) == -1) Err parazyd.org 70 it@@ -67,7 +94,7 @@ int main(int argc, char **argv) { Err parazyd.org 70 i if (chdir (CHRDIR) == -1) Err parazyd.org 70 i return die (1, "chdir", strerror (errno)); Err parazyd.org 70 i #endif Err parazyd.org 70 i- ret = execv (*rules[i].path? rules[i].path:argv[1], argv+1); Err parazyd.org 70 i+ ret = execv (cmd, argv+1); Err parazyd.org 70 i return die (ret, "execv", strerror (errno)); Err parazyd.org 70 i } Err parazyd.org 70 i } Err parazyd.org 70 .