Domanda

ho ottenuto un compito a casa che mi chiedeva di richiamare una funzione senza chiamare esplicitamente, utilizzando buffer overflow. Il codice è fondamentalmente questo:

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

void g()
{
    printf("now inside g()!\n");
}


void f()
{   
    printf("now inside f()!\n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)
}

int main (int argc, char *argv[])
{
    f();
    return 0;
}

Anche se non sono sicuro di come procedere. Ho pensato di cambiare l'indirizzo di ritorno per il contatore programma in modo che procederemo direttamente all'indirizzo di g (), ma non sono sicuro di come accedervi. In ogni caso, suggerimenti sarà grande.

È stato utile?

Soluzione

L'idea di base è quella di modificare l'indirizzo di ritorno della funzione in modo che quando la funzione restituisce è continua ad eseguire ad un nuovo indirizzo violato. Come fatto da Nils in una delle risposte, è possibile dichiarare un pezzo di memoria (di solito array) e traboccare in modo tale che l'indirizzo di ritorno viene sovrascritto pure.

Io vi suggerisco di non prendere ciecamente uno dei programmi qui riportati senza realmente capire come funzionano. Questo articolo è scritto molto bene e lo troverete molto utile:

Un passo-passo sulla vulnerablity buffer overflow

Altri suggerimenti

Questo è il compilatore dipendente, quindi nessuna risposta singola può essere dato.

Il seguente codice farà quello che vuoi per gcc 4.4.1. Compilare con le ottimizzazioni disabilitate (importante!)

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

void g()
{
    printf("now inside g()!\n");
}


void f()
{   
  int i;
  void * buffer[1];
  printf("now inside f()!\n");

  // can only modify this section
  // cant call g(), maybe use g (pointer to function)

  // place the address of g all over the stack:
  for (i=0; i<10; i++)
     buffer[i] = (void*) g;

  // and goodbye..
}

int main (int argc, char *argv[])
{
    f();
    return 0;
}

Output:

nils@doofnase:~$ gcc overflow.c
nils@doofnase:~$ ./a.out
now inside f()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
Segmentation fault

Poiché si tratta di compiti a casa, vorrei fare eco suggerimento di codeaddict di comprendere come un buffer overflow funziona realmente.

ho imparato la tecnica leggendo l'eccellente (se un po 'datato) articolo / tutorial sfruttando vulnerabilità buffer overflow Smashing La Pila per divertimento e profitto .

Prova questo:

void f()
{   
    void *x[1];
    printf("now inside f()!\n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)
    x[-1]=&g;
}

o questa:

void f()
{   
    void *x[1];
    printf("now inside f()!\n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)
    x[1]=&g;
}

Anche se questa soluzione non fa uso di una tecnica di overflow per sovrascrivere l'indirizzo di ritorno della funzione nello stack, che provoca ancora g() per ottenere chiamato da f() sulla via del ritorno a main() da solo modificando f() e non chiamando direttamente g().

Funzione epilogo viene aggiunto -come assembly inline per f() per modificare il valore di l'indirizzo di ritorno sullo stack in modo che f() tornerà attraverso g().

#include <stdio.h>

void g()
{
    printf("now inside g()!\n");
}

void f()
{   
    printf("now inside f()!\n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)

    /* x86 function epilogue-like inline assembly */
    /* Causes f() to return to g() on its way back to main() */
    asm(
        "mov %%ebp,%%esp;"
        "pop %%ebp;"
        "push %0;"
        "ret"
        : /* no output registers */
        : "r" (&g)
        : "%ebp", "%esp"
       );
}

int main (int argc, char *argv[])
{
    f();
    return 0;
}

La comprensione di come funziona questo codice può portare ad una migliore comprensione di come frame dello stack di una funzione è configurato per una particolare architettura che costituisce la base di tecniche di buffer overflow.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top