t* Initial import of 'sup' into mercurial - sup - small tool for privilege escalation
 (HTM) git clone https://git.parazyd.org/sup
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 989bc1c744d8fe03a58692410a6d68ad00a872c8
 (HTM) Author: pancake@dazo <unknown>
       Date:   Mon, 14 Dec 2009 01:02:07 +0100
       
       * Initial import of 'sup' into mercurial
       Diffstat:
         A Makefile                            |      31 +++++++++++++++++++++++++++++++
         A TODO                                |       1 +
         A config.def.h                        |      18 ++++++++++++++++++
         A sup.1                               |      23 +++++++++++++++++++++++
         A sup.c                               |      72 +++++++++++++++++++++++++++++++
       
       5 files changed, 145 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -0,0 +1,31 @@
       +CC?=gcc
       +DESTDIR?=
       +PREFIX?=/usr
       +VERSION=0.1
       +USER=root
       +GROUP=root
       +
       +all: config.h sup
       +
       +config.h:
       +        cp config.def.h config.h
       +
       +sup.o: config.h sup.c
       +        ${CC} -c sup.c
       +
       +sup: sup.o
       +        ${CC} sup.o -o sup
       +
       +clean:
       +        rm -f sup.o sup
       +
       +mrproper: clean
       +        rm -f config.h
       +
       +install:
       +        mkdir -p ${DESTDIR}${PREFIX}/bin
       +        cp sup ${DESTDIR}${PREFIX}/bin
       +        chown ${USER}:${GROUP} ${DESTDIR}/${PREFIX}/bin/sup
       +        chmod 4111 ${DESTDIR}${PREFIX}/bin/sup
       +        sed s,VERSION,${VERSION}, sup.1 \
       +          > ${DESTDIR}${PREFIX}/share/man/man1/sup.1
 (DIR) diff --git a/TODO b/TODO
       t@@ -0,0 +1 @@
       +* Enforce with checksums (sha1?)
 (DIR) diff --git a/config.def.h b/config.def.h
       t@@ -0,0 +1,18 @@
       +#define USER 1000
       +#define GROUP -1
       +
       +#define SETUID 0
       +#define SETGID 0
       +
       +#define CHROOT "/"
       +
       +#define ENFORCE 1
       +
       +static struct rule_t rules[] = {
       +        { USER, GROUP, "whoami", "/usr/bin/whoami" },
       +        { USER, GROUP, "ifconfig", "/sbin/ifconfig" },
       +        { USER, GROUP, "ls", "/bin/ls" },
       +        { USER, GROUP, "wifi", "/root/wifi.sh" },
       +        { USER, GROUP, "", ""}, // allow to run any program
       +        { 0 },
       +};
 (DIR) diff --git a/sup.1 b/sup.1
       t@@ -0,0 +1,23 @@
       +.TH SUP 1 sup\-VERSION
       +.SH NAME
       +sup - scale user priviledges
       +.SH SYNOPSIS
       +.B sup
       +.RB [ \-hlv ]
       +.SH DESCRIPTION
       +sup is a minimal priviledge scalation utility that allow normal
       +users to run other programs as different user and group.
       +.P
       +The configuration is done in config.h at compile time.
       +.SH OPTIONS
       +.TP
       +.B \-h
       +print help message
       +.TP
       +.B \-l
       +list command whitelist
       +.TP
       +.B \-v
       +prints version information
       +.SH AUTHOR
       +pancake <nopcode.org>
 (DIR) diff --git a/sup.c b/sup.c
       t@@ -0,0 +1,72 @@
       +/* pancake <nopcode.org> -- Copyleft 2009 */
       +
       +#include <stdio.h>
       +#include <errno.h>
       +#include <string.h>
       +#include <sys/stat.h>
       +
       +#define HELP "sup [-hlv] [cmd ..]"
       +#define VERSION "sup 0.1 pancake <nopcode.org> copyleft 2009"
       +
       +struct rule_t {
       +        int uid;
       +        int gid;
       +        const char *cmd;
       +        const char *path;
       +};
       +
       +#include "config.h"
       +
       +static int die(int ret, const char *str) {
       +        fprintf (stderr, "%s\n", str);
       +        return ret;
       +}
       +
       +int main(int argc, char **argv) {
       +        char *cmd;
       +        int i, uid, gid, ret;
       +
       +        if (argc < 2 || !strcmp (argv[1], "-h"))
       +                return die (1, HELP);
       +
       +        if (!strcmp (argv[1], "-v"))
       +                return die (1, VERSION);
       +
       +        if (!strcmp (argv[1], "-l")) {
       +                for (i = 0; rules[i].cmd != NULL; i++)
       +                        printf ("%d %d %10s %s\n", rules[i].uid, rules[i].gid,
       +                                rules[i].cmd, rules[i].path);
       +                return 0;
       +        }
       +
       +        uid = getuid ();
       +        gid = getgid ();
       +
       +        for (i = 0; rules[i].cmd != NULL; i++) {
       +                if (!rules[i].cmd[0] || !strcmp (argv[1], rules[i].cmd)) {
       +#if ENFORCE        
       +                        struct stat st;
       +                        lstat (rules[i].path, &st);
       +                        if (st.st_mode & 0222)
       +                                return die (1, "Cannot run writable binaries.");
       +#endif
       +                        if (uid != SETUID && rules[i].uid != -1 && rules[i].uid != uid)
       +                                return die (1, "User does not match");
       +
       +                        if (gid != SETGID && rules[i].gid != -1 && rules[i].gid != gid)
       +                                return die (1, "Group id does not match");
       +
       +                        if (setuid (SETUID) == -1 || setgid (SETGID) == -1 ||
       +                            seteuid (SETUID) == -1 || setegid (SETGID) == -1)
       +                                return die (1, strerror (errno));
       +#ifdef CHROOT
       +                        if (chroot (CHROOT) == -1)
       +                                return die (1, strerror (errno));
       +#endif
       +                        ret = execv (rules[i].path? rules[i].path:argv[1], argv+1);
       +                        return die (ret, strerror (errno));
       +                }
       +        }
       +
       +        return die (1, "Sorry");
       +}