C'è un modo per eludere la sicurezza di Watt?

3

Sto cercando di conoscere i bug delle stringhe di formato e ho trovato l'opzione gcc -Wformat-security per generare un avviso quando viene trovato un potenziale bug della stringa di formato. Vorrei sapere se c'è un modo per eludere questo controllo e avere ancora un problema di bug di formato. Ad esempio:

#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;
}

Se compilato in 32 bit, si bloccherà su %21d input (non su %20d , ma su qualsiasi numero superiore a 20). Tuttavia, -Wformat-security lo rileva e genera un avviso come segue:

$> 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);
   ^

Quindi, c'è un modo per nascondere il bug dall'avviso e avere ancora un possibile sfruttamento?

Modifica : il mio punto non è correggere il bug, ma capire che tipo di bug della stringa di formato non vengono catturati da questo avviso. Aiuta a capire dove cercare se non viene generato alcun avviso ma sono presenti potenziali bug di stringhe di formato.

    
posta perror 11.11.2013 - 22:58
fonte

1 risposta

4

È necessario mantenere il formato sicuro della funzione e con l'utilizzo di argomenti junk bypassare la sicurezza del formato.
ad esempio printf(var); è un formato non sicuro al 100%! e compilatore in grado di rilevarlo, ma printf(var1,var2) (può essere sicuro e anche pericoloso)! il compilatore non è abbastanza intelligente da rilevare.
Puoi utilizzare un codice come printf(argv[1],"junk");

Per esempio

#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;
}

*/
    
risposta data 12.11.2013 - 00:13
fonte

Leggi altre domande sui tag