Re: Privilege-escalation attacks on NT-based Windows are unfixable

From: Barry Margolin (barmar@genuity.net)
Date: 08/23/02


From: Barry Margolin <barmar@genuity.net>
Date: Fri, 23 Aug 2002 20:00:27 GMT

In article <vZu99.981$rO3.113580119@newssvr30.news.prodigy.com>,
Alun Jones <alun@texis.com> wrote:
>At some point, the application programmers have got to stop saying "the
>operating system / programming language _let_ me do something stupid - waah!",
>and admit that many of the mistakes we make and inflict on the world are
>because we weren't thinking completely at the time of writing the code.

Right.

The DoD commissioned the creation of Ada because they wanted a programming
language that made it difficult for programmers to get around the
safeguards. They were expecting it to become the de facto standard
programming language. But hardly anyone uses it unless they're forced to
by contract. Many programmers rebel against being forced into a
straightjacket by B&D languages like this. Unfortunately, when they use a
language that gives them lots of rope, they tend to hang themselves with
it.

You can't have it both ways: demanding a simple, flexible language, and
then complaining that it doesn't protect you from all your mistakes. C
*has* improved over the years; ANSI C added prototypes, which allow for
better cross-module type checking, and functions like strncpy() have been
added (but it's still the programmer's responsibility to keep track of the
size of the destination, and to remember to call this instead of strcpy()).
But unless you switch to C++ and its bloated STL, you're stuck with many of
C's fundamental design limitations.

Getting back to Windows, there's a similar thing going on. It provides a
relatively simple, powerful API for communications between applications.
This API is very useful for most applications, and allows them to be
developed quickly. But when you're developing a privileged application,
you have to take extra care. An API appropriate for an ordinary program
may not be a good fit for a privileged one, because many of its convenience
features make assumptions that are no longer valid. When a program is
privileged, it necessarily takes on some of the security checking roles
that the OS normally performs (I'm reminded of a saying that usually refers
to society: with great privilege comes great responsibility). This is
likely to mean that it can't make as much use of the convenient API.

There *is* something paradoxical about this. As we know, the more complex
a program is, the harder it is to make it correct and secure. The KISS
principle is quite important in security -- if you don't understand what
you're doing, how can you be sure you have't left a security hole? But if
you can't make use of all the automation that the API provides, your
program is made necessarily larger and more complex. For instance, if you
take the route of splitting the application into two processes, an
unprivileged GUI and a privileged server, you have to design and implement
a communications protocol between them, and you have to ensure that *this*
is secure.

In a perfect OS, you wouldn't have a binary privileged/unprivileged
dichotomy: processes would be given access to specific resources, and they
couldn't be used to get around other, unrelated protections. But
capabilities-based operating systems like this have rarely been successful
in the mainstream. Multics had multiple privilege levels, but it was a
hierarchical structure (ring N has access to everything in rings >N),
rather than mutually-suspicious categories. Unix occasionally does this
with set-gid programs, or programs set-uid to someone other than root, but
for the most part there are just two practical privilege levels: ordinary
user and superuser.

-- 
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.