Attaque par débordement de tampon

J’essaie d’exécuter une attaque très simple par débordement de tampon. Je suis à peu près un débutant à cela. Donc, si cette question est stupide, veuillez m’excuser 🙂

Le code:

#include #include int i, n; void confused(int i) { printf("**Who called me? Why am I here?? *** %x\n ", i); } void shell_call(char *c) { printf(" ***Now calling \"%s\" shell command *** \n", c); system(c); } void victim_func() { int a[4]; printf("Enter n: "); scanf("%d",&n); printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~"); for (i = 0;i <n ;i++) printf ("\na[%d] = %x, address = %x", i, a[i], &a[i]); printf("\nEnter %d HEX Values \n", n); // Buffer Overflow vulnerability HERE! for (i=0;i<n;i++) scanf("%x",&a[i]); printf("Done reading junk numbers\n"); } int main() { victim_func(); printf(“\n done”); return 0; } 

Lorsque j’utilise objdump pour obtenir les adresses de fonction, j’ai les éléments suivants:

 main(): 0x804854d Address of main() where printf() is called: 0x8048563 victim_func(): 0x8048455 confused(): 0x8048414 

Maintenant, ce que je veux, c’est sauter à la fonction ‘confused ()’ de victim_func () en y faisant déborder le tampon et en écrasant l’adresse de retour à l’adresse de confused (). Et je veux revenir de confused () à l’instruction printf () dans main et quitter normalement. Donc, je fournis l’entrée suivante

 Enter n: 7 Enter 7 HEX values: 1 2 3 4 5 8048414 (This is to jump to confused) 8048563 (this is to jump to printf() in main) 

Bien que le programme imprime “Done” à partir de cette instruction printf, il revient à victim_func () et affiche “Enter n:”

Qu’est-ce que je fais mal? Toute aide serait grandement appréciée!

PS: Je ne suis pas sûr d’avoir bien posé la question. S’il vous plaît laissez-moi savoir, si plus d’informations sont nécessaires.

Une attaque par dépassement de tampon est beaucoup plus complexe que cela. Tout d’abord, vous devez comprendre l’assembleur pour pouvoir effectuer cela. Après avoir désassemblé le programme et la fonction que vous souhaitez cibler, vous devez déterminer la disposition de la stack lors de l’exécution de cette fonction. Voici un exemple de dépassement de tampon utilisant Visual Studio, mais le principe est le même.

 #include "stdafx.h" #include  volatile double test; double function3() { test++; return exp(test); } double function2() { return log(test); } double function1() { int a[5] = {0}; a[7] = (int)&function3; return exp(function2()); } int _tmain(int argc, _TCHAR* argv[]) { double a = function1(); test = a; return a; } 

Grâce au désassemblage, nous soaps qu’une fonction in est affectée avant où la fonction a enregistré le pointeur de la stack. La valeur après celle-ci est l’adresse de retour où fonction1 doit aller si elle est terminée.

 00401090 55 push ebp <- we save the stack pointer 00401091 8B EC mov ebp,esp 00401093 83 EC 1C sub esp,1Ch <- save space to allocate a[5] 00401096 B8 CC CC CC CC mov eax,0CCCCCCCCh 0040109B 89 45 E4 mov dword ptr [ebp-1Ch],eax <- crt debug init a[5] 0040109E 89 45 E8 mov dword ptr [ebp-18h],eax 004010A1 89 45 EC mov dword ptr [ebp-14h],eax 004010A4 89 45 F0 mov dword ptr [ebp-10h],eax 004010A7 89 45 F4 mov dword ptr [ebp-0Ch],eax 004010AA 89 45 F8 mov dword ptr [ebp-8],eax 004010AD 89 45 FC mov dword ptr [ebp-4],eax 

Nous pouvons en conclure que si nous écrasons un [7] avec une adresse différente, la fonction reviendra non pas en principal mais avec l’adresse que nous avons écrite dans un [7].

J'espère que cela t'aides.

Tout d’abord, il me semble que vous ne devriez pas entrer le nombre 5 dans votre exemple de saisie. Votre tableau est déclaré un [4] a donc des éléments indexés 0-3 – donc votre entrée d’attaque me semble fausse.

Il me semble également que votre programme suppose plusieurs choses à propos de l’architecture:

  • sizof (int) == sizeof (adresse mémoire)
  • Le sens de la croissance et le mécanisme de la mise en œuvre des environnements

Si l’une de ces hypothèses est fausse, elle ne fonctionnera jamais.

Cela semble être une tâche très difficile.

Il existe des exemples plus simples d’attaques par dépassement de mémoire tampon que de modifier le stream de contrôle du code. Par exemple, vous pouvez éventuellement écraser un autre élément de données censé être protégé de l’utilisateur (tel qu’un paramètre de sécurité).

Maintenant, ce que je veux, c’est sauter à la fonction ‘confused ()’ de victim_func () en y faisant déborder le buffer et en écrasant l’adresse de retour à l’adresse de confused () …

Sur les plateformes Linux modernes, vous devez également vous assurer que deux fonctions de sécurité sont désactivées pour les tests. Le premier est NX-Stacks et le deuxième est Stack Protectors.

Pour désactiver NX-Stacks, utilisez -Wl,z,execstack (par opposition à -Wl,z,noexecstack ). Pour désactiver les protecteurs de stack, utilisez -fno-stack-protector (par opposition à -fstack-protector ou -fstack-protector-all ).

Vous devrez peut-être désactiver la troisième protection. Cette protection est FORTIFY_SOURCE. FORTIFY_SOURCE utilise des variantes “plus sûres” de fonctions à haut risque telles que memcpy et strcpy . Le compilateur utilise les variantes les plus sûres pour déduire la taille de la mémoire tampon de destination. Si la copie dépasse la taille de la mémoire tampon de destination, le programme appelle alors abort() . Pour désactiver FORTIFY_SOURCE, comstackz le programme avec -U_FORTIFY_SOURCE ou -D_FORTIFY_SOURCE=0 .

Les fonctions de sécurité sont activées par défaut car il y a eu beaucoup de problèmes dans le passé. En général, c’est une bonne chose car il arrête de nombreux problèmes (comme celui que vous expérimentez).

Vous ne nous avez pas montré la sortie du programme avec les adresses d’un [i]. Je soupçonne que le compilateur fait quelque chose comme aligner les données de la stack sur 16. Cela pourrait être beaucoup plus loin que l’adresse de retour que ce à quoi vous vous attendiez.