0x4E/setuid-wrapper

This is example source code for a setuid wrapper program. The basic idea is that the setuid C program becomes root, and then simply executes another program.

Download setuid-wrapper.c

/*****************************************************************************
 * setuid-wrapper.c                                                          *
 *                                                                           *
 * This is a setuid program that simply becomes root and calls the           *
 * given script / executable.                                                *
 *                                                                           *
 * cc -Wall --pedantic --ansi --static setuid-wrapper.c -o setuid-wrapper    *
 * cp setuid-wrapper /usr/local/bin/setuid-wrapper                           *
 * chown root:mygroup /usr/local/bin/setuid-wrapper                          *
 * chmod 4750 root:mygroup /usr/local/bin/setuid-wrapper                     *
 ****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

/* the name of this wrapper program */
#define PROGRAM_NAME "setuid-wrapper"

/* the command to execute */
#define CMD_PATH "/usr/local/bin/path-to-script"

/* environment variable pointer */
extern char **environ;

/* FUNCTION PROTOTYPES */
int setenv(const char *name, const char *value, int overwrite);
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);

/* MAIN PROGRAM */
int main(int argc, char *argv[]) {
    char *cmd[2];

    /* clear all existing environment variables */
    environ = NULL;

    /* overwrite the PATH environment variable with something sensible */
    setenv(
        "PATH",
        "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
        1
    );

    /* set real and effective uid and gid all to root */
    setreuid( 0, 0 );
    setregid( 0, 0 );

    /* exec command */
    cmd[0] = CMD_PATH;
    cmd[1] = NULL;
    execve(cmd[0], cmd, NULL);

    /* if it worked, this program has now been replaced with the script */
    /* if it didn't work, show an error message and exit with an error code */
    fprintf(stderr, "%s: could not execute %s\n", PROGRAM_NAME, cmd[0]);

    return 1;
}