2012-11-16 11 views
5

Ho un piccolo programma C da sfruttare. E ho anche capito la logica dietro l'attacco da eseguire. Tuttavia, per quanto io provi, non funziona proprio per me.Formato stringa Attack

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

#define SECRET1 0x44 
#define SECRET2 0x55 

int main(int argc, char *argv[]) { 
    char user_input[100]; 
    int *secret; 
    int int_input; 
    int a, b, c, d; /* other variables, not used here.*/ 

    /* The secret value is stored on the heap */ 
    secret = (int *) malloc(2*sizeof(int)); 

    /* getting the secret */ 
    secret[0] = SECRET1; secret[1] = SECRET2; 

    printf("Please enter a decimal integer\n"); 
    scanf("%d", &int_input); /* getting an input from user */ 
    printf("Please enter a string\n"); 
    scanf("%s", user_input); /* getting a string from user */ 

    printf(user_input); 
    printf("\n"); 

    /* Verify whether your attack is successful */ 
    printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2); 
    printf("The new secrets:  0x%x -- 0x%x\n", secret[0], secret[1]); 
    return 0; 
} 

ho solo bisogno di stampare l'indirizzo e il valore del segreto [0] utilizzando la stringa di formato "printf (user_input);"

Ho provato a dare qualcosa come "\ x6e \ xaf \ xff \ xff% x% x% x% x% s". ma non sta funzionando. Ogni suggerimento sarà apprezzato. Molte grazie.

+1

Se si desidera stampare l'indirizzo di qualcosa, è consigliabile utilizzare l'indirizzo dell'operatore '' & '. –

+0

+1 per codice ben formattato. –

risposta

8

Questo sembra un esercizio per una classe, quindi fornirò alcuni suggerimenti, ma non la soluzione reale.

Si sta tentando di sfruttare questo programma fornendo input non attendibili. Ci sono due bug abbastanza ovvi qui; uno è il scanf() utilizzando %s, poiché è possibile sovrascrivere il buffer e sovrascrivere lo stack. L'altro è una vulnerabilità format-string. Sovrascrivere la pila probabilmente non ti permetterebbe di fare qualcosa di interessante finché la funzione non tornasse. Sulla base della sezione "verifica se il tuo attacco ha esito positivo", probabilmente vorrai sfruttare la vulnerabilità prima di allora, quindi suppongo che si suppone che sia una vulnerabilità legata alle stringhe di formato.

In base alla sezione di verifica, è prevista la sovrascrittura della memoria indicata da secret. L'unico modo per scrivere printf in una posizione controllata in memoria è utilizzare lo specificatore di formato %n, che scrive il puntatore specificato.

Ora il trucco è capire come salire la pila fino a trovare il puntatore appropriato. Convenientemente, c'è un intero controllato dall'utente subito prima del puntatore in pila. Quindi, inseriamo un numero con uno schema facile da individuare (forse 65535, che è ffff in esadecimale) e utilizzare una stringa di formato con molto %x s per vedere cosa c'è in pila. Una volta che lo troviamo, la prossima cosa in pila dovrebbe essere il puntatore.

Hmm. Ho appena provato questo, e si scopre che non è così semplice. Il layout esatto dello stack frame non è in realtà correlato all'ordine delle dichiarazioni; e differisce tra i diversi sistemi per me. Invece, ho dovuto usare un sacco di %lx s, insieme a una stringa ben nota all'inizio, e aggiungere una linea per stampare il puntatore reale, quindi vorrei sapere quando l'ho trovato. Quindi sostituire il corrispondente %lx con lo %n per scrivere attraverso quel puntatore. Potrebbe essere più semplice provare solo 20 o più %lx s e sostituirli uno per uno con %n, fino a quando non sarai riuscito a sovrascrivere quel puntatore.

In ogni caso, spero che sia sufficiente per iniziare. Fatemi sapere se avete domande.

+2

Infatti, su x86_64 ci sono abbastanza registri che se si compila con O2 o O3, potrebbe non esserci nulla sullo stack tranne il buffer. –

+0

Inoltre, le variabili non utilizzate possono essere ottimizzate dal compilatore, quindi la configurazione effettiva dello stack potrebbe non essere quella che ci si aspetta. –

+0

Grazie mille per i tuoi input. Ricevo gli indirizzi ripetuti quando restituisco% 1x molte volte, il che mi confonde. Capisco che le variabili stack (da alto a basso) siano memorizzate nell'ordine, user_input, secret, int_input. Quindi se fornisco% 1x 8 volte, dovrei essere in grado di puntare a & int_input.segreto = 0xbffffa5c, user_input = bffffa60, int_input = bffffa58 Si prega di inserire un intero decimale Si prega di inserire una stringa % 1x% 1x% 1x% 1x% 1x% 1x% 1x% 1x bffffa60bffffa60bffffa584002c8a440021000400212d810 I segreti originali: 0x44 - - 0x55 I nuovi segreti: 0x44 - 0x55 – shambolic

Problemi correlati