"Steam will save the world" – Tales from the Crypto

"Steam will save the world"

I was reminded last night, that there are always going to be some constructs that your static analysis tools won’t save you from. [A point made by Microsoft’s Michael Howard, in his blog and in his new book on the Secure Development LifeStyle… er… LightCycle… er… LifeCycle]


For instance, here’s a piece of code:

#include <windows.h>


int main(int argc, char **argv)
{
    char buff[5];
    strcpy(buff,”1234567890″);
    return 0;
}


Yep, that’s a really short program that makes for a buffer overflow.


And yet, “cl /analyze” won’t complain, except to tell you that strcpy is deprecated.


So, what do you do?


The right first step, of course, is to replace strcpy – as a deprecated function, it’s kind of dangerous.


So, let’s say we replace strcpy with strcpy_s, and here’s the output I get from running “cl /analyze”:


Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80×86
Copyright (C) Microsoft Corporation.  All rights reserved.


test.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.


/out:test.exe
test.obj


So, clearly, we’re still not detecting the overflow.


“Isn’t strcpy_s safe? Do we care that it’s not detecting the overflow?”


Sure, it’s safe – but it really depends on what you call ‘safe’. Using strcpy_s like that will simply kill your process right there, with an exception:


—————————
test.exe – Application Error
—————————
The exception unknown software exception (0xc000000d)
occurred in the application at location 0x0040108f.
 


Click on OK to terminate the program
Click on CANCEL to debug the program
—————————
OK   Cancel  
—————————


[So, you did know you can press Ctrl-C in most dialogs to get the text of the message in the clipboard, right? Try it next time you need to report a dialog box error – much better than sending a graphic!]


But if you ship an application that does this, you’ll get a reputation for shipping crap.


Possibly deservedly.


What to do? I’ve known some authors who handle this by catching, and then ignoring, the exception, in somewhere like their main loop.


Quite simply, that’s the wrong thing to do – it may even be the worst thing to do. Why? Because the exception you ignore may be the test packet that gets thrown at you prior to the successful exploit. You definitely want to fail on unexpected exceptions – and a buffer overflow, even when it’s detected, should not be expected.


But, you say, this exception is expected, and will be handled in some other way – say, by telling the user that he’s entered a bad value, and requesting his input again.


Well then, it’s not an exception, and you shouldn’t use a function that makes an exception out of a commonplace occurrence. Look instead to StringCchCopy, which will return an error result when you overflow. Handle the error result correctly, and you avoid the mess and overhead of exception handling. Or, use strncpy_s with the “_TRUNCATE” parameter for the count value, and get a similar kind of handling.

2 Responses to "Steam will save the world"

Leave a Reply

Your email address will not be published. Required fields are marked *