Shatter-proofing Windows

advertisement
Shatter-proofing Windows
Tyler Close, Alan H. Karp, Marc Stiegler
Mobile and Media Systems Laboratory
HP Laboratories Palo Alto
HPL-2005-87
May 9, 2005*
Microsoft
Windows security,
Shatter attack
The Shatter attack uses the Windows API to subvert processes running
with greater privilege than the attack code. The author of the Shatter code
has made strong claims about the difficulty of fixing the underlying
problem, while Microsoft has, with one exception, claimed that the attack
isn't a problem at all. Whether or not Shatter is indeed an exploit worth
worrying about, it uses a feature of Windows that has other malicious
uses, such as keystroke logging. This paper presents a means of defeating
this entire family of attacks with minimal breaking of applications and
effect on the look and feel of the user interface.
* Internal Accession Date Only
© Copyright 2005 Hewlett-Packard Development Company, L.P.
Approved for External Publication
Shatter-proofing Windows
Tyler Close, Alan H. Karp, Marc Stiegler
Hewlett-Packard Laboratories
Palo Alto, California
Abstract
The Shatter attack uses the Windows API to subvert processes running with greater
privilege than the attack code. The author of the Shatter code has made strong claims
about the difficulty of fixing the underlying problem, while Microsoft has, with one
exception, claimed that the attack isn’t a problem at all. Whether or not Shatter is indeed
an exploit worth worrying about, it uses a feature of Windows that has other malicious
uses, such as keystroke logging. This paper presents a means of defeating this entire
family of attacks with minimal breaking of applications and effect on the look and feel of
the user interface.
1. Introduction
Shatter [1], so called because it “breaks” Windows, uses the Windows API to send
messages to windows associated with processes that have greater authority than the
process running the attacker’s code. In the example exploits, the target is a system
service that has a window on the interactive desktop. The attack uses Windows messages
to remove the length restrictions on an input field in the target window and insert code
into the service’s address space. The final step sends a WM_TIMER message that
induces the service to branch to the exploit.
Microsoft initially denied that the attack exploits an architectural flaw in Windows [2],
citing three points:
•
•
•
Privileged services should not have windows on the interactive desktop.
Shatter requires that the attacker be able to log onto the system.
No privileges are gained on the domain.
That note also states that “all services within the interactive desktop are peers”, which
implies that processes with different privilege levels should not be placed on the same
desktop. Microsoft also notes that it has long recommended that processes with system
privileges not have windows on the visible desktop. A response [4] points out that
several services, some supplied by Microsoft, violate this rule.
Microsoft’s second and third points appear disingenuous. Logging onto the system is not
the most common way for attackers to run code. Viruses, worms, and ActiveX controls
on web pages are far easier methods than finding passwords. Also, not exposing the
domain to attack will be small comfort to users who have had all their local files
corrupted.
1
Microsoft later released a security bulletin [3] that fixed the WM_TIMER flaw. This
message informs the application that a kernel timer event has occurred and tells the
application what address to jump to. The flaw was that the application did not check this
address. Hence, once the exploit code was installed in the target application’s address
space, a WM_TIMER message would cause that code to be executed. The fix added a
check to see if the address specified in the WM_TIMER message was registered as a callback before taking the branch. The author of Shatter agreed that this fix largely blocked
the attack [4], but claimed that this patch didn’t totally solve the problem. A later paper
[5] demonstrated that other Windows messages, such as EM_SETWORDBREAKPROC,
can also be used in Shatter-like attacks.
The paper reporting Shatter makes several strong claims about the difficulty of making
changes to prevent the attack from succeeding. The suggested solutions all break
applications or change the behavior of the system. “Basically, there is no simple
solution.” summarizes the author’s opinion.
We have found a feature in the Windows API that defeats Shatter while having minimal
impact on application behavior or the user’s interaction with the system. First, this paper
describes how Windows is structured in Section 2. Next, Section 3 describes several
rejected approaches to defeating Shatter. Our proposed solution and the tests showing
that it works are presented in Section 4.
2. Windows Structure
Most people are aware that every window appears on a desktop. Fewer people know that
there may be multiple desktops. For example, the login window appears on a dedicated
desktop. Even fewer know that every desktop is assigned to a window station [8].
Understanding Microsoft’s response to Shatter [8] and our approach to defeating it
requires knowledge of the interaction among these structures.
The user interface component of Windows consists of a number of parts. One is the
windows station [7], which is a securable object containing a clipboard, one or more
desktop objects, and some other state accessible to objects in the window station. Each
logon session is associated with a window station. A desktop is a securable object
attached to a windows station that holds UI objects, such as windows, menus, and hooks.
Note that windows are not securable objects in the Windows API.
Only one window station, called Winsta0, can interact with the user display, keyboard,
and mouse, except on the Terminal Services version of the operating system where each
session has such a window station. Only one desktop at a time can interact with the user,
and that desktop must necessarily be associated with Winsta0. Every process is
associated with a window station, and every thread is associated with a desktop. Threads
can move between desktops, and processes can move between window stations, but
windows are tied to the window station where they started.
2
3. Rejected Options
We considered a number of approaches to defeat Shatter. In addition to merely blocking
Shatter, we felt that we also had to maintain the system’s usability. After all, we’d get no
security if nobody used our software. All the options described in this section failed that
test.
1. Desktops
Microsoft states that “all services in the interactive desktop effectively have privileges
commensurate with the most highly privileged service there” [2]. The implication is that
processes with different privilege levels should run on different desktops. So, our first
idea was to follow Microsoft’s suggestion and run applications with different privileges
on different desktops within Winsta0. However, the window station contains the name
space of desktops. Although a thread can only enumerate windows on its desktop, it can
switch itself to another desktop in its window station if it has the handle to one. It’s even
possible to guess a desktop name. For example, most systems have a desktop named
DEFAULT. Once a thread has a handle to a desktop, it can assign itself to it,
circumventing any security benefits.
We tested this attack by creating an alternate desktop, imaginatively named “alternate”,
and opened three windows on it. We then wrote attack code that did an OpenDesktop,
specifying “alternate” for the desktop name and getting back a handle to the desktop.
The code then did a SetThreadDesktop, enumerated the windows on that desktop, and
sent them SW_MINIMIZE messages. None of the operations used require any
privileges. While this attack did no harm and involved no escalation of privilege, it
shows that Microsoft’s instructions about not putting privileged applications on the
“interactive desktop” are incomplete at best.
2. Window Stations
If desktops aren’t the answer, perhaps Microsoft was really referring to window stations,
not desktops. Unfortunately, using windows stations as the unit of protection instead of
the desktop doesn’t work for interactive applications running at different privilege levels,
as done by Polaris [13]. Since only Winsta0 has access to the display, and windows can’t
move between window stations, there is no way to interact with such applications running
on other window stations.
3. Terminal Server
A given login session has only one window station with access to user interactions, and
the standard versions of Windows have only one interactive window station. The Server
versions don’t have this restriction, though. Hence, we can run each application in its
own login session with its own displayable window station.
There are two problems with this approach. The first is cost. A single license for
Windows XP Professional sells for $300 on the Microsoft web site. One for Server 2003
carries a $1,000 price tag, with an additional charge for Client Access Licenses (CALs)
3
beyond the first five. It’s not clear from the Microsoft description of the CAL whether
one is needed for each login session.
The second problem arises primarily in corporate environments. A company’s IT staff
may spend many hours validating their software environment for desktop machines.
Today, that effort is spent on the desktop version of the operating system. Many
applications have not been tested on the Server version.
4. Virtual Machines
Virtual machines, such as VMWare [8], provide all the isolation needed to block Shatter.
All that’s needed is to run every application in a separate virtual machine. Unfortunately,
virtual machines are expensive, almost $200 for a copy of VMWare. They also take
considerable resources; VMWare specifies a minimum of 128 MB RAM for each running
instance. It’s clear that a machine with a standard configuration won’t be able to run very
many instances.
5. Virtual OSes
Defeating Shatter doesn’t require the full emulation of the hardware done by virtual
machines. Virtualizing the operating system, as done by Xen [10] and Virtuozzo [11],
should suffice. A virtual OS is light-weight, allowing a machine to run a large number of
instances. Unfortunately, OSes in widespread distribution, such as Linux and Microsoft
Windows XP, need to be modified in order to run under Xen or Virtuozzo. There is no
Windows version of Xen, and Virtuozzo only supports the Terminal Server 2003 version
of Windows.
6. Common problem
The rejected solutions just described all share a common characteristic; they put windows
into separate environments. That means that producing the look and feel of using
Windows would be hard. The problem is manageable for applications that run in full
screen mode. In those cases, we only need to provide something that looks like the user’s
task bar to allow switching between environments. However, many people prefer to have
overlapping windows, but windows that can overlap necessarily can be used to mount
Shatter attacks against each other.
An alternative to overlapping the actual windows is to use screen scraping and keyboard
stuffing. Say that file explorer is running on the default desktop and a System service is
running on another. An interactive window opened by the service won’t be visible to the
user as long as the default desktop is active. However, we can write code that captures
the bitmap of the service’s interactive window and display those bits on the default
desktop. Note that we have to monitor the window for changes in case it contains
something like a progress bar. Windows messages sent to the window containing the
bitmap won’t reach the service. Keystrokes and mouse events that appear in it can be
forwarded to a daemon running on the alternate desktop for forwarding to the actual
interactive window. Implementing this scheme is a major effort with significant
performance and usability risks.
4
4. Defeating Shatter
The process-handling part of the Windows API contains a feature that can be used to
block Shatter. A Job object [12] is designed to allow control of a group of processes.
Once a process has been assigned to a job object, the association cannot be removed, nor
can it be changed. Child processes are part of the same job unless a breakaway privilege
is granted explicitly.
Various restrictions can be placed on processes running within a job. In particular, we
can set the JOB_OBJECT_UILIMIT_HANDLES restriction (UILIMIT for short), which
prevents a process in the job from using handles to windows associated with processes
outside the job. Figure 1 shows Shatter running without the UILIMIT restriction
successfully changing the length field in a dialog box to 4. What you don’t get from this
figure is the beep heard when trying to type a fifth character, which demonstrates the
success of a key step in the attack.
Figure 1. Shatter changed length field with no UI limit.
Figure 2 shows Shatter running in a job with the UI limit. First, you’ll see that the attack
succeeds in getting the window handle, which is the same as the one shown in Figure 1.
However, this time the window message that changes the length of the input field to 4
fails, as shown by the error message and the typed text.
5
Figure 2. Shatter unable to change length field with UI limit.
We also tried passing a window handle into a job. A process in a job with UILIMIT was
unable to use the handle. We even tried sending Windows messages using
PostThreadMessage() instead of PostMessage(). These messages were silently dropped
by the receiving thread as expected, based on the API and default implementation of the
message queue.
We conclude that UILIMIT on job objects defeats all shatter-like attacks. That doesn’t
mean that there aren’t flaws in Windows that can’t be exploited using other messaging
methods. However, using this restriction prevents the use of Window messaging, the
defining characteristic of Shatter.
We have built a version of Polaris [13], a package that configures applications to run in
restricted user accounts, to run processes in jobs with the UILIMIT. For the most part,
there are no problems. We did find one problem. Although we haven’t applied the
available clipboard restrictions, processes running with UILIMIT are unable to read text
from the clipboard. Since they can read bitmaps, we believe this problem is caused by a
bug in the Windows implementation, and we are developing a work-around.
Unfortunately, there is a more serious bug in the Windows XP implementation. If you do
a PostMessage() from within a job, specifying HWND_BROADCAST as the target
window handle, the Windows message is delivered to all top level windows, both inside
the job and outside the job. A test program assigned to a job with UILIMIT that sends
WM_CLOSE to HWND_BROADCAST results in all open windows closing. While this
denial of service attack is just an annoyance, it means that windows messages are
escaping the confines of the job and could be used in Shatter attacks.
6
This behavior is in direct contradiction to that specified for UILIMIT [9]. The Remarks
section for this restriction says:
"If you specify the JOB_OBJECT_UILIMIT_HANDLES flag, when a process
associated with the job broadcasts messages, they are only sent to top-level
windows owned by processes associated with the same job."
We reported this behavior to Microsoft. Their response states
“I have forwarded this information to the product group for further research as a
bug. It appears after researching this, that this is not a security vulnerability. If
this is not the case and I have overlooked the security implications, please send
me details on how an attacker might able to exploit this vulnerability and what the
results of an (sic) successful exploit might be.”
It seems surprising that circumventing a restriction isn’t considered a security
vulnerability, but this position is consistent with Microsoft’s original response to Shatter
[2].
5. Conclusions
The Shatter attack is based on the ability of a process to send a Windows message to
windows associated with processes running at a higher privilege level. While the
WM_TIMER flaw exploited by the original attack has been closed, users are at risk that
other such flaws might be discovered. Microsoft’s response that the desktop is the unit of
protection is at best incomplete. There appear to be ways to break that model.
We have shown that it is possible to defeat Shatter by assigning processes to jobs with
UILIMIT that correspond to their privilege levels. Since UILIMIT restricts the use of
window handles by those in the job, attacks like Shatter are blocked. Any attack based
on the use of Windows messages would be evidence of a bug in the implementation that
Microsoft would be compelled to fix.
Programs running in jobs with UILIMIT appear to behave normally, with two exceptions.
Drag/drop only works between windows in the same job with UILIMIT. However,
processes running with different privileges will most likely run in different logon
sessions, and drag/drop doesn’t work across sessions. The second difference is clearly
due to a bug in the behavior of the clipboard. These jobs cannot paste text, although
there is no problem pasting bitmaps. We believe Microsoft will eventually fix this bug.
In any case, applications appear to run normally under UILIMIT, contrary to the opinion
of the author of Shatter.
References
1. Foon, “Exploiting design flaws in the Win32 API for privilege escalation”,
http://security.tombom.co.uk/shatter.html
7
2. Microsoft, “Information About Reported Architecural Flaw in Windows”,
http://www.microsoft.com/technet/archive/security/news/htshat.mspx, September
2002
3. Microsoft, “Microsoft Security Bulleting MS02-071: Flaw in Windows
WM_TIMER Message Handling Could Enable Privilege Elevation (328310),
http://www.microsoft.com/technet/security/bulletin/ms02-071.mspx, December
2002, updated April 2003
4. Foon, “Shatter attacks – more techniques, more detail, more juicy goodness”,
http://security.tombon.co.uk/moreshatter.html
5. Lavery, Oliver, “Win32 Message Vulnerabilities Redux: Shatter Attacks Remain
a Threat”, iDefense Inc., Reston, VA,
http://www.netsys.com/library/papers/Shatter_Redux.pdf, July 2003
6. Brown, Keith, Programming Windows Security, Addison-Wesley, Boston, 2000
7. Microsoft, MSDN Library, http://msdn.microsoft.com/library/enus/dllproc/base/window_stations_and_desktops.asp
8. VMWare, http://www.vmware.com/
9. Microsoft, MSDN Library,
http://msdn.microsoft.com/library/default.asp?url=/library/enus/dllproc/base/jobobject_basic_ui_restrictions_str.asp
10. Xen, http://www.cl.cam.ac.uk/Research/SRG/netos/xen/
11. SWSoft, Virtuozzo, http://www.sw-soft.com/virtuozzo
12. Microsoft, http://msdn.microsoft.com/library/en-us/dllproc/base/job_objects.asp
13. Stiegler, M., Karp, A. H., Yee, K.-P., Close, T., and Miller, M, “Polaris: Toward
Virus Safe Computing for Windows XP”, HP Labs Tech Report HPL-2004-221,
http://www.hpl.hp.com/techreports/2004/HPL-2004-221R1, 2004
8
Download