Wenn Ihr Stack und Ihr Heap nicht ausführbar sind, wie kann Ihr Code dann ausgeführt werden?
Lesezeit: 4 Minuten
Adam Sch
Ich habe ein Buch über Pufferüberlauf gelesen, und es schlägt das nächste vor, mit dem man sich befassen sollte:
Den Stack (und Heap) nicht ausführbar zu machen, bietet ein hohes Maß an Schutz gegen viele Arten von Pufferüberlaufangriffen für bestehende Programme.
Aber ich verstehe nicht, wie wir das machen sollen – wo würde die Ausführung stattfinden, wenn nicht auf dem Heap oder auf dem Stack?
Jim Balter
Wenn ich Ihre Frage richtig verstehe, spricht keine der anderen Antworten sie an. Die Antwort ist, dass die Ausführung im Codeabschnitt erfolgt, der weder Stack noch Heap ist. In einem typischen ausgelagerten Speichersystem wird der Code aus einer Programmdatei (z. B. einer .exe-Datei in Windows) in ausführbare, aber schreibgeschützte Seiten geladen. Dem Prozess werden für Stack und Heap zusätzliche beschreibbare (und ausführbare) Seiten zugeordnet. Der Vorschlag hier ist, dass das Betriebssystem und die Hardware zusammenarbeiten sollten, um diese Seiten als beschreibbar, aber nicht ausführbar zu markieren (die Antwort von rgngl erklärt, wie das in Windows geht).
Gute Antwort. Ein kleiner Kommentar jedoch – (Blind) ROP besiegt tatsächlich ASLR ieeexplore.ieee.org/xpl/…
– Hack-R
15. März 2015 um 20:23 Uhr
Es gibt sogenannte „return-orientierte Programming“ (AKA ROP) Art von Exploits.
Der Angreifer findet heraus, wie er aus verschiedenen Teilen des Programms, das ausgenutzt wird, seinen bösartigen Code macht.
Er findet brauchbare Bytesequenzen (Anweisungen) vor den Byte(n) der Rückgabeanweisung, die nützliche Operationen an Registern oder im Speicher ausführen können, wie z. B. einen Wert an eine Stelle verschieben, Werte hinzufügen, Werte vergleichen usw gebaut aus.
Dann zwingt der Angreifer durch Ausnutzen eines Codefehlers das Programm, mit der Ausführung der Kette dieser Mikrosubroutinen zu beginnen, die all die böse Arbeit erledigen.
Also, jetzt wird aus gutem Code böser Code. Nichts wird auf dem Stack oder im Heap ausgeführt.
Bemerkenswert ist auch, dass bei CPUs, bei denen Befehle mehrere Bytes umfassen und variable Länge haben, sogar die unmittelbaren Befehlsoperanden (IOW, numerische Konstanten), die Teil von Befehlen sind, zu Code werden können, sodass die Chancen, brauchbare Bytesequenzen zu finden, dort höher sind als auf “einfacheren” CPUs.
Es ist auch oft möglich, bösartigen Code zu konstruieren, der den Speicherschutz ändert, und der Exploit wird nicht mehr durch den Code der vorhandenen Anwendung eingeschränkt.
Ganz konkretes Beispiel: Richten Sie die Absenderadresse ein, auf die verwiesen werden soll system und der nächste Schlitz auf dem Stapel (oder das erste Argumentregister auf Pass-by-Register-Bögen), um ein Zeiger auf die Zeichenfolge zu sein "/bin/sh".
Aber müssen Sie in diesem Fall nicht auch Zugriff auf die Konsole haben?
– Alexey Frunze
14. Juli 2012 um 8:03 Uhr
Nein. Ich bin davon ausgegangen, dass die Standardeinstellung des Prozesses ein Socket oder Terminal ist, mit dem Sie verbunden sind, aber wenn nicht, ändern Sie es einfach "/bin/sh" zu "/bin/sh 0<&n" wo n ist die Dateideskriptornummer des Server-Sockets für Ihre Verbindung.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
14. Juli 2012 um 8:16 Uhr
Oder Sie können es natürlich so ändern, dass es ohne interaktive Shell tut, was Sie wollen, z "echo 'toor::0:0::/:/bin/sh' >> /etc/passwd"
– R.. GitHub HÖR AUF, EIS ZU HELFEN
14. Juli 2012 um 8:37 Uhr
Diese Art von Schutz wird vom Betriebssystem bereitgestellt und kann nicht in der Anwendungsschicht erfolgen.
Sie können zu jeder anderen Stelle springen, die ein ausführbares Segment ist, und Ihren bösen Code ausführen …
Schließlich sind alle Daten auf jedem Speicher Bits und Bits können Anweisungen an die CPU sein, die ausgeführt werden sollen.
argentage
Sie können Ihren Überlauf verwenden, um die Rückkehradresse einer Funktion zu überschreiben, die mit Ihrem Code zu einer bekannten Adresse springen kann. Aber dann reagierten die Betriebssystemschreiber, indem sie den Adresscode randomisierten, der ausgeführt wird auf …
Wie laden Sie zunächst Ihren Code in ausführbare Speicherorte, wenn sich alles außer dem Programmcode im nicht ausführbaren Speicher befindet? Die Randomisierung des Adressraums allein verhindert keine ROP-basierten Exploits. Siehe meine Antwort.
– Alexey Frunze
14. Juli 2012 um 7:55 Uhr
13516900cookie-checkWenn Ihr Stack und Ihr Heap nicht ausführbar sind, wie kann Ihr Code dann ausgeführt werden?yes