Bugtraq mailing list archives

Re: Wiping out setuid programs


From: smb () RESEARCH ATT COM (Steven M. Bellovin)
Date: Sat, 9 Jan 1999 18:13:01 -0500


In message <19990109105854.3085.qmail () cr yp to>, "D. J. Bernstein" writes:

...

What's left is a tiny percentage of today's setuid code: the part that
reads untrusted user data. Securing this code against local attackers is
just like securing network code against remote attackers.


For comparison, here's the idea mentioned by Steve Bellovin. Put your
restricted file into a protected directory. Change its mode to 777. Now
the setuid program can

  (1) chdir() to the protected directory,
  (2) setuid(getuid()), and
  (3) read and write the restricted file.

Does this idea reduce the amount of security-critical code? Does it save
time for security reviewers? Can the programmer relax?

No! Step #3 no longer has a privileged uid but it still has a privileged
cwd. The attacker is still trying to convert his control over portions
of the process state into control over the restricted file. This idea is
like replacing setuid with setgid: it might turn a disaster into a
marginally less impressive disaster, but it makes no contribution to the
goal of eliminating all disasters.

There are many different levels of problem.  Dan is certainly correct that
the scheme I suggested is useless if, say, the privileged program can
be tricked into providing the user with a shell inside the locked area.
Unfortunately, I don't share his conviction that daemon access is a
panacea.

First, of course, there's the problem of contacting the daemon.  There
are ample opportunities for denial of service from half-open connections,
to say nothing of dead daemons, daemons that didn't start, careless programmers
who use Internet sockets as RPC mechanisms -- and, on many platforms, the
utterly buggy implementation of UNIX domain sockets and (especially) file
descriptor passing.

Second, and more serious, connection-based programs are just as subject
to data-driven attacks as are setuid programs.  Look at all of the remote
attacks on sendmail, or all the buffer overflows!  Some of the former are
actually more interesting, since they relied on the attacking program
manipulating the data sent to sendmail to corrupt the spool files -- i.e.,
things like embedded newlines.

That said, Dan is right -- connections are good for security for the same
reason that system calls are; they provide a very narrow communications channel
between the potentially malicious user and the privileged (in the sense of
having access to some sensitive resource) program.  Anything that narrows
that pipe is good.  As Dan noted, the problem with set[ug]id programs is that
the resources they rely on are not always obvious -- for example, they
themselves may not call getenv(), but if crt0.o does (and that has happened),
you're toast.

Finally, Dan bemoaned my suggestion as not making a contribution towards
the goal of elminating all disasters.  Quite true -- but I don't think there's
any way to do that.  As best I can tell, there are no panaceas in the
security world.  There are tools, techniques, good programmers, and gurus --
and all of them have their limits.  We can use string-safe languages like
Java, and we can store temporary files in some place that isn't world-writable -- and then we can trip over bizarre 
host names, inappropriate code paths that
allow for command execution in the wrong spot, etc.  Privileged programs
demand their own individual analysis and design; it can't be done by
cookbook.



Current thread: