Bugtraq mailing list archives

Re: Why are we using priveleged images / state so much? (Was Re:


From: fc () all net (Dr. Frederick B. Cohen)
Date: Thu, 6 Jul 1995 20:57:32 -0400


...
How about an explanation here by me, that seems to explain every single
security hole which compromised any system, that has ever existed:

   "You can't get blood from a turnip."
...
   "A computer program that lacks priveleges can't get priveleges
    unless some process that has them, gives them to that unpriveleged
    program.  Period.   Full stop.  There is no way for a process to give
    away what it does not have, and there never will be.  It has to have
    something or access to it, if it is to allow someone else to have or
    access it.  Without priveleges, a program can do only what it is
    permitted to do, and no more.  No matter how skilled, how capable,
    or how talented a programmer the creator of the program is, you
    can't get priveleges where they are nonexistent.  I would think this
    would be self-evident, but apparently it is not."

This is certainly an important source of problems, but not the only one.
For example, denial of services and corruption is often the result of
inadequate attention to those issues rather than some problem related
to excessive privilege.

...
It looks like people are making the same mistakes over, and over, and over
("Paul Robinson Presents The 'Energizer Bunny Theory of Programming
Errors': They keep going, and going, and going...:)), and not learning
from either history in general, or from the history of computing.  Maybe
this stuff isn't getting published, or maybe the people doing programming
don't do much reading of the literature, and maybe they don't do much
reading of books on theory and prior practices, or maybe some of the
people doing this work are not all that competent.  Or they don't care
much since they aren't being paid to do this work:

Indeed - the problem stems, at least in part, from inadequate education of
the last generation of programmers.

As far back as the 1960s people knew the dangers of running with
unnecessary priveleges.  Sometime during the 1970s or 1980s, I read a
book on operating systems design that said something like this:

In the 50s people began to consider this, in the 70s there were several
good papers on it, and by the early 1980's there had ben several books
and voluminous papers discussing this.

     "When designing a system section to do a task that requires privelege,
      isolate all sections that require privelege to one area of the code,
      enable privelege only for the absolute minimum time needed to read or
      write or update whatever it is that requires privelege to do, then
      as soon as possible, drop priveleges and go back.  As little of the
      system should run in priveleged mode as possible."

The so-called principle of least privilege - well known for a long time,
ignored, particularly by people who create prototype netork services
like gopher and W3 - then they fail - then after they fail, people like
us go and try to fix them - but by the time we hear about them, they are
so widespread that the fixes don't catch up to the holes for a long time.
It's a social problem.

You look at every major security hole that gave people ROOT priveleges or
other such things.  If there wasn't a way to get priveleges in the first
place, people couldn't have done things that way.  Let me make some
suggestions on how to fix the problem.

  1.  Don't have anything that is priveleged at all that runs directly from
      a user application.  Question: can a priveleged task change the state
      of some other task on the system, e.g. may process 14, a daemon running
      in the background, give process 9102 priveleges?  Or must that task
      (9102) be running a program which has setid root capability, e.g.
      the S bit in its execute value in the directory set?  If it can give
      priveleges to that task, let it do so for the exact minimum time
      needed and no longer, and possibly only exactly the priveleges that
      are needed.

This is more commonly done by passing arguments to a call from the requester
to the service running with privileges - and appropriately so.  Unfortunately,
the generation of DOS programmers don't understand this.

  2.  Does a task need to do something directly or does it simply need
      something done by some task on the system?   That's not an idle
      question.  If I need to get access to a file, can I have the system
      temporarily put me into a special group, then temporarily grant me
      read (or read/write) access to the group that that file is assigned
      to which happens to correspond to the group that I am temporarily
      running under?  E.g. assign every file on the system that isn't a
      priveleged image additionally to group "95" and the only time a
      process is in group 95 is when it asks to be assigned to it, and
      is there for one O/S instruction only.

This has been done in several applications - and in many cases, they
have failed because the "setuid" program was insecure.  A big problem is
that there are few well designed systems with well established criteria
for determining whether or not the privileged call is indeed secure.
Only provably correct systems have a hope of demonstrating this.

   3. Why does the FTP daemon need to have priveleges at all?

Because the way ports are deigned under Unix, you have to be root to get
things on these privileged ports.  A much better question might be: Why
do we run these processes on privileged ports instead of unprivileged
ports? Well, if you did that, any user could set up a daemon (which they
can do anyway) and open up a big hole.  An appropriate design MIGHT have
a special user ID for each daemon and only allow that daemon on that
port with only the privileges of the special user designated for the
daemon.  This is, in effect, one of the security precautions taken by
our recently designed secure http and gopher daemons.  It is implemented
by immediate chroot and setuid to the non-privileged user as soon as the
program starts, however, if the OS supported it, even this amount of
privilege would not be needed.

 A user dials
      in via the FTP port (21?) on an internet connection.  The daemon sees
      this and spawns a process to run it.  Why is it necessary that this
      process log in at all?

It's not, however, ftp was originally designed for normal users transfering
files between their accounts.  Anonymous ftp came later and the old protocol
was grandfathered in.  Once it became widespread, it was impossible to change
the whole world.

In effect, this is what gopher and http do - they don't require authentication
and perform essentially the same function as ftp.

 Why can't the spawned process run as user FTP
      with, say, only the priveleges of user FTP?

They can, and in our secure http and gopher daemon, they do.  They store
log files in the chroot area with access controls so that remote users
cannot see the log files unless they are setup for world read.

Part of the problem stems from the designers of these services having a
convoluted sense of protection.  Instead of using the features of the OS
designed for protection, they go off and create novel protection schemes
without the knowledge spawned by years of experience by real experts.  The
result is this foolishness we see.

Have the spawning process
      (which might not need to be priveleged) log the access to the system
      log, and the spawned process, if it has to have access to the private
      unshared files of a specific user (non-'anonymous' FTP), issue a
      request to have its process name changed to that user, and the
      daemon that does that checks to see that user 'FTP' (notice I use
      capital letters, since 'real' logins on unix systems usually use
      lower case only, if I remember correctly), was asking for the
      service, it would know this was the Pseudo-user FTP which was
      asking for the request.  (Or follow the 'ps' program chain and
      see that the 'parent' of that task/process is the FTP daemon, or
      the Grandparent is the daemon spawner, which does run priveleged to
      spawn tasks under different usernames, or maybe IT doesn't have to
      either, since its username is DAESPAWN (also caps), and the same
      thing is done for it, etc.

No reason to be that complex.  It can be done far more simply and securely.

   4. The login programs can be set up to automatically force a username
      to lower case when the name is accepted, and unless the job issuing
      the spawn is priveleged, a request for the Login service or spawn
      job under new username (if such exists), a username which is
      capitals is forced to lower case or it is set up to do so if it is
      requested by any task except task 1.  So only the initial task
      which starts the system is priveleged, only it can create
      priveleged tasks, and everything else runs nonpriveleged unless it
      requests privelege from task 1 or the O/S and is entitled to do so.

Certain things require privilege, such as the creation of file systems,
moving information between users, system services, etc.  Unfortunately, we
rarely enforce least privileges because it's almost always easier to make
any program needing any privilege run as root.  It makes it work, even if it
introduces big holes.  It's harder to do things well than poorly.

  5.  Force priveleged tasks to 'no error recovery'.  If any error occurs
      at all in a priveleged task, such as asking for a file that isn't
      there, or whatever, that error automatically forces the task to be
      unconditionally killed.  If a program needs to check for a file, it
      can request it from the system if it is running with the right to
      check that file.  When it needs to open the file, it can request
      a privelege to open that file or be handed the file handle already
      open from a priveleged 'file opener' task.  This would make trying
      to get a privelege by winning a race condition almost impossible,
      would it not?

There is the more general issue of resource allocation being a problem.
One cure (that most people shun and criticize in others) is not using
allocation in your program - all static variables, etc.  It's hard to do
with some system services, but it eliminates much of the error complexity.
The secure http and gopher daemons use this to some extent and always
fail with termination and an error return.

...
  6.  Think about how often are jobs left running with constant
      priveleges when they need them once during the start of the job, and
      maybe once at the end?

Almost guaranteed they do not need privilege at the end if you do it
right.  Design so that all privileged operations can happen in the first
few instructions and eliminate the overhead and complexity of having to
return to a privileged state.  It's much safer.

...
      want to puke.  Device drivers need I/O priveleges for the devices
      they run AND NO OTHER PRIVELEGES.  Writing to user memory can be
      done by a special priveleged task when needed, or the memory area
      of the user's buffer can be elided to by overlaying a new descriptor
      giving the device driver read/write priveleges on that user's
      memory space in that area, and only that area.

But time is often of the essence, and programmers often trade time for protection.

  8.  I believe I am being reasonable in my expectations.  I do not think
...

I agree, but almost all programming shops and IT managers do not.  Info-sec
is a specialized field that too few know about.  We need education.

  9.  Nobody says we have to slow down user programs, we can find ways to
      only use priveleges when absolutely necessary.  Perhaps, during
      initialization, all priveleged functions (opening a special private
      file, opening a port on the network, or whatever) can be activated,
      then the process can permanently drop all priveleges since it will
      no longer need any priveleges (I am assuming that if you do
      something such as open a file when priveleged, that you would not
      normally have access to that file when not priveleged, that the
      open and read/write capability to that file remain even if the task
      permanently and irrevocably dismisses its priveleges.

Or you can do even better as some examples above try to point out.

If stuff like this had been done, I think the number of accidental root
or priveleged access holes would be reduced to maybe 1% of what they have
been.

And then nobody would continue doing them because they cost time and money
and no known breakins would lead people to believe they didn't need security.
It's a catch 22!

Hmm.  Why does ROOT even have to be on the system as a user account?
There are some things people have to do as root, but why not request
special programs (like 'Shutdown') or other features, to be set up to
allow only users in a certain class or certain userid to do them.

This is done in some secure OSs, however, there are legitimate needs to
alter the system operation at some level, and whatever level that is,
that is where problems will start to pop up.

For example, the only user that can do a shutdown is user SHUTDOWN, their
login shell is a procedure that asks some questions that only admin
people could know, and if approved, runs the program(s) to begin an
orderly shutdown.  Emergency shutdown can be done from any admin account
in the correct group, and/or only certain users, perhaps special
priveleges.

That is done in most Unix systems, but root users abuse the privilege.

There are other ideas that might be even better.  Let's just ask, does
something need privelege to do this, can we get in, get it done, and get
the hell out fast?  What other options do we have besides staying
priveleged constantly?

There are also systems that implement POsets so that privilege can be
divided.  This is especially effective in networks where there is no SUP
or INF.  I published several journal articles on this in the 80s, so did
Dorathy Denning in the early 80s.  But it's not as easy to work in a
well disciplined system as in a poorly disciplined system.  You have to
think about what you are doing all the time and consider the implications.
Few programmers and sysops are able or willing to do this.

We do not want ask "Will this code need priveleges?"  What we want to ask
is, "Must this code have priveleges, why and when, and if so, how can we
make that priveleged state as short a period of time as possible?"

Agreed.

I would love to hear questions, new ideas, or comments.  Privately or to
the list.

You got-em.

--
-> See:  Info-Sec Heaven using our New Super Secure World-Wide-Web Server
-> Free: Test your system's security (scans deeper than SATAN or ISS!)
---------------------- both at URL: http://all.net ----------------------
-> Read: "Protection and Security on the Information Superhighway"
         John Wiley and Sons, 1995 ISBN 0-471-11389-1, 320 pp, $24.95
-------------------------------------------------------------------------
   Management Analytics - 216-686-0090 - PO Box 1480, Hudson, OH 44236



Current thread: