2016-06-30 14 views
3

In der Art, Binärdateien zu verstehen (virtuelles Speicherlayout, Ausführung ... etc), habe ich einen C Code geschrieben, der eine globale Zeichenfolge deklariert, die Bytes eines ausführbaren Codes enthält, dann überschrieb ich die Rücksprungadresse von der main() Funktion zu diesem ausführbaren Code mit einem einfachen Trick durch die Deklaration eines Zeigers (PTR) in main(), die eine lokale Speicherbereich auf dem Stapel 2 WORDS weit entfernt von der Rücksendeadresse von der main() reserviert ist, so dass ich nur die Adresse der Geben Sie die Adresse an diesen Zeiger (PTR=(int*)&PTR+2) zurück und überschreiben Sie dann den Inhalt dieser Adresse mit der Adresse des ausführbaren Codes (der statischen Zeichenfolge).

Jetzt ist das Dilemma, dass, wenn ich kompiliere und ich ausführen, erhalte ich einen Segmentierungsfehler. Der ausführbare Code hat keinen Speicher input/output (es ist nur eine Reihe von NOPs).

Mit GDB habe ich sichergestellt, dass der Prozess perfekt funktioniert: die Absenderadresse wird geändert, um die Adresse der Zeichenfolge zu sein, aber die Rückkehr passiert nie.

Alles was ich weiß ist, dass die ausführbaren Code auf Seiten im virtuellen Speicher Thar sind RW markiert abgebildet wird (.data & .bss Segmente) so vielleicht gibt es keine Möglichkeit, eine solche Ausführung von Code zu tun, wenn Code in einer executable Speicherbereich injiziert wird (Seiten das sind markiert RE). Das ist meine Theorie über das Thema, ich lade Sie ein, mehr Details zu geben.Kann ich Code ausführen, der sich im Datensegment (ELF-Binärdatei) befindet?

char code[]="\x90\x90\x90\x90\x90\x90\x90\x90"; //a static string contains executable code 

int main() 
{ 
int *return_address; //Pointer to the return address - uninitialized 
return_address = (int *)&return_address + 2; //Initializing the return address - according to stack layout 
(*return_address) = (int)code; //Overwriting the return address with the code's address 
} 
+0

Sie möchten mprotect sycall mit PROT_EXEC Flagge nennen hinzugefügt ... Es gibt keine x-Berechtigung für Datenseite auf vielen Architekturen (x86 auch), überprüfen Sie die Speicherkarten in linux durch Lesen von/proc/$ PID/maps Datei, während die Anwendung läuft (gestoppt in gdb), wobei $ PID die PID des Zielprozesses ist. Sie sehen, dass das Daten/BSS-Segment mit rw-permission geladen ist. – osgx

+0

@osgx Es ist genau dasselbe, was ich vermutete, erlauben ältere Linux-Kernel (wie vor 2007) diese Art der Ausführung? –

+0

hast du? Sie können die Kartendatei auf einem älteren Kernel überprüfen. Es gibt eine Wiki-Seite zur Technologie: https://en.wikipedia.org/wiki/Executable_space_protection und "NX bit"/"XD bit" -Technologie kann in CPU und Kernel benötigt werden, um ... 'Executable' -Bit zu page- hinzuzufügen. Level-Übersetzungen von Hardware (OS kann 3-Bit-rwx-Berechtigungen haben, aber Hardware hatte kein x-Bit). PAE sollte auch im 32-Bit-x86-Modus aktiviert sein. (detaillierte Informationen gibt es hier https://en.wikipedia.org/wiki/NX_bit) – osgx

Antwort

2

i erhalten einen Segmentation Fault.

Es ist Hardware-Steuerung der Datenausführungsverhinderung (https://en.wikipedia.org/wiki/Executable_space_protection#Linux) - Sie können nicht nur auf Datenseite springen, wenn es kein ‚x‘ (Ausführen) hat Bit in Seitentabellen festgelegt. Speicherzuordnungen mit allen Bits sind in //proc/$pid/smaps Dateien als 'rwx' für schreibbaren Code, 'rw-' für Daten ohne Ausführung, 'r--' für schreibgeschützte Daten, 'r-x' für normalen Code aufgelistet.

Wenn Sie Daten ausführen möchten, sollten Sie mprotect syscall mit PROT_EXEC Flag auf den Abschnitt Ihrer Daten aufrufen, die Code sein möchte.

In x86 Welt wurde dies vollständig implementiert als "NX bit"/"XD bit" feature in Pentium 4 (Prescott) und neuer (Core, Core2, Core i *, Kern m)/in Athlon 64/Opteron und neuer. Wenn das Betriebssystem im 32-Bit-Modus arbeitet, muss es PAE aktivieren, um dieses Bit in der Seitentabelle zu haben. Im x86_64-Modus (64-Bit) wird immer NX/XD-Bit unterstützt.

Erste Varianten der Unterstützung um 2.004 auf Linux wurden hinzugefügt: http://linuxgazette.net/107/pramode.html

2007 Sie veraltet Hardware hat, alten Kernel oder 32-Bit-Modus-Kernel ohne PAE.

Info über NX/XD Bit: https://en.wikipedia.org/wiki/NX_bit

Manchmal 'rwx' -Modus verboten werden können, überprüfen https://en.wikipedia.org/wiki/W^X.

Für Pre-NX-Systeme gab es Lösungen, die auf Segmentregistern von x86 basierten, um einen Teil des Speicherplatzes teilweise von der Ausführung auszuschließen.

kann ich das obige Programm ausführen, ohne einen Segmentierungsfehler zu haben?

Sie können:

  • die Datenseite ausführbar zu machen, indem mprotect auf sie mit PROT_READ|PROT_EXEC
  • machen das Datensegment von elf Datei markiert als ausführbare Aufruf (müssen tief in ld Skripte hacken - default ist in ld --verbose)
  • verschieben Sie den Shellcode auf Stapel und machen den Stapel ausführbar mit execstack
  • Shellcode in Textdaten der Elf-Datei verschieben
  • versuchen, nx/xd-Bit im Kernel zu deaktivieren (schwer; Neukompilierung ist möglicherweise erforderlich)
  • 32-Bit-Betriebssystem (Kernel) ohne aktivierte PAE-Option (Option für die Buildzeit) verwenden.
  • verwenden ältere CPU ohne NX/XD
+0

PS: jemand kann (aber sollte nicht, laut Gesetz) * spray * verwenden, um eigenen Code in remote-Prozess in ausführbaren Seiten (https: //en.wikipedia .org/wiki/JIT_spraying). Funktioniert nicht mit RISC und Gogol NaCl (sie haben keine variable Längenanweisungscodierung oder springen in die Mitte des Befehls) und auf modernem JIT mit Anti-Spray. – osgx

+0

ubuntus-Seite von nx/xd: https://wiki.ubuntu.com/Security/Features#nx "Die 64bit und 32bit-Server und -generic-pae-Kernel sind mit PAE-Adressierung kompiliert. Ab Ubuntu 9.10 ist dieser Schutz teilweise emuliert für Prozessoren ohne NX, wenn sie auf einem 32-Bit-Kernel laufen. Ab Ubuntu 11.04 werden BIOS NX-Einstellungen vom Kernel ignoriert. " Und Farbmatrix. – osgx