Shattering Windows
ChrisPaget writes: "I've just released a paper documenting and exploiting fundamental flaws in the Win32 API. Essentially, they allow you to take control of any window on your desktop, regardless of whether that window is running as you, localsystem, or anywhere in between. The technique has been discussed before, but AFAIK this is the first working exploit. Oh, did I mention it's unfixable?" You may want to read this CNET interview with Microsoft security head Scott Charney to learn even more about "trustworthy computing."
You misunderstand. He's talking about NT/2000/XP, where you have privilege and non-privilege accounts, and where even as a non-privilege account, you can have stuff running as the Windows equivalent of "root", and you can use any window that "setuid root" application pops up to root the box yourself.
The example he gave is the anti-virus program that runs with administrator privs (because it has to do stuff to the registry), when you're logged in as Joe User without admin privs. The anti-virus program pops up a window, and bam, you've hijacked the window, given yourself admin privs, made a new administrator login for yourself, and you're away to the races.
The next Cmdr Taco duplicate will be ready soon, but subscribers can beat the rush and see it early!
This isn't a flaw in the win32 API. This is a flaw in some applications which run under windows.
No to the former; yes to the latter. 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.
If you're talking about a large enterprise installation with lots of closed-source apps and a vendor turnaround time on security issues which runs into the months--and there are a lot of them out there, make no bones about it--then your boxes are at critical risk. In that case, you're essentially guaranteed to have at least one app an attacker can root the box through. Sure, it may be the app's fault for not separating interface and back-end sanely, like most of us who give a damn about good engineering learned (sometimes the hard way)... but it's also the Win32 API's fault for not requiring separation of interface and back-end [*], it's the Win32 API's fault for being so shoddily designed that an attack like this becomes possible in the first place.
A good analog in the UNIX world is sprintf(), which has been responsible for more stack-smash attacks than probably any other thing. Even though we have snprintf(), most people don't know snprintf() exists or why it should be used. Like the Win32 window exploit, our sprintf() vulnerabilities will continue for as long as people write stupid code. Like the Win32 window exploit, we can't fix the problem by removing sprintf() [**]. All we can do is provide snprintf() and hope and pray that people use it.
sprintf() is a flaw in the UNIX/C API which has led and continues to lead to attacks against the system, facilitated by stupidly-designed software which uses the call even when snprintf() is available. sprintf() can't be removed without breaking literally thousands of stupidly-written apps which depend upon it.
This Win32 attack is a flaw in the Win32 API which has led and continues to lead to attacks against the system, facilitated by stupidly-designed software which doesn't separate interface and back-end. This Win32 attack can't be removed without breaking literally thousands of programs.
Hey, guess what, world? We've found Win32's version of sprintf(). Oh, happy day.
My condolences go out to any security engineers working in Win2K land. You guys have got your work cut out for you minimizing this exploit.
[*] Not that I have any idea how they could do this.
[**] sprintf() is defined in C89. Good luck getting rid of it.
I'm really, really disgusted that this even got posted. This isn't a Win32 vulnerability, it's a Virusscan vuln. (Watch my karma burn, I'm actually defending MSFT... but hear me out.)
For those of you who aren't familiar with Windows programming, here's what he's doing. Viruscan's GUI is very poorly written and doesn't check for a maximum length on a text box's input. So, he adjusts the size of a textbox using an outside program to 4GB. (Windows unfortunately allows this, since the message format doesn't include a "sender" field to check against the owner handle.) He then inserts shellcode in it, attaches a debugger to the process and searches all of memory for the start of the shellcode. Real efficient, this one.
He then sends it a WM_TIMER message to trigger it. WM_TIMER is usually sent to your window on a regular interval when you've called SetTimer(), and contains either an integral ID or a pointer to a callback in memory. So, he sends it a fake WM_TIMER, and Viruscan executes the callback blindly.
You know what, I use WM_TIMER too in my apps - but, there's two simple ways to defend against it.
if ((void *) msg.lparam != known_cb_address)
{
return false;
}
if (0 != IsBadCodePtr((FARPROC) msg.lparam))
{
go_fuck_yourself();
}
And if I'm not using it, special-case it so that it doesn't fall through to DefWindowProc().
Seriously, all this guy is doing is buffer overflowing a poorly written program to get Administrator privs. That's like claiming that glibc is insecure and should be thrown out because it has sprintf() or gets(). Ya know, I can buffer overflow a poorly written suid app too, but that doesn't make the libc to blame, nor have we published articles lambasting the GNU Project for not putting bounds checking into those functions.
This guy's just trying to sell himself, and you guys were more than helpful. Maybe I should write a system service that subclasses MSIE's WndProc with a single function that calls ExitProcess(1), and see if Slashdot will find me a security job.
The point remains that it isnt a question of "a user runs unknown code, they're screwed" - in this scenario the USER is the attacker.. they already have a legit account but it doesnt have administrator privs. They want to get past some restriction on their account - like maybe locate and disable any nasty corporate keyloggers that might get them fired for pr0n-mining, or plant some nasty stuff on a shared PC to grab other accounts credentials so somebody ELSE gets fired for it? Lots of attacks come from inside and lots of *nix attacks are described as "local root" compromises - thats what we have here.
To rephrase your statement its more a question of "if a user can get localsystem privs by running arbitrary code, you (as the sysadmin) are screwed."
This isnt specific to windows or any other OS for that matter. If any user can get arbitrary code to run with a higher privilege level than their own, this kind of hole exists.
I had a