Come eliminare gli indirizzi con gli exploit delle stringhe di formato

1

Giocando su vari wargames ho notato che continuavo a rimanere bloccato sulle vulnerabilità delle stringhe di formato, così ho deciso di fare un passo indietro e riapprenderli da zero. Nel processo ho capito che non potevo spiegare a me stesso perché possiamo leggere / scrivere in posizioni arbitrarie fornendo un indirizzo valido.

printf (\x41\x41\x41\x41_%08x_%08x)

In base alla mia comprensione delle stringhe di formato, questa chiamata di funzione dovrebbe semplicemente stampare AAAA + stack value + stack value e nient'altro. Invece, perde due indirizzi a partire dall'indirizzo fornito

Da link

The format function now parses the format string ‘A’, by reading a
character a time. If it is not ‘%’, the character is copied to the output. In
case it is, the character behind the ‘%’ specifies the type of parameter that
should be evaluated. The string “%%” has a special meaning, it is used to print
the escape character ‘%’ itself. Every other parameter relates to data, which
is located on the stack

Se l'affermazione precedente è vera e \x41\x41\x41\x41_%08x_%08x è l'unico argomento di printf () allocato nello stack, come possiamo spiegare la lettura / scrittura da / a posizioni di memoria?

MODIFICA 1:

Questa risposta in realtà specifica che possiamo diffondere qualsiasi indirizzo che vogliamo, ma non va oltre come iniziare a perdere da una posizione di memoria arbitraria.

I questa altra risposta

So you're asking how printf can find the string because there is a
different parameter count than the % signs say? Two thought problems here: a)
Before printf can count the % at all, it has to find the string. Wrong string
content can't prevent finding this string. b) Without attacks: printf supports
variable parameter counts, and it always can find the string. Last parameter
etc. doesn't matter.

Per qualche motivo l'OP presuppone che la parte 'AAAA' sia un vero indirizzo.

    
posta shxdow 12.03.2017 - 01:10
fonte

1 risposta

2

@LiveOverflow mi ha aiutato a capire cosa non potevo ottenere. Entrambe le supposizioni che avevo erano vere

  1. printf stampa semplicemente ciò che non è mai un '%' e tratta in modo speciale i caratteri che seguono '%'
  2. Formattatori (% x,% s, '% n, ecc ...) SOLO utilizzano gli indirizzi trovati nello stack (ciò che intendo è che se iniziamo a caricare i valori utilizzando% x, tali valori verranno inseriti nello stack finché sono disponibili indirizzi validi

Ora nel codice della domanda, fornire un indirizzo come primo argomento non è sufficiente, dobbiamo in qualche modo mettere nello stack l'indirizzo che vogliamo leggere / scrivere da / a

Esempio:

vuln.c (gcc -g vuln.c -m32 -o vuln):

#include <stdio.h>

int main (int argc, char ** argv) {

    buffer[32];

    fgets (buffer, sizeof(buffer), stdin);

    printf (buffer);

    return 0;
}

Possiamo farlo chiamando il programma con un argomento ./vuln AAAA . Alla richiesta di input possiamo inserire la nostra stringa di formato. Ecco il trucco: dobbiamo eliminare i valori fino a trovare il nostro AAAA , dopo che %s avrebbe dereferenziato l'indirizzo AAAA e leggere una stringa da lì, facendo fuoriuscire un indirizzo arbitrario. Scrivere su un indirizzo funziona nello stesso modo.

Per semplicità, l'ho compilato con -g in modo da poter usare il * argv symbol

pwndbg> x/4s *argv
0xffffd258: "/home/ncrntn/vu"...
0xffffd267: "ln"
0xffffd26a: "AAAA"
0xffffd26f: "XDG_CONFIG_DIRS"...

A questo punto sappiamo dove guardare

pwndbg> x/200wx $esp
. . .
0xffffd260: 0x6e746e72  0x6c75762f  0x4141006e  0x58004141
. . .

E abbiamo effettivamente trovato il nostro AAAA (in hex \ x41 \ x41 \ x41 \ x41)

    
risposta data 16.03.2017 - 15:44
fonte

Leggi altre domande sui tag