2014-01-16 6 views
6

Ja, eine ganze Reihe ähnlicher Fragen existieren bereits (5037601, 19166698, 4855162, 14505995, 5052648, 13409508, 7745146, 7459630; sorry, nicht genug rep für mehr als 2 Links), und ja , es gibt einige schöne Artikel, die diese Art von Sache erklären (click, click, http: //codearcana.com/posts/2013/05/02/introduction-to-format-string-exploits.html). Ich habe sie gelesen, und ich denke, ich bekomme die allgemeine Idee, schaffe es aber immer noch nicht, das einfachste Trainingsspielzeug, das mir einfällt, erfolgreich zu nutzen.Überschreiben Absenderadresse einfaches Format Zeichenfolge Exploit

#include <stdio.h> 

void f(char* a) 
{ 
    printf("a: %p\n", &a); 
    printf(a); 
    return; 
} 

void main(int argc, char** argv) 
{ 
    f(argv[1]); //please ignore the lack of any check 
    return; 
} 

Ja, der Stapel ist ausführbar und ja, Speicher Layout Randomisierung ist deaktiviert. Jede Ausführung gibt mir die gleiche Adresse a. Ich kann es füttern zum Beispiel $ ruby -e 'print "AAAA"+("%08x."*16)', und das führt zu:

a: 0xbfffece0 
AAAAbfffece0.bfffecf0.b7fd7ff4.00000000.00000000.bffffcf8.080484b0.bfffecf0.00000fff.b7fd8420.00000000.41414141.78383025.3830252e.30252e78.252e7838. 

jetzt So kann ich sehen, wo meine Eingabe im Speicher landet. Ich kann mit $ ruby -e 'print "12345%n"+("%08x."*16)', Wert auf den Stack schreiben, die in diesen Ergebnissen:

a: 0xbfffece0 
12345bfffecf0.b7fd7ff4.00000000.00000000.bffffcf8.080484b0.00000005.00000fff.b7fd8420.00000000.34333231.256e2535.2e783830.78383025.3830252e.30252e78. 

Offensichtlich mein Ziel vermutlich so etwas wie <something><NOPs><shellcode> wäre, wo <something> die Absenderadresse von f überschreibt, so dass das Programm springt in den NOP-Schlitten und führe den Shellcode aus. Aber die Adresse der gespeicherten Absenderadresse scheint jetzt von meiner Eingabe abhängig zu sein, oder? Etwas Ähnliches wie 0xbfffece0 - len(input) - 12, unter der Annahme eines 12-Byte-Prologs? Vielleicht ist dieses Beispiel doch nicht das einfachste ...

Ich bin verwirrt. Irgendwelche Ideen?

+0

In der Tat, da die Argumente für 'printf' auf den Stack geschoben werden, ändert sich die Adresse der Rückgabeadresse entsprechend Ihrer Eingabe.Ihre Formatzeichenfolge muss dann so viele Bytes wie sie selbst "konsumieren", plus alles andere bis zur Rücksendeadresse. –

+0

Können Sie vielleicht ein konkretes Beispiel geben, zum Beispiel einen 50-Byte-Shellcode und keine NOPs? –

+0

http://stackoverflow.com/questions/7459630/how-can-a-format-string-vulnerability-be-exploited –

Antwort

0

Ich schlage vor, Sie verwenden eine lange Reihe von '% 08x' Format-Zeichen, um den richtigen '% n' Wert in der Eingabe herauszufinden, so dass es die Rücksendeadresse überschreibt.

12345%n%08x%08x%08x%08x........%08x%08x 

Weiter können Sie Ihre Eingabe ersetzt einen Teil des ‚% 08x‘ string mit NOP Schlitten + Shellcode halten die Länge des Eingangs gleichen ändern.

12345%n\x90\x90\x90\x90...\x90\x90SHELLCODE 

(Ändern% n Formatspezifizierer oben als erforderlich, um einen korrekten Wert zu schreiben)

Dadurch wird sichergestellt, um die Größe des Eingangs und damit die Position der gespeicherten Absenderadresse bleibt gleich.

0

Eine andere Idee ist die Verwendung des "dolor sign" %<distance>$n.

von Linux printf manpage Zitiert:

Man kann auch explizit angeben, welches Argument genommen wird, an jedem Ort, an dem ein Argument erforderlich ist, um "% m $" zu schreiben. Wo die dezimale ganzzahlige m die Position in die Argumentliste des gewünschten Argument bezeichnet, indizierte ausgehend von 1. Source

Beispiel:%5$n würde von der Oberseite des Stapels in den 5. Adresse schreiben.