Vulnerability
Flaw covered this week is classical example of format string vulnerability.
Problem is that the whole format string provided to printf function is user controlled, so one has total control over it: he can make it look like this: %s%s%s%s
or this %s%s%s%s%s%s%s%s%s%s%s%s%n
. That's not good.
Exploitation
Formt string vulnerability is quite severe and could lead to overwriting arbitrary memory address with user controlled value - which ultimately leads to taking over process's execution flow typically by overwriting .dotrs section or overwriting entry in GOT table.
Exploitation of these kind of problems take advantage of %n format specifier in printf function (and it's derivatives). More detalis can be found here.
The only not so obvious (at least at first spot) part in this week's vulnerable piece of code is this line:
if(argc) exit(0);
Basically it prevents us from providing input data via command line arguments. Therefore it seems that we can't take advantage of format string flaw from next line:
printf(argv[3]);
To overcome this inconvenience one has to realize that in absence of command line arguments program's execution parameters will look like this:
argv[0]env[0]env[1]env[2]env[3]...env[n]
^
|
argv[3]
so argv[3]
will point to env[2]
environment variable which can be used as source of input data.
Mitigation
The obvious fix is to replace this line:
printf(argv[3]);
with the following:
printf("%s", argv[3]);
This way format string won't be controlled by the user and therefore code won't be vulnerable anymore.
To partially harden your Linux platform against these type of attacks one can compile program with -Wl,-z,relro
flags which will prevent from overwritng GOT table entries (which is commonly used in exploiting this type of flaws as mentionted in Exploitation section). Additionally compiling with _FORTIFY_SOURCE=2
flag will warn about misuses of function which use format strings.