Not even making it to the airtight hatchway: Execution even before you get there


Today’s dubious security vulnerability comes from somebody who reported that the Load­Keyboard­Layout function had a security vulnerability which could lead to arbitrary code execution. This is a serious issue, but reading the report made us wonder if something was missing.

// sample program to illustrate the vulnerability.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int __cdecl main(int argc, char **argv)
{
 LoadKeyboardLayout("whatever", system("notepad.exe"));
 return 0;
}

According to the report, this sample program illustrates that the Load­Keyboard­Layout function will execute whatever you pass as its second parameter. In this case, the program chose to launch Notepad, but obviously an attacker could change the code to something more dangerous.

We had trouble trying to figure out what the person was trying to say. After all, it’s not the Load­Keyboard­Layout function that is executing the second parameter. It’s the sample program that’s doing it, and using the return value as the second parameter to the Load­Keyboard­Layout function. I mean, you can use this “technique” on the function

void donothing(int i) { }

to demonstrate that the donothing function has the same “vulnerability”:

donothing(system("notepad.exe"));

Logically, the compiler decomposes the call to Load­Keyboard­Layout function as

 auto param2 = system("notepad.exe");
 LoadKeyboardLayout("whatever", param2);

and now it’s clear that it’s not the Load­Keyboard­Layout function which is executing its second parameter; it’s you.

This is like taking a printed picture of your friend into a secured area, then saying, “See, I have a picture! Your security failed to stop me from taking a picture!” That picture was taken outside the secured area. What you have is not a security vulnerability because the picture was taken on the other side of the airtight hatchway.

Before contacting the submitter, we want to be sure that we weren’t missing something, but after looking at it from every angle, we still couldn’t see what the issue was. We ran the alleged exploit under the kernel debugger and traced through the entire Load­Keyboard­Layout function (both the user-mode part and the kernel-mode part) to confirm that the function never launched Notepad on its own. We repeated the investigation on all service packs on all versions of Windows still under support (and even some that are no longer supported). Still nothing.

Stumped, we contacted the submitter. “From what we can tell, the call to system takes place before you call the Load­Keyboard­Layout function. Can you elaborate on how this constitutes a vulnerability in the Load­Keyboard­Layout function?”

Apparently, the submitter didn’t quite understand what we were after, because the response was just more of the same. “I have discovered that the Visual Basic MsgBox function has a similar vulnerability:

Module Program
Sub Main()
 MsgBox(System.Diagnostics.Process.Start("notepad.exe").ToString())
End Sub
End Module

The MsgBox method will execute whatever you pass as its parameter, as long as the result is a string. (You can even pass something that isn’t a string, but it’ll throw an exception after executing it.) The documentation for MsgBox clearly states that the function displays a message box with the specified text. It should therefore display a string and not execute a program!”

At this point, we had to give up. We couldn’t figure out what the person was trying to report, and our attempt to obtain a clarification was met with another version of what appeared to be the same nonsense. As I recall, this entire investigation took five days to complete, plus another day or two to complete the necessary paperwork. Each year, 200,000 vulnerability reports are received, and each one is taken seriously, even the bogus-looking ones, because there might be a real issue hiding behind a bogus-looking report. Sort of how the people in the emergency communication center have to follow through on every 911 call, even the ones that they strongly suspect are bogus, and even though dealing with the suspected-bogus ones slows down the overall response time for everyone.

These sort-of-but-not-quite reports are among the most frustrating. There’s enough sense in the report that it makes you wonder if there’s a real vulnerability lurking in there, but which remains elusive because the author is unable (perhaps due to a language barrier) to articulate it clearly. They live in the shadowy ground between the reports that are clearly crackpot and the reports which are clear enough that you can evaluate them with confidence. These middle-ground reports are just plausible enough to be dangerous. As a result, you close them out with trepidation, because there’s the risk that there really is something there, but you just aren’t seeing it. Then you have nightmares that the finder has taken the report public, and the vulnerability report you rejected as bogus is now headline news all over the technology press. (Or worse, exploits start showing up taking advantage of the vulnerability you rejected as bogus two months ago.)

Update: Sure, this looks like something you can reject out of hand. But maybe there’s something there after all. Perhaps the system call somehow “primed the pump” and left the system in just the right state so that an uninitialized variable resulted in Notepad being launched a second time or editing its token to have higher privileges. In that case, you rejected a genuine security vulnerability, and then when hackers start using it to build a botnet, somebody will go back into the vulnerability investigation logs, and the only entry will be “Rejected without investigation by Bob.”

Comments (38)
  1. John says:

    It is a bit unsettling that people like this are out there writing software.

  2. Tim says:

    Maybe the customer comes from a functional-programming background, and thinks that lazy evaluation is working even for parameters to system calls…

  3. Jon says:

    @John

    It could always be a kid just learning to program by playing around on his own that doesn't really understand the basic concepts of how function calls work and how expressions are evaluated. After discovering this "exploit" and not understanding what is really going on, he can tell his friends about all how he is an amazing hacker finding all sorts of flaws in Windows. His exploits are so advanced that the Microsoft employees he reported them to couldn't even figure out how they work!

  4. Diego says:

    How come you can't see the security flaw? LOL

  5. @Mongo says:

    No, wait, it's worst.

    Every operator, including comma also has the vulnerability. And even just (). Oh wait even if you don't write anything at all. It must be a vulnerability due to ending the lines with ;

    Maybe the JS guys were right after all.

  6. JM says:

    The actual vulnerability is apparently that LoadKeyboardLayout() can be called after executing arbitrary code — and by extension every API function has this problem. The solution is to make LoadKeyboardLayout() return an error if it detects it was executed after arbitrary code. We can't know what the code was, so we have to be conservative.

  7. No One says:

    @JM: I agree!  This "arbitrary code" thing is such a plague.  We really just need to stop attackers from being able to use "arbitrary code" and all the security vulnerabilities would go away, amirite?  Can we get that implemented in Windows 8 — a security feature that turns off "arbitrary code execution"?

  8. Stephen Nuchia says:

    Like grading math homework — the ones that aren't obviously wrong take more time than everything else combined.

  9. Joshua Ganes says:

    I'm glad that Microsoft takes security seriously, but I'm surprised that you allowed this particular incident to consume so many resources. Programmers worth their salt would be able to recognize the flaw in the logic of this report very quickly. At that point, I can understand going back to the original submitter for clarification. After the reply you were given, you can conclude that the submitter is either profoundly confused or so poor of a communicator that it will be nearly impossible to get to the meat of the issue.

    This sounds like a very expensive Denial of Service attack. Find a few hundred people to each file a vague but concerning vulnerability report. Now sit back and watch while Microsoft wastes several developer years following false leads.

    [Oh, we recognized it immediately. But it was so obviously wrong that we began to fear that we were missing something. And you don't want to go back to somebody and say "You are an idiot," if in fact they found something but simply expressed it poorly. -Raymond]
  10. Joshua says:

    In the same vane, disabling the signature verifying code in the bootloader (this can only be done by modifying the bootloader) to load a modified kernel is not a security vulnerability.

  11. Phil W says:

    First, get into somebody's system by breaking down the door and finding a logged-on a computer. Second, copy this program in from your memory stack and run it. See!!! There's a vulnerabilty!!!

    Duh….

  12. mikeb says:

    > As I recall, this entire investigation took five days to complete, plus another day or two to complete the necessary paperwork. <<

    So the real vulnerability that was exposed was a denial-of-service attack on Microsoft's security vulnerability investigation team.  Anybody can send in a knucklehead security defect description and tie up those resources for a whole week!

    Watch out for the security defect report about the zero-day backdoor in the "Run" control that can be optionally enabled on the Start button…

  13. Skyborne says:

    I think I've seen all these comments before, but they have today's date.  It appears that Raymond has found a way to DoS his blog readers, by repeating themes from past posts.  The theme event triggers a predictable cascade of rants against Microsoft by the readers' installed handlers….

  14. Anonymous Coward says:

    @Joshua and Raymound: Maybe it was worth the time to check it out but it wasn't worth the time to write an article about it. It definitely wasn't worth our time reading it.

    [Your money has been refunded. In the future, you can ignore "airtight hatchway" articles. -Raymond]
  15. DOS 101 says:

    while(true)

    {

     SendVulnerabilityToMs(RandomApi+BogusParams);

     Sleep(4days);

    }

  16. Me says:

    >They live in the shadowy ground between the reports that are clearly crackpot and the reports which are clear enough that you can evaluate them with confidence.

    >Oh, we recognized it immediately. But it was so obviously wrong that we began to fear that we were missing something.

    I don't see how these two statements fit together. If this report didn't hit the "crackpot" bar then what does??? Or did you mean it overflowed the scale and came out negative? You said yourself it's obviously from someone who doesn't know how computers work.

    @AC: Wrong on all accounts, IMO. Not worth wading through with the kernel debugger, but the article was definitely worth a read.

    [That is not crackpot. This is crackpot. While the initial reaction is that it's obviously from somebody who doesn't know how computers work, it could be that the problem was actually more subtle. (For example, maybe the system call left the system in just the right state that an uninitialized variable in Load­Keyboard­Layout caused a second copy of Notepad to run.) Think of the news articles where somebody finds a real exploit and adds, "I reported this to Microsoft, and they said there was no security vulnerability." -Raymond]
  17. Mike says:

    I like how you take the time to personally contact an anonymous crackpot wasting your time, but you don't contact paying customers who report non-security bugs that affect their ability to actually use their computers. It's like you care 100X more about your company's security reputation than the well-being of customers whose cash eventually becomes your salary.

    [When you write "you", is that the singular or plural? Because I didn't personally contact the (what we assumed to be) crackpot. -Raymond]
  18. Mongo says:

    It's even worse than previously thought — *every* API that takes an INT parameter is vulnerable to the system("notepad.exe") attack.

    :)

  19. Kawahee says:

    You should have gone back to the customer and chastised him for writing such insecure code:

    main(system("notepad.exe"), NULL); // Launches notepad!

    Joking aside, although you might fault Microsoft for wasting (in hindsight) 5 days investigating this issue, you can't fault them for taking security seriously.

  20. Willie says:

    Haters are gonna hate.

    Keep up the good work Raymond, I enjoy reading your stories.

  21. kme says:

    Are you sure that this bug reporter wasn't just trolling you?

  22. JM says:

    @Joshua: you're right, that *is* a serious concern. You should file a meta-vulnerability report.

    Figuring out why the meta-issue tracker isn't subject to the same attack and how to modify it to make it work anyway are left as exercises to the reader.

  23. JM says:

    @No One: actually, Windows already has a feature like that — kernel drivers need signing and the same move is being made towards BIOSes. And, of course, console hardware tries its best to prevent arbitrary code from being executed, though most such schemes have been circumvented.

    An OS that utilizes "default deny" for all code would be a severe pain to administer, but you could certainly make it more secure than OSes that will run any old executable. Of course, on such an OS a function like "system" probably should not exist — makes it too hard to keep an overview of what code is calling what, even if both caller and callee are trusted. If it did exist, its use would be regulated so that not just any old application could start Notepad, but only those authorized to do so. And that is *before* checking user permissions.

    Now, one problem this leaves is that the security doesn't really properly percolate to all levels. What if the processor contains malicious microcode? Could have slipped in during an update. Not just any process should be able to add two numbers together, is all I'm saying…

  24. fool [MSFT] says:

    The bug report was from inside the house. That's why mr chen spent a week on crackpot.

  25. yuhong2 says:

    BTW, what is irritating for me is that DoS/BSoD attacks against win32k are not considered security when on a terminal server it can kick hundreds of users off.

  26. Mark S says:

    'fool' – I'm not sure that's a mitigating factor..was that a hire from back in the "how many golf balls fit in a school bus" days?

  27. I don't get it says:

    Raymond writes an interesting and amusing post, and someone complains that Microsoft cares *too much* about security?

    And how on earth is "caring about security" supposed to be the opposite of caring about the well-being of customers who are harmed when people exploit security holes?

    Some people just love to complain.

  28. John says:

    I don't think he was complaining about caring too much about security.  I think he was complaining about being overly sensitive to the point of wasting a few days on something that is obviously not an issue.  If this came across my desk I would not even bother to test it, let alone kernel debug a number of Windows versions.  On the flip side, perhaps this report is so dumb that it just shuts your brain down and forces you to validate your very existence.

  29. Ian Boyd says:

    That might just be crazy enough to work.

  30. Paul DeCarlo says:

    Great read. Good to know Microsoft keeps a good eye out on security and listens to reports.  It may not have been the best idea to inform the masses that your time can be abused with frivolous reports, but then again, any bug submission system is susceptible to abuse, it's not just Microsoft.  To criticize Microsoft as being the center of fault for not skipping over the issue is rather short-sighted as some critics are relaying.  Some people just want to watch the world burn.  

  31. CarlD says:

    Maybe all those who would immediately dismiss this as crackpot don't realize that real bugs that seem as impossible as this do in fact occur.  I've no doubt that some of those result in security vulnerabilities.  Spend some time thinking about Raymond's example of an uninitialized variable in LoadKeyboardLayout() containg some remnant of the execution of that call to system() and it's not hard to imagine that bizzare linkages involving calling a particular sequence of otherwise benign APIs could in fact result in a security loophole.

  32. How about kernel memory exaustion by opening COM port, setting infinite timeouts, queueing a READ request, and then queuing a bunch of IOCTL_SERIAL_SET_QUEUE_SIZE with big buffer size requested (over a page, like 1 MB). Is it bogus or not?

  33. Joshua says:

    @algerl: Why bother? Until the system is no longer susceptible to forkbomb-like techniques this is pointless.

  34. Nik says:

    This is great: Mike says "It's like you care 100X more about your company's security reputation than the well-being of customers whose cash eventually becomes your salary."

    Could this be the first time that Microsoft has been criticized for caring too much about security at the expense of raking in more cash ?  I find this heartwarming.

    Raymond, your blog (which I love) used to have a clever sub-heading, something along the lines of "enriching our learns etc".  Maybe the new sub-heading should be "haters gonna hate".  Or "they see me codin', they hatin'"

    Also, I'm impressed you've kept this blog up in spite of all the pointless knee-jerk criticism and nit-picking.

  35. Mark says:

    I'm actually fairly impressed at the attention bug reports are paid. Definitely a change in opinion about how serious I think microsoft take security issues. Fair play for investigating this even if you did suspect it was a waste of time.

  36. LarryOsterman says:

    I remember when this one came in.  There was a surprising amount of investigation done on this on – what Raymond left out was that the investigation was done in parallel on every version of Windows that is supported, even those under a custom support agreement (download.microsoft.com/…/custom_support_agreement.pdf)

  37. John Hensley says:

    "Apparently, the submitter didn't quite understand what we were after, because the response was just more of the same."

    Attention a-holes: When a support contact asks you a question, before you do anything else, ANSWER THE G**-D*** QUESTION. Or at least acknowledge that there was a question and you're not sure what it means.

  38. yuhong2 says:

    Yep, FYI CSAs for Windows cost $50,000 per quarter for the first year after end of support, and increases every year thereafter.

Comments are closed.