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

From: Alun Jones (alun@texis.com)
Date: 08/27/02


From: alun@texis.com (Alun Jones)
Date: Tue, 27 Aug 2002 13:24:46 GMT

In article <akfme3$16j$1@aquila.mdx.ac.uk>, david20@alpha2.mdx.ac.uk wrote:
>In article <sZva9.5331$M25.2353748105@newssvr11.news.prodigy.com>,
> alun@texis.com (Alun Jones) writes:
>>In article <akdqjm$ce2$1@aquila.mdx.ac.uk>, david20@alpha1.mdx.ac.uk wrote:
>>>I do apologise for not making clear that I expected that hypothetical
> turn-off
>>>privs call to be made as the first call in the program ie before any windows
>>>were opened, input accepted etc. This is very similar to one of the
> "solutions"
>>>suggested where each application would have to set itself up to handle the
>>>incoming windows messages. If it did it after the window was opened then
> there
>>>would be a small period where the windows message would be handled by the
>>>default library.
>>
>>You don't write Windows programs, do you? It's not like there's some mystic
>>juju that calls GetMessage until such time as your application does. It's
>>your application that calls GetMessage to get the first message, and it's your
>>application that calls TranslateMessage to decode keypresses, and calls
>>DispatchMessage to send the message on to whichever window procedure it needs
>>to go to. Any filtering that goes after GetMessage and before DispatchMessage
>>(in every message loop that you have, if your app has more than one - MFC apps
>>do, for instance) _will_ get every message.
>
>Except that in this case as I understand it from previous posts this is by
>default bypassing the application.
>If your application doesn't setup something to handle WM_TIMER then it is
>allowing code to be executed which shouldn't be executed.

That's not the same as it being unable to be caught by your application.

Every window message goes through your app's message loop. A typical message
loop runs like this:

BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
// A good place to filter WM_TIMER.
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

By the time you've reached GetMessage, you have called CreateWindow, to assign
at least one window and its default window procedure, but the messages are sat
waiting in that queue until a part of your process calls GetMessage.
CreateWindow does not spawn off a separate process, as your assumption would
require. The WM_TIMER message _can't_ be processed until the DispatchMessage
call, and can be thrown out at any time after the GetMessage call by finding
some way to skip the call to DispatchMessage. A simple "if
(WM_TIMER==msg.message) continue;" would work in the above example, where I've
marked as a good place to filter WM_TIMER.

>Lets try this a different way.

Is it really different?

>Defining in documentation that the security boundary is the desktop in no way
>relieves the OS of the responsibility of policing that security boundary !!!

And it does. You can't punch through the boundary unless you have the
appropriate privilege. That means that you can't create a window on the
user's desktop without either being the user, or having the privilege to
access the desktop. In the former case, there's no security issue, and in the
latter, one assumes that a privileged process wanting to break a security
barrier would know what it was doing, and take appropriate precautions.

>This is NOT impossible for Windows to have done. Fixes range from
>redesigning the API to be more like X-windows, appending identification
>information to windows messages and requiring applications to explicitly
>state from which sources they will accept messages, banning applications from

My experience is that many of the programmers that we seem to be stuck with in
the Windows world would simply "explicitly state" that they'd like to accept
messages from all sources.

>directly opening windows on a user's desktop unless they are running in the
>user's context - thereby forcing the writers of privileged applications to
>split the application into an unprivileged user interface running in the
>user's context and a privileged program communicating via another IPC.
>
>Windows could have done any of these, plus probably quite a few other things,
>to protect itself from this security boundary. It didn't do any of these
>things.

Because it has the concept that a process with privilege X can do action X.
Unix could have had privileges, too, for example, but it didn't. It has users
and it has root. root can do damn near anything, which is one reason why Unix
privilege escalation attacks are so devastating. Each OS makes its own
decision. You write your applications for the OS that you're targetting, not
some idealised "wouldn't it be nice if" operating system that nobody has yet
made.

>See above. I don't care which methodology windows were to choose to control
>access across this security boundary just that they have some control in place.

They do. Only the desktop's owner or a process running in the LocalSystem
context, or a process that has been granted access to the desktop by the
desktop's owner, may open a handle to the desktop, and thus create a window.

>Until they do, whilst they rely on the application writer to "do the right
>thing" without providing mechanisms which force him to "do the right thing",
>then Windows is not a secure OS.

Not to pick on Unix, just that it's the other OS that I'm most familiar with
(and that's not saying a lot), but how much does Unix "provide mechanisms
which force" the author of a setuid-root process to "do the right thing"?

>Since "Shatter" and WM_TIMER are the meat of this discussion I cannot see how
>you can make any arguments which start off by dismissing them.

Because the WM_TIMER function can be fixed in the OS as well as be worked
around easily in any application. The argument is that the OS is unfixably
flawed. A simple patch to SetTimer and DefWindowProc would prevent the
"Shatter" attack. Therefore, the OS is not unfixably flawed. However, the
security model is obviously being overridden on a casual basis by application
developers that ought to know better. That is a problem worth discussing.

>Since a user can use Shatter and WM_TIMER to execute arbitrary code in the
>process space of another process - whether higher privileged or not -
>segregation has been breached. If the process being attacked has higher
>privileges then privilege escalation occurs which allows the attacker to
>subvert the TCB.

The segregation was breached by the application, when it chose to open a
desktop window and expose itself to any and all messages from the desktop.
Just send your target process a "WM_QUIT" message, and you've killed off (in
this example) a virus scanner, something that ought to be a part of the
overall system's security.

Alun.
~~~~

[Please don't email posters, if a Usenet response is appropriate.]

-- 
Texas Imperial Software   | Try WFTPD, the Windows FTP Server. Find us at
1602 Harvest Moon Place   | http://www.wftpd.com or email alun@texis.com
Cedar Park TX 78613-1419  | VISA/MC accepted.  NT-based sites, be sure to
Fax/Voice +1(512)258-9858 | read details of WFTPD Pro for XP/2000/NT.



Relevant Pages

  • Re: Privilege-escalation attacks on NT-based Windows are unfixable
    ... I obviously cannot get you to accept that this security breach ... >>>juju that calls GetMessage until such time as your application does. ... >user's desktop without either being the user, or having the privilege to ... >>This is NOT impossible for Windows to have done. ...
    (comp.security.misc)
  • Re: Privilege-escalation attacks on NT-based Windows are unfixable
    ... I obviously cannot get you to accept that this security breach ... >>>juju that calls GetMessage until such time as your application does. ... >user's desktop without either being the user, or having the privilege to ... >>This is NOT impossible for Windows to have done. ...
    (comp.os.ms-windows.nt.admin.security)
  • Re: Privilege-escalation attacks on NT-based Windows are unfixable
    ... >>>incoming windows messages. ... >>juju that calls GetMessage until such time as your application does. ... user's desktop without either being the user, or having the privilege to ... privilege escalation attacks are so devastating. ...
    (comp.os.ms-windows.nt.admin.security)
  • Re: Privilege-escalation attacks on NT-based Windows are unfixable
    ... >>against the Windows messaging exploit in question. ... The application, since it's the one with the privilege, ... > service component and its desktop component through Windows messages, ... regardless of the privilege levels of either process. ...
    (comp.security.misc)
  • Re: Privilege-escalation attacks on NT-based Windows are unfixable
    ... >>against the Windows messaging exploit in question. ... The application, since it's the one with the privilege, ... > service component and its desktop component through Windows messages, ... regardless of the privilege levels of either process. ...
    (comp.os.ms-windows.nt.admin.security)