3

I am trying to learn about format string bugs and I found the gcc option -Wformat-security to raise a warning when a potential format string bug is found. I would like to know if there is a way to evade this check and still have a format bug problem. For example:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
  char outbuf[32];
  char buffer[32];

  if (argc < 2)
  {
     fprintf (stderr, "Error missing argument!\n");
     exit (EXIT_FAILURE);
  }

  snprintf (buffer, 28, "ERR Wrong command: %8s", argv[1]);
  sprintf (outbuf, buffer);

  perror(outbuf);

  return EXIT_SUCCESS;
}

When compiled in 32bits, it will crash on %21d input (not on %20d, but on any number higher than 20). But, the -Wformat-security will detect it and raise a warning as follow:

$> gcc -m32 -Wall -Wextra -Wformat-security -std=c99 -o fstring fstring.c 
fstring.c: In function ‘main’:
fstring.c:19:3: warning: format not a string literal and no format arguments [-Wformat-security]
   sprintf (outbuf, buffer);
   ^

So, is there a way to hide the bug from the warning and still have a possible exploitation ?

Edit: My point is not to correct the bug, but to understand what kind of format string bugs are not captured by this warning. It helps to understand where to look if no warning is raised but potential format string bugs are present.

  • -Wxxx flags only affects the warnings that are shown, it does not change the code. What is your problem? – Lekensteyn Nov 11 '13 at 22:44
  • @Lekensteyn : He want to hide the bug from the warning! – Sajjad Pourali Nov 11 '13 at 23:20
  • @Lekensteyn: Yes, this is as Sajjad Pourali said. – perror Nov 12 '13 at 0:08
4

You must keep secure format of the function and with using to junk arguments bypass format-security.
for example printf(var); is 100% unsafe format ! and compiler able to detect it, but printf(var1,var2) (it can be safe and also dangerous) ! the compiler is not smart enough to detect .
You can use a code like it printf(argv[1],"junk");

For Example

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
  printf (argv[1],argc);
  //              ^^^^---------> Junk :)
  return EXIT_SUCCESS;
}
/*
sajjad@xxx:~$ gcc -m32 -Wall -Wextra -Wformat-security -std=c99 a.c 
sajjad@xxx:~$ ./a.out %n%n%n
Bus error: 10
sajjad@xxx:~$ ./a.out %s%s%s
Bus error: 10
sajjad@xxx:~$ ./a.out %x%x%x
bffcfb242bffcfb88sajjad@xxx:~$ ./a.out %d%d%d
-10747629722-1074762872sajjad@xxx:~$ ./a.out %s
???|???sajjad@xxx:~$
/*

/*

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
  char outbuf[32];
  char buffer[32];

  if (argc < 2)
  {
     fprintf (stderr, "Error missing argument!\n");
     exit (EXIT_FAILURE);
  }

  snprintf (buffer, 28, "ERR Wrong command: %8s", argv[1]);
  sprintf (outbuf,buffer, "junk");
  //                      ^^^^^^---------> Junk :)
  perror(outbuf);

  return EXIT_SUCCESS;
}

*/
  • If I understand it well, even only one argument to the format string function will allow to disable the check even if the vulnerability is still here. Thanks for this example code ! – perror Nov 12 '13 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.