Bugtraq mailing list archives

Re: IRIX 5.2 Security Advisory


From: max () gac edu (max () gac edu)
Date: Tue, 9 Aug 94 15:18:35 -0500


   Newsgroups: comp.sys.sgi.admin,comp.sys.sgi.bugs
   From: Steve Kotsopoulos <steve () ecf toronto edu>
   Date:        Tue, 9 Aug 1994 09:44:19 -0400

   I am cc'ing this update to several mailing lists the advisory has been
   forwarded to since last week. 

Likewise.

   ...
   : If we told you what the problem was, then you might go break into other
   : machines. That wouldn't look good for SGI. ...

When the truth comes out, this *isn't* going to look good for SGI,
period.  This is an ugly bug. As the source at SGI wrote

   : It's such
   : a quiet little hole that it doesn't leave a mark anywhere. You don't
   : even have to logon to exploit it. That's how bad it is. ...

   Corrections and updates to the above information is encouraged.

OK, here comes a big update [well, 1 and 2 are somewhat old news; 3 is
the real news].

1) The problem would allow even people who couldn't logon to become
   root. [As per the SGI source, above.]  However, it could also be
   exploited in a slightly different way by those who had already
   logged on as normal users to become root.

     **** The SGI official patch of removing ViewerHelp only stops
          the non-logged in; normal users can still become root. ****

2) As I posted before, renaming /usr/sbin/sgihelp out of existance
   will stop both variants; however you lose all 'desktop help'.  See
   below for a better option.

3) I enclose below a wrapper program for sgihelp that will stop both
   the logged-in and the non-logged-in variant without losing help.
   You mv /usr/sbin/sgihelp to /usr/sgihelp.real, and then install the
   compiled wrapper program as /usr/sbin/sgihelp.  No guarantees, but
   it seems to do the trick.

/* A security wrapper for sgihelp, written 8/9/94 by Max Hailperin
   <max () gac edu>.  Sets the effective uid and gid back to the real ones,
   unless that is 0 (root), in which case nobody is used instead.
   (See code for details.) Public domain, no warranty of any kind. */

/* configuration options: 

     REAL_SGIHELP is the pathname of what used to be /usr/sbin/sgihelp
       [i.e., mv /usr/sbin/sgihelp to this path, then install this
        wrapper program as /usr/sbin/sghihelp] */

#define REAL_SGIHELP "/usr/sbin/sgihelp.real"

/* BLOCK_HASH is the hashcode for a certain program from which sgihelp
     access should be disallowed; either it should be defined or
     sgihelp.books.ViewerHelp should be removed as SGI recommended.
     Otherwise, a security violation will still be possible (though
     not as severe a one as without this wrapper program).

     Either way you lose something; with BLOCK_HASH defined, there is
     no help available from that one program (though it is one very
     few people need help with).  With ViewerHelp removed, you can't get
     help on the help viewer. Personally I prefer BLOCK_HASH as the
     lesser evil. */

#define BLOCK_HASH 636

#include <sys/types.h>
#include <unistd.h>
#include <limits.h>

#ifdef BLOCK_HASH
#include <sys/procfs.h>
#include <fcntl.h>
#include <stdio.h>
#endif

main(int argc, char *argv[], char *envp[]){
  setgid(getgid());
  setuid(getuid());
  if(getuid() == 0){
    /* if the real uid is 0 (root), then as a special case we setuid
       to -2 (nobody) rather that 0 because some setuid root programs
       once they have effective uid 0 then use that priviledge to set
       their real uid to 0 as well; thus a real uid of 0 may not mean
       that the real user is root, but possibly just that such a
       program is an ancestor; running as nobody is unlikely to cause
       many problems for real root users and protects against the kind
       of programs mentioned above. Since uids are mod UID_MAX+1,
       -2 => UID_MAX-1. */
    setuid(UID_MAX-1);
#ifdef BLOCK_HASH
    {int fd;
     char fname[256], *cp;
     unsigned hash = 0;
     struct prpsinfo info;
     sprintf(fname, "/proc/pinfo/%05d", getppid());
     if((fd = open(fname, O_RDONLY)) < 0)
       exit(1);
     if(ioctl(fd, PIOCPSINFO, &info) < 0)
       exit(1);
     for(cp = info.pr_fname; *cp; cp++)
        hash += *cp;
     if(hash == BLOCK_HASH)
       exit(1);
   }
#endif
}
  execve(REAL_SGIHELP, argv, envp);
  exit(1);
}



Current thread: