Wednesday, October 05, 2005

Microsoft Visual Studios 2005 Team System, Episode II (Microsoft Visual C++ 2005 new Features Part A)

Now it's the time for the first technical article, it'll be about the new features added inside Microsoft Visual C++ Whidbey, of course it won't be a complete guide for those searching for every thing new (they can refer to C++ language specification), but Iam only listing here the new amazing features which are added to Microsoft Visual C++.


The new additions for Visual C++ are categorized into 3 main categories:

1- Additions to the core language compiler.
2- Additions for giving the applications more security.
3- Additions for optimizing the generated applications.
4- Changes in compiler switches.

We'll talk about each of these sections in more detail now.


1- Additions to the core language compiler:

During last several years, C++ compiler wasn't following the pure standard rules, in other words, Microsoft Visual C++ compiler till version 2003, was not following the standard C++ language and it wasn't conformant, it was accepting things that mustn't be accepted and was refusing things that mustn't be refused, and so when some body is trying to compiler some code from Unix or Linux on MS VC++ compiler, he'll usually get tons of compilation errors.

This problem had been solved completely, now VC++ compiler is more standard than any compiler (it's about 98% following standard rules), it's more standard than Intel's compiler and gcc, and so, now you can easily import Unix and Linux code and libraries and build them easily without any problems or errors, but you are supposed to get some errors if you compile your old code, and this will be the case only if your old code is not following the standard rules.


2- Additions for giving the applications more security:


Visual C++ 2005 adds a lot of options to make you sure that you're shipping a secure application and makes it passes through many levels of checks, I'll take the example of buffer overrun through this article to make it clear for every body, the first addition to support this, or to say the first level, is making a lot of changes in C and C++ libraries, every function which is dealing with strings or character pointers or any function which may lead to buffer overrun and such security vulnerabilities, is having a new version from it to secure your application, as example, imagine this simple application which will show you the buffer overrun vulnerability through stack overrun from writing secure code great book:




#include "stdio.h"
#include "string.h"

void foo(const char * input)
{
char buf[10];
//What? No extra arguments supplied to printf?
//It's a cheap trick to view the stack 8-)
//We'll see the trick again when we look at format strings.
printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n% p\n\n");

//Pass the user input straight to secure code public enemy #1
strcpy(buf,input);
printf("%s\n",buf);
printf("Now the stack looks like: \n%p\n%p\n%p\n%p\n%p\n% p\n\n");
}

void bar(void)
{
printf("Augh! I've been hacked!\n");
}

int main(int argc, char * argv[])
{
//Blatant cheating to make life easier on myself
printf("Address of foo = %p\n",foo);
printf("Address of bat = %p\n",bar);
if(argc != 2)
{
printf("Please supply a string as an argument!\n");
return -1;
}
foo(argv[1]);
return 0;
}

Now let's try to show how we could make the overrun happens, first let's try to run it in normal mode:

D:\Secureco2\Chapter05>StackOverrun.exe Hello
Address of foo = 00401000
Address of bar = 00401045
My stack looks like:
00000000
00000000
7FFDF000
0012FF80
0040108A <-- We want to overwrite the return address for foo. 00410EDE

Hello
Now the stack looks like:
6C6C6548 <-- You can see where "Hello" was copied in.
0000006F
7FFDF000
0012FF80
0040108A
00410EDE

Now let's try another input:

D:\Secureco2\Chapter05>StackOverrun.exe ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Address of foo = 00401000
Address of bar = 00401045
My stack looks like:
00000000
00000000
7FFDF000
0012FF80
0040108A
00410EBE

ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Now the stack looks like:
44434241
48474645
4C4B4A49
504F4E4D
54535251 <-- Return address has changed to this number.
58575655

We'll get now an error message telling us that we're trying to execute instruction at 0x54535251.
And as we see 0x54 is the code for the letter T, so if we tried this time:

D:\Secureco2\Chapter05>StackOverrun.exe ABCDEFGHIJKLMNOPQRS
Address of foo = 00401000
Address of bar = 00401045
My stack looks like:
00000000
00000000
7FFDF000
0012FF80
0040108A
00410ECE

ABCDEFGHIJKLMNOPQRS
Now the stack looks like:
44434241
48474645
4C4B4A49
504F4E4D
00535251 <-- Return address has changed to this number.
00410ECE

Now we got it, by changing the user input we're able to manipulate where the next instruction to be executed, so if we could send 0x45, 0x10, 0x40 instead of QRS, we could get bar to execute, but how we could pass these parameters and 0x10 is not even printable? We'll create a perl script (or you could create another program which passes the following input to the buffer overrun exe):

$arg = "ABCDEFGHIJKLMNOP"."\x45\x10\x40";
$cmd = "StackOverrun ".$arg;
system ($cmd);

Then run it:

D:\Secureco2\Chapter05>perl HackOverrun.pl
Address of foo = 00401000
Address of bar = 00401045
My stack looks like:
77FB80DB
77F94E68
7FFDF000
0012FF80
0040108A
00410ECA

ABCDEFGHIJKLMNOPE?@
Now the stack looks like:
44434241
48474645
4C4B4A49
504F4E4D
00401045
00410ECA

Augh! I've been hacked!


Now we knew how it could occur, now how Visual Studio has solved this problem?!

The first level is to provide the strsafe versions for strcpy and such functions, which gives another parameter which is to add the size of the buffer, when the developer is using the normal dangerous versions, the compiler will give him a warning of having the probability of exporting vulnerable code.

That looks cool, but what if the developer had committed a mistake and provided a wrong value for the buffer?!

Now we come to the second level, at execution time (this is the thing Iam not well remembering now), as you see it's all about overriding some values on the stack, the compiler will make many things, the one I am remembering now is the shadow copy of the stack and when it's trying to return will compare the old with the new and then determine if someone has made any thing over the stack or not, I am really not remembering the exact actions, so no body asks me how it's done exactly :D, but whenever I remember or find any resource on the web which is discussing how they made it, I'll put it here immediately :)


I think it's really enough for today, next time I'll resume the new additions in VC++ as I am tired now from writing all these stuff

Catch you later.....

No comments: