Kompilieren Sie C, um Pufferüberlauf zu ermöglichen

9

Ich lerne über Pufferüberläufe und versuche, einen zu machen. Ich habe diesen Code:

%Vor%

Ich kompiliere das mit gcc und führe es dann in gdb

aus

Ich gebe etwa 100 "A" s als Passwort ein und das Programm stürzt ab.

Das Problem ist, dass kein Register in 0x4141414141414141

überschrieben wird

Ich habe das gegoogelt und das -fno-stack-protector Flag zu gcc hinzugefügt, was es erlaubt hat RBP in 0x4141414141414141 zu überschreiben, aber sonst nichts.

Ich habe mich gefragt, ob es eine Möglichkeit gibt, den Code zu kompilieren, damit RIP überschrieben werden kann.

    
carloabelli 09.02.2013, 15:56
quelle

2 Antworten

3

Ihr Code macht bereits, was Sie wollen, wenn Sie mit -fno-stack-protector kompilieren. Der Grund, warum Sie RIP mit einem Wert von 0x4141414141414141 in GDB nicht sehen, ist, dass ein allgemeiner Schutzfehler ausgelöst wird, bevor RIP aktualisiert wird. (Wenn ein Seitenfehler auftritt, lädt der GPF-Handler normalerweise die Seite aus dem Swap und setzt die Ausführung fort, indem er mit der fehlgeschlagenen Anweisung beginnt.)

    
nwellnhof 10.02.2013, 21:54
quelle
1

Der Grund dafür, dass EIP 0x41414141 auf x32 abstürzt, liegt daran, dass die CPU versucht, den Befehl an der Speicheradresse 0x41414141 auszuführen, wenn das Programm den zuvor gespeicherten EIP-Wert aus dem Stack und zurück in EIP löscht ein segfault. (Es muss die Seite vor der Ausführung des Kurses abrufen)

Nun, während der x64-Ausführung, wenn das Programm den zuvor gespeicherten RIP-Wert wieder in das RIP-Register kopiert, versucht der Kernel dann, die Anweisungen unter der Speicheradresse 0 × 4141414141414141 auszuführen. Erstens müssen aufgrund der kanonischen Formadressierung die Bits 48 bis 63 einer beliebigen virtuellen Adresse Kopien des Bits 47 sein (ähnlich der Zeichenerweiterung), oder der Prozessor wird eine Ausnahme auslösen. Wenn das kein Problem war, führt der Kernel zusätzliche Prüfungen durch, bevor er den Seitenfehlerhandler aufruft, da die maximale Benutzerraumadresse 0x00007FFFFFFFFFF ist.

Zur Erinnerung, in der x32-Architektur wird die Adresse ohne "Validierung" an den Page Fault-Handler übergeben, der versucht, die Seite zu laden, die den Kernel dazu veranlasst, das Programm segfault zu senden, aber x64 kommt nicht so weit.

Testen Sie es, überschreiben Sie RIP mit 0 × 0000414141414141 und Sie werden sehen, dass der erwartete Wert in RIP platziert wird, da die Prechecks durch den Kernel übergeben und dann der Seitenfehlerhandler wie der x32-Fall aufgerufen wird (was natürlich dann bewirkt das Programm zum Absturz).

    
import os.boom.headshot 07.05.2013 01:29
quelle

Tags und Links