Actually I think it is codenamed "Longhorn" after the "Longhorn Saloon" in Whistler, BC. Originally, after "Whistler" (Windows XP codename), the next major release was supposedly going to be called "Blackcomb" after the other mountain at Whistler. After the goals for that release proved to be too lofty, they decided to scale back the design and shoot for a simpler release, codenamed instead after the bar at the base of Blackcomb mountain.
"The problem with things like browsing is that MS changes Active directory and the smb protocal quite frequently."
Please.
If the code keeps changing so much, explain to me how my Active Directory client from May 2001 still works with Active Directory? Explain to me how my 8 year old Win95 box can still communicate with my XP box using SMB?
Microsoft can't just change the core of a protocol without alienating old versions of its code. This is obvious.
You make a good point about self-sufficiency requirements for gov't agencies.
Does this mean that a gov't must mandate use of open source software? I'm not convinced that this follows. What I mean is, for a gov't to require access to source code so that they can understand/review/maintain it, must it be "open" in the sense that anyone must be able to get such access to the source too? A gov't could just as well have a special licensing deal with the supplier of the proprietary software that gives them the level of source access that they require -- e.g. "Windows is o.k. but only if MSFT shares the source code with the gov't, regardless of whether MSFT is willing to share the source with anyone else".
The only reason I can come up with for why a gov't might have a requirement for source to 3rd party software that they use to be open to anyone (not just the gov't) is because of support and operations. If a gov't is going to license a large closed-source product (e.g. Windows) and swing a licensing deal so that they get the source and can make changes and rebuild, they're running a huge support risk -- all cost will fall on the gov't, or on a pricy special support contract if the supplier is willing to support that single customer's modifications to one of their standard SKUs. (Support costs go way up for a supplier when their installed base starts getting fragmented with customized versions of the software.) I suppose that with an "open source" requirement, the gov't may be hoping that if they *do* make changes to their software (e.g. bugfixes) they may somehow have a larger base of "experts" to help with support, and they are free to show the public what changes they have made. In this sense they are mandating openness upon themselves, too, not just on their suppliers.
This last point may actually be very central in Brazil's decision -- perhaps they want the ability to show the public exactly what their machines are running. "Openness" not in the sense that gov't employees have access to everything, but "openness" in the sense that they are free to respond to requests for information on how the gov't is operating.
This is argument is a bit flawed. A VM running a legacy app is subject to all of the security risks associated with that legacy app.
Example: RPC hole in NT4 running on a connectix VM. If you send a bad packet to the VM, it crashes -- a virtual crash. It's still a DOS attack because it halts the service provided by the VM. The only difference is that it doesn't necessarily bring down the physical machine hosting the VM. But who cares, since if the VM is dead, the services provided by that VM aren't available and the physical machine is basically just a paperweight. Virtual crash == physical crash, from a business/operations perspective.
You are then left with a choice, stay with an unsecure system which will never be patched (unless independent sources patch the flaw,) or buy a new system at an inflated price, that will do exactly the same thing your old system did, but not have the fatal security flaw.
As is the case with some security holes, patching the hole breaks app compatibility. Migrating the operating environment to a VM doesn't magically patch the security hole or allow for it to be patched without still breaking app compatibility. Your virtually hosted and patched app would still be virtually incompatible with its clients.
Providing a VM isn't a shortcut around patching security holes. What it allows is server consolidation so you can virtually host legacy apps from the same box that you provide newer apps from. It helps to remove the upgrade barrier caused by incompatibility concerns. It doesn't fix broken apps or remove the app providers' responsibility to support and patch VM hosted apps.
...that the basic security model in place for software today for mitigating the risk of an attacker modifying service code (0wning y0ur b0xen) is to automate the process of modifying your service code via patching.
"The Microsoft KB article for the Slammer patch found here has an incorrect URL for 'Download the patch' referring to KB Q316333 which is only a handle leak fix. The real patch may be found later in the article."
If you read the technical details of KB 316333, you will find that the link to download the patch is correct -- it is a real patch for Slammer. Can anyone update the story posting to correct the misinformation?
If you're coming to Seattle for this conference, you might try heading across town for a real experience with wearable computers at the Experience Music Project (EMP) at the Seattle Center. (Be prepared to pay a lot to get in -- it was $20 or $30 last time I was there.)
To me, the EMP was a lesson in all the bad things about wearable computers. Sure, they are uncomfortable to wear, but technology can probably remedy that. The real problem with them is how they require a lot of attention and prevent you from being able to focus on what's really going on around you. It's weird to be standing in the middle of a crowd with a bunch of people using wearable computers, with no one looking at each other or interacting -- they're all too busy fidgeting with the gadget they're wearing to take notice of each other.
If you want to enjoy the EMP, sure, get the wearable computer for the "gee whiz" thrill, but put it away after a few minutes so you can enjoy what's going on around you.
The real point is that the only apps that are insecure are the ones at the same privilege level as the user, or poorly written services that the administrator never should have installed.
This is because you can copy arbitrary data into another process but only if it's got a thread on your desktop.
Which applications would those be?
The vast majority of them will be ones running as you. So you can subvert a process running as you. Big deal.
The unlucky among us may have installed a hack job service, granting it LocalSystem access at the time they installed it. This service explicitly configured itself to be able to interact with the interactive desktop. !!!Big news!!! Hack job service compromises system!!!
A closer look at the "Overview" section of the white paper reveals that it opens with "In this example, I will be exploiting Network Associates VirusScan v4.5.1...", so this whole article looks like the case of the unwisely configured service.
This is all very simple, and it's been this way for years: if it runs as LocalSystem, uncheck the "Allow service to interact with desktop" box. Then there's no risk. You can't copy arbitrary data into the process, and you can't send it WM_TIMER messages. If you install a service app and it turns that option on, maybe you should look for a vendor with a higher quality product. And just to be on the safe side, set NoInteractiveServices to 1 under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Windows.
(By the way, you're right that the bit about WM_TIMER in the white paper isn't even correct. The app that receives it has the opportunity to drop the message without dispatching the callback function, contrary to the white paper, whose author didn't even bother to investigate that claim before blurting it out.)
D
Re:Shoddy work, mistake in the whitepaper!
on
Shattering Windows
·
· Score: 1
Yes, it would be a daunting task, and you'd never find all the bugs.
But the only people who need to worry about this are the people who are going against Microsoft's recommendations by writing service code registered to run as LocalSystem who either (A) have desktop interaction enabled or (B) are writing code to change window station ACLs or are making calls to SetProcessWindowStation/SetThreadDesktop to allow for this interaction.
There's no possibility for elevation of privilege via this exploit otherwise.
The reason why this is a critical flaw in the Win32 API is because it means that in order for code to be secure it is essential that every existing piece of software be carefully checked to make sure it separates interface from back-end.
Nonsense. This is an elevation of privilege issue that can only occur when privileged code shares the same desktop as unprivileged code.
If you're not writing service code, you're fine. No elevation of privilege risk. The majority of applications are unaffected.
If you've written service code, don't set the SERVICE_INTERACTIVE_PROCESS flag when you call CreateService in your installer. The only actual review of your service code is a grep to make sure no one's calling SetProcessWindowStation and SetThreadDesktop in combination to sabotage your security. Hopefully your code doesn't need to call these at all!
SendMessage can only be used to post messages to windows on the same desktop as the caller. Services that have elevated privileges can be (and are by default) configured to have a separate, privileged desktop that normal user processes don't have access to. (See the "Allow service to interact with desktop" option in the Windows services UI.)
The exploit in the white paper takes advantage of a poorly written service that was configured to expose its GUI to the same desktop that normal users create windows on.
You might want to go back and have a second look at your "secure" WndProc. WM_TIMER messages aren't sent to the WndProc when you call DispatchMessage. They're special-cased such that the callback occurs without invoking WndProc. You need to catch them before you call DispatchMessage.
Besides this technicality, the essence of your post makes sense.
Actually your WndProc will never be called in response to a WM_TIMER message. WM_TIMER messages are handled by a special case inside DispatchMessage, which is where the jump to the callback occurs. If you want to intercept WM_TIMER messages, you need to intercept them prior to calling DispatchMessage.
D
Shoddy work, mistake in the whitepaper!
on
Shattering Windows
·
· Score: 3, Insightful
This white paper makes several allegations, not the least among which is that there is no way for a user-mode app to mitigate the security risk it presents. This is untrue, however, and appears to be the result of a failure to investigate properly on the part of the author! User mode applications can be rewritten to guard themselves against malicious Win32 message-based attacks. That's because every user-mode app has full say in how every message is handled, contrary to the white paper.
From the paper: "As far as I know, the message [WM_TIMER] doesn't even go into the message queue, so the application doesn't even have a chance to ignore it."
The previous post follows the theme with: "It's like opening a socket for doing basic network communication and Windows API allowing certain pre-determined 'helper' messages to be handled by OS before your app has any say to handling."
Dave at Microsoft did a thorough investigation with the developers who were familiar with the relevant code and replied to the author before he released his white paper (8/5/2002): "It is the implementer of a program that decides what messages to handle
and how to handle them."
The author could possibly have arrived at his erroneous conclusion by writing a test app and monitoring calls to a message handling routine when certain types of messages were sent to the app. Observing that a WM_TIMER message sent to the app was processed without the application-supplied message handler being invoked, one might conclude that it is therefore impossible for an application to guard against WM_TIMER-triggered attacks. This test is flawed.
The standard message dispatching pattern you'll find in common Win32 programming books (e.g. "Teach Yourself Windows 95 Programming in 21 Days" by Charles Calvert) and even in sample code from Microsoft goes like so:
Wait for a message to arrive in the queue (GetMessage)
Optional logic to crack certain types of messages for easier handling later (e.g. TranslateMessage)
Dispatch the message for handling by an application-specified handler routine (DispatchMessage).
Repeat until a special message arrives that breaks the loop.
No message is processed until the application calls DispatchMessage. DispatchMessage contains special-case logic which handles WM_TIMER and WM_SYSTIMER events *without* invoking the application-supplied message handler, which is why tests similar to the case I mentioned above don't show a call to the message handler for WM_TIMER messages. However, the message will only be processed if the app calls DispatchMessage.
Applications can guard themselves by inserting a (possibly non-trivial) step 2.5 into the pattern above: security filtering of messages prior to dispatch.
So, the basic Win32 thread messaging API calling patterns are flawed when used in situations where applications with different privilege levels coexist on the same desktop. Dave already pointed this out in his email response to the white paper author on 8/5/2002. Message filtering needs to be added to those specific applications in those cases if there is to be any measure of security.
Also, the most privileged service applications (those that run as LocalSystem) can't create windows on the interactive desktop by default, which means that they aren't vulnerable unless someone checks a box that says that they should be! That feature must specifically be enabled (see the "Allow service to interact with desktop" checkbox in the Services UI). Services that run in security contexts other than LocalSystem don't even support the "interact with desktop" functionality.
The conclusion of the whitepaper -- that there is no way to write a service to be secure -- was not proven. The author should have done a better job of investigating his claims before publishing this paper.
This really boils down to a case of poorly written services exposing more "services" to users than they intended to. Several good posts on this/. topic echo that too. At least we've raised awareness.
The CLR only threatens the JVM, not the Java language. Someone will implement a Java compiler for the CLR; then components written in Java and C# and other languages will be able to seamlessly interact. We will finally be rid of the JVM's language lock-in now that there's a competing product available in the cross-platform market. This is the whole point of the CLR: you can use whichever language you want to.
I'm astonished that the previous post was modded to a 4. The blatantly obvious has been overlooked here:
Microsoft's service packs are free; you get the bug fixes without paying Microsoft for an upgrade. For this reason, their business model is obviously not based around building flaws into code.
If a piece of software is released without any known bugs, it's either because (A) the software doesn't actually do anything, or (B) the developer did a poor job of finding bugs. Previous Poster is either trolling or is speaking outside of any experience in the software industry.
Microsoft has no motivation to get new customers. Being a monopoly, they already have virtally all of them. Their motivation is to earn more proffits off of their existing customers.
Microsoft is always looking for new customers. Since Microsoft sells a shrink-wrapped product and charges a one time fee, as opposed to charging for an ongoing service, one of Microsoft's biggest competitors is Microsoft. Every Windows 98 user is a potential Windows XP customer.
Microsoft knows that browsing the web and viewing media are basic functionalities that the majority of users expect from their computer. Better integration of features like IE and Media Player into Windows are some of the key selling points of recent versions of Windows. Take a Windows 98 user who often listens to music and watches video clips on their computer, tell them that Windows XP is "better" since the Media Player is more integrated, and you've got your foot in the door for a sale.
I tend to agree with the principle behind Occam's Razor, which is that the simplest explanation tends to be the correct one.
I know what buffer overflow is, and the zlib issue is not it. This may be an issue, but surely something that doesn't require this much coverage or worrying.
A double-free can be just as bad. For example:
Suppose some code frees a buffer.
Then some other piece of code asks the allocator for a block of memory, and happens to get the block that was just freed.
Next, suppose the already-freed block is double-freed.
Suppose, finally, that some code asks the allocator for a block of memory again and it receives the block that was just double-freed.
Now two pieces of code are using the same buffer for two different purposes without knowing it.
Maybe one of the pieces of code is using the buffer to write data from an untrusted source. This corrupted data could then mistakenly be trusted by the other piece of code.
For example, if one function thinks the memory is a C++ class with a vtable, and the other thinks it's a buffer to store incoming data from a socket, whoever's sending the data to the socket has an opportunity to replace a function pointer with one of their choosing, and the next time a virtual method is called by the code that thinks the buffer is a C++ class instance with a valid vtable, it's curtains.
This is a good non-technical explanation of a buffer overflow, but I'd like to point out many buffer overflows do not allow for such exploits as the poster suggests. Lots of them just lead to crashes. This is due to the difficulty (and sometimes impossibility) of getting the attacked application to actually execute the "code" that's overwritten past the end of the buffer.
I've got some free time on my hands, so for those technical types who want an example of a buffer overrun with an analysis and how to fix it...
Recently I was working on a win32 program that contained a call to wvsprintfA() (see MSDN for details -- wvsprintfA is the ASCII version of wvsprintf). This function takes a buffer, a format string, and a variable argument list, and renders the some formatted output into the supplied buffer. Conspicuously absent from the argument list to this function is the buffer size (so that wvsprintf knows when to stop). Documentation says it's hardcoded to stop at 1024 bytes, but it's actually 1025 bytes (found this out the hard way). This is because even though it will truncate ASCII strings down to 1024 chars or less, it always writes a null-terminator character on the end. So for results that are too big, if you're buffer's only 1024 bytes, you're going to have a 1 byte overrun.
This leads to a very important point. How the memory immediately following your buffer is used determines what kinds of exploits are possible in the event of an overrun (this can be machine dependent). Whether the buffer is in a thread's stack space, or in a heap, or in a code image will have a significant impact on what's possible.
In the case of my overrun, the buffer was allocated on a thread's stack. For those familiar with C/C++ (on x86, I can't speak for other hardware platforms) with most compilers that looks something like this:
void foo(int bar, char *toobig)
{
char *buffer[1024];// this is a stack allocated buffer
wvsprintf(buffer, "%s", toobig);
}
Looking at the code, it may appear that the call to wvsprintf is what comes next in memory after the buffer, but if you take this in context, you'll realize that that's not the case. What's next in memory here (in the case of my compiler at least) is going to be a saved stack frame base pointer from the caller, followed by the calling function's return address, followed by the parameters passed to foo in this call (most likely -- again, depends on compiler, calling convention, optimizer settings, etc.).
STACK (in order of increasing memory addresses):
buffer (1024 bytes)
saved EBP (<-- foo's EBP should point here)
return address
int bar
char *toobig
foo's caller's local vars
foo's caller's saved EBP (<-- foo's caller's EBP should point here)
foo's caller's return address
(Stack layout will vary depending on your compiler, platform, etc.)
So, since this buffer can get overrun by one byte, part of the caller's saved stack frame base pointer (EBP) could be overwritten! On the platform where I observed this, pointers were 32-bits wide (4 bytes) and the byte ordering on my hardware has less significant bytes at lower memory addresses. This means that the lowest order byte of the saved base pointer can be overwritten, and in this case predictably by a zero (0x00) if it does happen. This doesn't cause a crash right away; rather, it has the effect of misaligning the caller's stack frame so that when foo returns, EBP is incorrectly restored, so all addresses that the caller computes relative to EBP will be off -- for example, local variables in the caller of foo will be trashed, as well as its caller's saved base pointer and return address, since they've been "relocated";-). (Note that in the off chance that foo's caller's EBP just so happened to be aligned on a 256-byte boundary this overrun would have no affect at all!)
This caused a crash after foo returned and subsequently foo's caller returned to its caller -- because foo's caller's return address wasn't where it used to be relative to EBP, seeing as EBP was erroneously adjusted to point to a lower address.
void foocaller(char *s)
{
foo(0, s);
// EBP is now bogus if the buffer in foo // was overrun. Better not use any // local variables or try to return from // this point on!
bar();
return;// <-- crashed after this, fortunately
}
The return address that was actually used was "garbage" data left over on the stack -- in the middle of the space that was occupied by the buffer in foo. Note that execution of bar() in foocaller() could potentially overwrite this space too. (In my case, that's what happened, since bar made lots of calls and had enough local variables.) This means that the return address is potentially up for grabs! Fortunately in my case, the stack frames written by bar and its subfunctions was always such that the return address would be overwritten with an unreadable memory address, so my program would access violate (SIG_SEGV) and stop when foocaller attempted to return.
This particular problem is avoided by allocating 1025 bytes instead of 1024 bytes for the buffer, because of the nature of wvsprintfA.
Scary what one little byte can do, eh? Be very cautious when copying data around!
So it turns out that the only exploit in this buffer overrun was that you could make my code crash. You couldn't actually get arbitrary code to run even though you could influence the contents of the buffer from outside of the program. But it was a close call.
Actually I think it is codenamed "Longhorn" after the "Longhorn Saloon" in Whistler, BC. Originally, after "Whistler" (Windows XP codename), the next major release was supposedly going to be called "Blackcomb" after the other mountain at Whistler. After the goals for that release proved to be too lofty, they decided to scale back the design and shoot for a simpler release, codenamed instead after the bar at the base of Blackcomb mountain.
Please.
If the code keeps changing so much, explain to me how my Active Directory client from May 2001 still works with Active Directory? Explain to me how my 8 year old Win95 box can still communicate with my XP box using SMB?
Microsoft can't just change the core of a protocol without alienating old versions of its code. This is obvious.
You make a good point about self-sufficiency requirements for gov't agencies.
Does this mean that a gov't must mandate use of open source software? I'm not convinced that this follows. What I mean is, for a gov't to require access to source code so that they can understand/review/maintain it, must it be "open" in the sense that anyone must be able to get such access to the source too? A gov't could just as well have a special licensing deal with the supplier of the proprietary software that gives them the level of source access that they require -- e.g. "Windows is o.k. but only if MSFT shares the source code with the gov't, regardless of whether MSFT is willing to share the source with anyone else".
The only reason I can come up with for why a gov't might have a requirement for source to 3rd party software that they use to be open to anyone (not just the gov't) is because of support and operations. If a gov't is going to license a large closed-source product (e.g. Windows) and swing a licensing deal so that they get the source and can make changes and rebuild, they're running a huge support risk -- all cost will fall on the gov't, or on a pricy special support contract if the supplier is willing to support that single customer's modifications to one of their standard SKUs. (Support costs go way up for a supplier when their installed base starts getting fragmented with customized versions of the software.) I suppose that with an "open source" requirement, the gov't may be hoping that if they *do* make changes to their software (e.g. bugfixes) they may somehow have a larger base of "experts" to help with support, and they are free to show the public what changes they have made. In this sense they are mandating openness upon themselves, too, not just on their suppliers.
This last point may actually be very central in Brazil's decision -- perhaps they want the ability to show the public exactly what their machines are running. "Openness" not in the sense that gov't employees have access to everything, but "openness" in the sense that they are free to respond to requests for information on how the gov't is operating.
This is argument is a bit flawed. A VM running a legacy app is subject to all of the security risks associated with that legacy app.
Example: RPC hole in NT4 running on a connectix VM. If you send a bad packet to the VM, it crashes -- a virtual crash. It's still a DOS attack because it halts the service provided by the VM. The only difference is that it doesn't necessarily bring down the physical machine hosting the VM. But who cares, since if the VM is dead, the services provided by that VM aren't available and the physical machine is basically just a paperweight. Virtual crash == physical crash, from a business/operations perspective.
As is the case with some security holes, patching the hole breaks app compatibility. Migrating the operating environment to a VM doesn't magically patch the security hole or allow for it to be patched without still breaking app compatibility. Your virtually hosted and patched app would still be virtually incompatible with its clients.
Providing a VM isn't a shortcut around patching security holes. What it allows is server consolidation so you can virtually host legacy apps from the same box that you provide newer apps from. It helps to remove the upgrade barrier caused by incompatibility concerns. It doesn't fix broken apps or remove the app providers' responsibility to support and patch VM hosted apps.
Luna gets the first post!
They aren't, unless you rooted a DC.
...that the basic security model in place for software today for mitigating the risk of an attacker modifying service code (0wning y0ur b0xen) is to automate the process of modifying your service code via patching.
DDL
If you read the technical details of KB 316333, you will find that the link to download the patch is correct -- it is a real patch for Slammer. Can anyone update the story posting to correct the misinformation?
You could use it to search singles ads and chat no matter where you are, so maybe it would help.
If you're coming to Seattle for this conference, you might try heading across town for a real experience with wearable computers at the Experience Music Project (EMP) at the Seattle Center. (Be prepared to pay a lot to get in -- it was $20 or $30 last time I was there.)
To me, the EMP was a lesson in all the bad things about wearable computers. Sure, they are uncomfortable to wear, but technology can probably remedy that. The real problem with them is how they require a lot of attention and prevent you from being able to focus on what's really going on around you. It's weird to be standing in the middle of a crowd with a bunch of people using wearable computers, with no one looking at each other or interacting -- they're all too busy fidgeting with the gadget they're wearing to take notice of each other.
If you want to enjoy the EMP, sure, get the wearable computer for the "gee whiz" thrill, but put it away after a few minutes so you can enjoy what's going on around you.
D
The real point is that the only apps that are insecure are the ones at the same privilege level as the user, or poorly written services that the administrator never should have installed.
This is because you can copy arbitrary data into another process but only if it's got a thread on your desktop.
Which applications would those be?
A closer look at the "Overview" section of the white paper reveals that it opens with "In this example, I will be exploiting Network Associates VirusScan v4.5.1...", so this whole article looks like the case of the unwisely configured service.
This is all very simple, and it's been this way for years: if it runs as LocalSystem, uncheck the "Allow service to interact with desktop" box. Then there's no risk. You can't copy arbitrary data into the process, and you can't send it WM_TIMER messages. If you install a service app and it turns that option on, maybe you should look for a vendor with a higher quality product. And just to be on the safe side, set NoInteractiveServices to 1 under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Windows.
(By the way, you're right that the bit about WM_TIMER in the white paper isn't even correct. The app that receives it has the opportunity to drop the message without dispatching the callback function, contrary to the white paper, whose author didn't even bother to investigate that claim before blurting it out.)
D
Yes, it would be a daunting task, and you'd never find all the bugs.
But the only people who need to worry about this are the people who are going against Microsoft's recommendations by writing service code registered to run as LocalSystem who either (A) have desktop interaction enabled or (B) are writing code to change window station ACLs or are making calls to SetProcessWindowStation/SetThreadDesktop to allow for this interaction.
There's no possibility for elevation of privilege via this exploit otherwise.
D
The reason why this is a critical flaw in the Win32 API is because it means that in order for code to be secure it is essential that every existing piece of software be carefully checked to make sure it separates interface from back-end.
Nonsense. This is an elevation of privilege issue that can only occur when privileged code shares the same desktop as unprivileged code.
D
SendMessage can only be used to post messages to windows on the same desktop as the caller. Services that have elevated privileges can be (and are by default) configured to have a separate, privileged desktop that normal user processes don't have access to. (See the "Allow service to interact with desktop" option in the Windows services UI.)
The exploit in the white paper takes advantage of a poorly written service that was configured to expose its GUI to the same desktop that normal users create windows on.
D
You might want to go back and have a second look at your "secure" WndProc. WM_TIMER messages aren't sent to the WndProc when you call DispatchMessage. They're special-cased such that the callback occurs without invoking WndProc. You need to catch them before you call DispatchMessage.
Besides this technicality, the essence of your post makes sense.
D
Actually your WndProc will never be called in response to a WM_TIMER message. WM_TIMER messages are handled by a special case inside DispatchMessage, which is where the jump to the callback occurs. If you want to intercept WM_TIMER messages, you need to intercept them prior to calling DispatchMessage.
D
This white paper makes several allegations, not the least among which is that there is no way for a user-mode app to mitigate the security risk it presents. This is untrue, however, and appears to be the result of a failure to investigate properly on the part of the author! User mode applications can be rewritten to guard themselves against malicious Win32 message-based attacks. That's because every user-mode app has full say in how every message is handled, contrary to the white paper.
From the paper: "As far as I know, the message [WM_TIMER] doesn't even go into the message queue, so the application doesn't even have a chance to ignore it."
The previous post follows the theme with: "It's like opening a socket for doing basic network communication and Windows API allowing certain pre-determined 'helper' messages to be handled by OS before your app has any say to handling."
Dave at Microsoft did a thorough investigation with the developers who were familiar with the relevant code and replied to the author before he released his white paper (8/5/2002): "It is the implementer of a program that decides what messages to handle and how to handle them."
The author could possibly have arrived at his erroneous conclusion by writing a test app and monitoring calls to a message handling routine when certain types of messages were sent to the app. Observing that a WM_TIMER message sent to the app was processed without the application-supplied message handler being invoked, one might conclude that it is therefore impossible for an application to guard against WM_TIMER-triggered attacks. This test is flawed.
The standard message dispatching pattern you'll find in common Win32 programming books (e.g. "Teach Yourself Windows 95 Programming in 21 Days" by Charles Calvert) and even in sample code from Microsoft goes like so:
No message is processed until the application calls DispatchMessage. DispatchMessage contains special-case logic which handles WM_TIMER and WM_SYSTIMER events *without* invoking the application-supplied message handler, which is why tests similar to the case I mentioned above don't show a call to the message handler for WM_TIMER messages. However, the message will only be processed if the app calls DispatchMessage.
Applications can guard themselves by inserting a (possibly non-trivial) step 2.5 into the pattern above: security filtering of messages prior to dispatch.
So, the basic Win32 thread messaging API calling patterns are flawed when used in situations where applications with different privilege levels coexist on the same desktop. Dave already pointed this out in his email response to the white paper author on 8/5/2002. Message filtering needs to be added to those specific applications in those cases if there is to be any measure of security.
Also, the most privileged service applications (those that run as LocalSystem) can't create windows on the interactive desktop by default, which means that they aren't vulnerable unless someone checks a box that says that they should be! That feature must specifically be enabled (see the "Allow service to interact with desktop" checkbox in the Services UI). Services that run in security contexts other than LocalSystem don't even support the "interact with desktop" functionality.
The conclusion of the whitepaper -- that there is no way to write a service to be secure -- was not proven. The author should have done a better job of investigating his claims before publishing this paper.
This really boils down to a case of poorly written services exposing more "services" to users than they intended to. Several good posts on this /. topic echo that too. At least we've raised awareness.
D
Finally... we are starting to clear out the DNS cruft!
The CLR only threatens the JVM, not the Java language. Someone will implement a Java compiler for the CLR; then components written in Java and C# and other languages will be able to seamlessly interact. We will finally be rid of the JVM's language lock-in now that there's a competing product available in the cross-platform market. This is the whole point of the CLR: you can use whichever language you want to.
I'm astonished that the previous post was modded to a 4. The blatantly obvious has been overlooked here:
People aren't buying MS enterprise computing product.
Microsoft Exchange Server has over 100,000,000 seats in the enterprise email market.
Microsoft has no motivation to get new customers. Being a monopoly, they already have virtally all of them. Their motivation is to earn more proffits off of their existing customers.
Microsoft is always looking for new customers. Since Microsoft sells a shrink-wrapped product and charges a one time fee, as opposed to charging for an ongoing service, one of Microsoft's biggest competitors is Microsoft. Every Windows 98 user is a potential Windows XP customer.
Microsoft knows that browsing the web and viewing media are basic functionalities that the majority of users expect from their computer. Better integration of features like IE and Media Player into Windows are some of the key selling points of recent versions of Windows. Take a Windows 98 user who often listens to music and watches video clips on their computer, tell them that Windows XP is "better" since the Media Player is more integrated, and you've got your foot in the door for a sale.
I tend to agree with the principle behind Occam's Razor, which is that the simplest explanation tends to be the correct one.
D
A double-free can be just as bad. For example:
- Suppose some code frees a buffer.
- Then some other piece of code asks the allocator for a block of memory, and happens to get the block that was just freed.
- Next, suppose the already-freed block is double-freed.
- Suppose, finally, that some code asks the allocator for a block of memory again and it receives the block that was just double-freed.
Now two pieces of code are using the same buffer for two different purposes without knowing it. Maybe one of the pieces of code is using the buffer to write data from an untrusted source. This corrupted data could then mistakenly be trusted by the other piece of code.For example, if one function thinks the memory is a C++ class with a vtable, and the other thinks it's a buffer to store incoming data from a socket, whoever's sending the data to the socket has an opportunity to replace a function pointer with one of their choosing, and the next time a virtual method is called by the code that thinks the buffer is a C++ class instance with a valid vtable, it's curtains.
Yikes!
D
This is a good non-technical explanation of a buffer overflow, but I'd like to point out many buffer overflows do not allow for such exploits as the poster suggests. Lots of them just lead to crashes. This is due to the difficulty (and sometimes impossibility) of getting the attacked application to actually execute the "code" that's overwritten past the end of the buffer.
I've got some free time on my hands, so for those technical types who want an example of a buffer overrun with an analysis and how to fix it...
Recently I was working on a win32 program that contained a call to wvsprintfA() (see MSDN for details -- wvsprintfA is the ASCII version of wvsprintf). This function takes a buffer, a format string, and a variable argument list, and renders the some formatted output into the supplied buffer. Conspicuously absent from the argument list to this function is the buffer size (so that wvsprintf knows when to stop). Documentation says it's hardcoded to stop at 1024 bytes, but it's actually 1025 bytes (found this out the hard way). This is because even though it will truncate ASCII strings down to 1024 chars or less, it always writes a null-terminator character on the end. So for results that are too big, if you're buffer's only 1024 bytes, you're going to have a 1 byte overrun.
This leads to a very important point. How the memory immediately following your buffer is used determines what kinds of exploits are possible in the event of an overrun (this can be machine dependent). Whether the buffer is in a thread's stack space, or in a heap, or in a code image will have a significant impact on what's possible.
In the case of my overrun, the buffer was allocated on a thread's stack. For those familiar with C/C++ (on x86, I can't speak for other hardware platforms) with most compilers that looks something like this:
Looking at the code, it may appear that the call to wvsprintf is what comes next in memory after the buffer, but if you take this in context, you'll realize that that's not the case. What's next in memory here (in the case of my compiler at least) is going to be a saved stack frame base pointer from the caller, followed by the calling function's return address, followed by the parameters passed to foo in this call (most likely -- again, depends on compiler, calling convention, optimizer settings, etc.).
(Stack layout will vary depending on your compiler, platform, etc.)
So, since this buffer can get overrun by one byte, part of the caller's saved stack frame base pointer (EBP) could be overwritten! On the platform where I observed this, pointers were 32-bits wide (4 bytes) and the byte ordering on my hardware has less significant bytes at lower memory addresses. This means that the lowest order byte of the saved base pointer can be overwritten, and in this case predictably by a zero (0x00) if it does happen. This doesn't cause a crash right away; rather, it has the effect of misaligning the caller's stack frame so that when foo returns, EBP is incorrectly restored, so all addresses that the caller computes relative to EBP will be off -- for example, local variables in the caller of foo will be trashed, as well as its caller's saved base pointer and return address, since they've been "relocated" ;-). (Note that in the off chance that foo's caller's EBP just so happened to be aligned on a 256-byte boundary this overrun would have no affect at all!)
This caused a crash after foo returned and subsequently foo's caller returned to its caller -- because foo's caller's return address wasn't where it used to be relative to EBP, seeing as EBP was erroneously adjusted to point to a lower address.
The return address that was actually used was "garbage" data left over on the stack -- in the middle of the space that was occupied by the buffer in foo. Note that execution of bar() in foocaller() could potentially overwrite this space too. (In my case, that's what happened, since bar made lots of calls and had enough local variables.) This means that the return address is potentially up for grabs! Fortunately in my case, the stack frames written by bar and its subfunctions was always such that the return address would be overwritten with an unreadable memory address, so my program would access violate (SIG_SEGV) and stop when foocaller attempted to return.
This particular problem is avoided by allocating 1025 bytes instead of 1024 bytes for the buffer, because of the nature of wvsprintfA.
Scary what one little byte can do, eh? Be very cautious when copying data around!
So it turns out that the only exploit in this buffer overrun was that you could make my code crash. You couldn't actually get arbitrary code to run even though you could influence the contents of the buffer from outside of the program. But it was a close call.
D
Or maybe it's not a threat:
(3) "Windows wouldn't be able to be sold at all? There must be something wrong with the settlement plan if it would require that."
D