Re: Security problems on SCO's lp subsystem

From: Bela Lubkin (belalat_private)
Date: Fri Jun 19 1998 - 12:42:46 PDT

  • Next message: Il Oh: "protocol 191 clarification"

    Thanks to Marco Paganini & Michael L. Wilkerson Jr. for this report.
    
    I've verified these two problems.  Note that both of them require
    special enabling conditions, which I describe below.
    
    SCO OpenServer includes two spooling subsystems: the System V spooler
    and the Berkeley spooler.  Berkeley spooler support is split into client
    and server support.  By default, only SysV client support is active.
    Berkeley client support is activated by root running `mkdev rlp`; or
    through `scoadmin printer manager` (I haven't tested, but I believe the
    option is "Printer -> Add Remote -> UNIX...").
    
    Activating Berkeley client support causes certain binaries to change;
    for instance, /usr/bin/lp changes from:
    
      ---x--s--x   1 bin      lp         91044 Dec 16  1997 /usr/bin/lp
    
    to:
    
      ---x--x--x   1 bin      lp          2472 Jun 19 11:09 /usr/bin/lp
    
    Exact dates and sizes will vary by release, but the general pattern will
    be the same.  The Berkeley client version is a simple wrapper program
    which actually execs /usr/lpd/remote/lp:
    
      -rws--s--x   1 root     daemon     36116 Dec 16  1997 /usr/lpd/remote/lp
    
    If a Berkeley client destination hasn't been specified, that in turn
    execs the original SysV lp client, which has been saved aside in
    /usr/lpd/local:
    
      ---x--s--x   1 bin      lp         91044 Jun 19 11:09 /usr/lpd/local/lp
    
    Also, in general, /etc/printcap will exist if and only if Berkeley
    client support has ever been activated.
    
    Both of these exploits require Berkeley client support to be active,
    although the details are different.
    
    #1:
    
    > SCO 5.0.4 Enterprise
    >         (also) Plain Vanilla Intel
    >
    > as root...
    >         echo "test" > /tmp/rootfile
    >
    > and the perms thereof are...
    >
    >         drwxrwxrwt   2 sys      sys          1024 Jun 18 20:26 tmp
    >
    >         and
    >
    >         -rw-rw-r--   1 root     sys             5 Jun 18 20:26 rootfile
    >
    > okay. now as a normal, unprivileged user, I run...
    >
    > lpr -d lp -R /tmp/rootfile
    >
    > ...and to my displeasure, but as expected, the root-owned tempfile is
    > removed.  (BTW, this normal user is NOT a member of the group, sys --of course).
    
    This exploit only works if the destination is a Berkeley lpd client.  In
    practice this means that (1) /etc/printcap must exist, (2) it must have
    an entry for the destination ("-d lp"), and (3) the spool directory
    mentioned in the printcap entry must exist.  These conditions normally
    exist only if Berkeley client support has deliberately been activated by
    root.
    
    #2:
    
    > >This is even better, but only works if your lp subsystem has a file named
    > >/var/spool/lpd/lock. With this file in place, the lp command will enable
    > >the "-L live" option. With this, you can write to *any* file in the system.
    > >And even better, the file will be mode 600, owned by root...
    > >
    > >Just do:
    > >$ lp -L live=/any_file_in_the_system
    > >blablabla
    > >^D
    > >
    > >And that's it. You can type anything you want/need.
    >
    > One more time!
    >
    > running "touch /var/spool/lpd/lock"
    > yields:
    >         -rw-rw-r--   1 root     sys             0 Jun 18 20:41 /var/spool/lpd/lock
    >
    > ...now as the same normal user I run (with rootfile being an as of yet
    > non-existing file)
    >
    >         lp -L live=/tmp/rootfile
    >
    > Okay, then I enter whatever text I choose...and a ^D and bingo!
    > now "ls -l /tmp/rootfile" yields:
    >         -rw-------   1 root     lp             21 Jun 18 20:45 rootfile
    >
    > Of course, the same normal user which created the file can now not even read it.
    
    Again, this depends on the Berkeley client support being enabled.
    
    The actual "-L=live" support is in the SysV client.  However, it looks
    for a file (/usr/spool/lpd/lock -- /var/spool is a symlink to
    /usr/spool) which exists only when the Berkeley client is enabled.
    Specifically, the directory /usr/spool/lpd is created by the Berkeley
    client install; and /usr/spool/lpd/lock is created temporarily by
    Berkeley client actions.  The permissions on /usr/spool don't allow
    users to create subdirectories; and /usr/spool/lpd's permissions do not
    allow users to create the lock file, except as a temporary byproduct of
    client actions.
    
    Even if you deliberately create /usr/spool/lpd/lock while the Berkeley
    client isn't enabled:
    
      # mkdir /usr/spool/lpd
      # touch /usr/spool/lpd/lock
    
    `lp -L live=filename` can only attack files writable by group "lp".  The
    root attack works because of the changed flow of control when Berkeley
    client support is enabled.  /usr/bin/lp execs /usr/lpd/remote/lp,
    gaining setuid-root privileges.  That then execs /usr/lpd/local/lp,
    which is the original SysV lp client.
    
    I would summarize these bugs as:
    
      1. Berkeley `lp` client doesn't give up setuid/setgid privileges when
         removing a file according to "-R" flag.
    
      2. Berkeley `lp` client passes on setuid/setgid privileges to SysV
         `lp` client, when a Berkeley lpd destination hasn't been specified.
    
      3. SysV `lp` client doesn't give up setuid/setgid privileges before
         opening target file for "-L live=file" flag.
    
      4. "-L live=file" flag appears to be archaic, perhaps shouldn't exist
         at all?
    
    Not a pretty picture.  I'll look into getting these fixed, and checking
    for other related issues in these subsystems.
    
    >Bela<
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:58:55 PDT