2017-08-25 2 views
-3

Supposons que je le programme suivant:vulnérabilité chaîne de format et les chaînes d'entrée

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

int main (int argc, char **argv) 
{ 
    char buf [100]; 
    snprintf (buf, sizeof buf, argv [1]) ; 
    buf [ sizeof buf -1 ] = 0; 
    printf ("%s \n" , buf) ; 
    return 0 ; 
} 

Si je compile et exécutez-le:

gcc test.c -o test 
./test %p%p%p 
(nil)0x4006d00x7f67e05b7ab0 

Je peux voir les valeurs de la pile, ce qui signifie qu'elle est affectée par la vulnérabilité de format de chaîne.

Maintenant, modifions légèrement le code ci-dessus:

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

int main (int argc, char **argv) 
{ 
    char buf [100]; 
    printf ("%s \n" , argv[1]) ; 
    return 0 ; 
} 

Si je recompiler et re-exécuter, la vulnérabilité a disparu:

gcc test.c -o test 
./test %p%p%p 
%p%p%p 

Pourquoi cela se produit, ce changé du premier exemple?

En outre, dans le premier exemple, ne devrait pas les % s dans le printf considérer buf comme une chaîne? Pourquoi un tel code est-il toujours affecté par la vulnérabilité de format de chaîne?

+0

'% p% p% p' est boiteux, essayez'% n% n% n% n' – Jasen

+0

ces espaces supplémentaires sembler terrible.ils rendent * plus difficile * de lire ce qui se passe –

+0

Eh bien, vous avez complètement supprimé la partie vulnérable, pour une chose. – user2357112

Répondre

0
snprintf (buf, sizeof buf, argv [1]) ; 

vous venez de abusé snprintf comme vous ne l'avez pas passé les paramètres en fonction de votre chaîne de format %p%p%p.

Donc vous avez juste un UB.

Vous devez par exemple (avec la même chaîne de format)

snprintf (buf, sizeof buf, argv [1], argv[0], buff, "Hello, Show where string literals are stored") ; 
1

Si vous voulez que la sortie du premier extrait pour correspondre à la seconde, puis il suffit d'utiliser la même mise en forme spécificateur que vous avez utilisé pour printf, à savoir :

snprintf (buf, sizeof buf, "%s", argv [1]); 
          ^^^^ 

Dans ce cas, la chaîne argv[1] n'est pas traitée comme un modèle de mise en forme pour d'autres arguments, et vous obtenez tout simplement %p%p%p écrit à buf.

Avez-vous eu l'intention de copier la chaîne à la place? Je demande parce que snprintf se termine automatiquement la mémoire tampon, vous ne pas besoin de définir le terminateur null manuellement (et c'est usually done when using strncpy):

strncpy (buf, argv [1], sizeof buf); 
buf [ sizeof buf - 1 ] = 0; 
1

Vous demandez au sujet de la vulnérabilité de chaîne de format. La vulnérabilité de format de chaîne se produit chaque fois qu'une chaîne fournie par l'utilisateur est utilisée comme le format toute fonction*scanf ou *printf. Dans le premier fragment de la vulnérabilité est snprintf. Dans le deuxième fragment votre printf a la chaîne de format "%s". Il n'a pas été fourni par l'utilisateur, donc aucune vulnérabilité. Essayez

printf(buf);