[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: possible problem with new perl, libc6 on Sep 23rd



Ben Collins wrote:
> Now when dpkg first unpacks a package, it replaces binaries by first,
> chmod 600 on the binary (I'm not sure why, but it does), then unlinking
> it.

The reason why dpkg does this is because of a neat little hard link exploit.

joey@kite:/tmp>ln /usr/gamesxthrust
joey@kite:/tmp>ls -l xthrust 
-rwxr-sr-x   2 root     games      251984 Sep 20 20:45 xthrust*

Now if a bug is found in xthrust that lets me get access to the games group,
the sysadmin quickly fixes it by installing a new binary. But I already have
made a hard link to the old one (and note the hard link has the same
permissions), so I can log in and run it at my leisure later and exploit the
hole. Of course, this works for suid executables too.

The fix is to clear the suid and sgid bits of the binary before you delete
it. So when dpkg goes in and upgrades xthrust, it first chowns the old file,
and I end up with just this, which isn't helpful to me as a cracker:

joey@kite:/tmp>ls -l xthrust
-rw-------   2 root     games      251984 Sep 20 20:45 xthrust

Now, what confuses me is why dpkg is doing this to perl, which isn't suid or
sgid at all. The dpkg code uses this:

int chmodsafe_unlink(const char *pathname) {
  struct stat stab;
  
  if (lstat(pathname,&stab)) return -1;
  if (S_ISREG(stab.st_mode) ? (stab.st_mode | 07000) :
      !(S_ISLNK(stab.st_mode) || S_ISDIR(stab.st_mode) ||
   S_ISFIFO(stab.st_mode) || S_ISSOCK(stab.st_mode))) {
    /* We chmod it if it is 1. a sticky or set-id file, or 2. an unrecognised
     * object (ie, not a file, link, directory, fifo or socket
     */
   if (chmod(pathname,0600)) return -1;
  }
  if (unlink(pathname)) return -1;
  return 0;
} 

-- 
see shy jo


Reply to: