[GO] Machen Sie Perl Segfo in einer Zeile

Einführung

Weil es heutzutage sehr beliebt zu sein scheint.

Also habe ich es mit Perl versucht. Die Umgebung ist ein geeignetes x86_64 Linux.

wie kann ich?

Sie sehen, es ist so einfach!

image.png

** Nein, nicht das **

nimm das Herz.

shell-session:WSL/Ubuntu18/Perl5.26.Laufen Sie auf 1


$ perl -e 'syscall 10,$m-=4096,4096,0 while$m||=1<<47'
Segmentation fault (core dumped)

Wenn ich es mit einem Shell Art Bot versuche, sieht es so aus. Es wurde ein glücklicher Segfo hier.

image.png

Was machst du?

Wenn Sie dies etwas einfacher zu sehen machen, sieht es so aus.

Frühere Geschichte


require 'syscall.ph';
$m=0x800000000000;
while ( 1 ) {
  $m-=0x1000;
  syscall &SYS_mprotect,$m,0x1000,0;
}

Mit anderen Worten, der zuvor erwähnte Einzeiler bestand darin, den mprotect-Systemaufruf endlos ab einem bestimmten Adresswert auszugeben.

Dies hat zur Folge, dass das Schutzattribut des angegebenen Speicherbereichs geändert wird. Da 0 im dritten Argument "PROT_NONE" entspricht, gehen alle Berechtigungen zum Lesen, Schreiben und Ausführen von Programmen für diesen Speicherbereich verloren. Daher fliegt das SEGV, sobald Sie auf den Speicher zugreifen.

Beachten Sie, dass 0x800000000000, die Startadresse, bestimmt wird, da sich das Ende des Speichers des 64-Bit-Prozesses (Heap, Stack, vdso) ungefähr unmittelbar davor befindet.

Überprüfen Sie die Speicherzuordnung


$ perl -e 'system "cat","/proc/$$/maps"'
7f11879f0000-7f11879f9000 r-xp 00000000 00:00 121160             /lib/x86_64-linux-gnu/libcrypt-2.27.so
7f11879f9000-7f11879fa000 ---p 00009000 00:00 121160             /lib/x86_64-linux-gnu/libcrypt-2.27.so
7f11879fa000-7f1187bf8000 ---p 0000000a 00:00 121160             /lib/x86_64-linux-gnu/libcrypt-2.27.so
(Abkürzung)
7f1188c00000-7f1188df7000 r-xp 00000000 00:00 135847             /usr/bin/perl
7f1188df7000-7f1188df8000 r-xp 001f7000 00:00 135847             /usr/bin/perl
7f1188ff8000-7f1188ffe000 r--p 001f8000 00:00 135847             /usr/bin/perl
7f1188ffe000-7f1189000000 rw-p 001fe000 00:00 135847             /usr/bin/perl
7fffbe41b000-7fffbe45d000 rw-p 00000000 00:00 0                  [heap]
7fffc523e000-7fffc5a3e000 rw-p 00000000 00:00 0                  [stack]
7fffc6124000-7fffc6125000 r-xp 00000000 00:00 0                  [vdso]

Gefährlicher

Ich suchte nach einer Möglichkeit, es interessanter oder kürzer zu machen, und fand eine schlechte.

python


$ perl -e 'unpack p,1x8'
Segmentation fault (core dumped)

Ich fragte mich, was es war, also sah ich nach.

Erstens ist "entpacken" eine integrierte Funktion, die mit "packen" gekoppelt ist, und kurz gesagt, sie ist für das Serialisieren ("Packen") und Deserialisieren ("Entpacken") von Daten verantwortlich. Dies wird verwendet, um einzelne bis mehrere Daten zu einer Zeichenfolge zu kombinieren, damit sie übertragen werden können, und umgekehrt, um Daten aus der Zeichenfolge abzurufen.

Wobei "p" die bloße Spezifikation der Zeichenfolge "p" ist. Dies stellt die Art der Daten dar, die zusammengefasst / zusammengefasst werden sollen, jedoch gemäß dem Handbuch:

Aus Pack-Handbuch:

p Ein Zeiger auf eine Zeichenfolge, die mit einem Nullzeichen endet.

… ** Zeiger ?? Hast du "Zeiger" gesagt !? **

Was ist die versteckte Funktion für die Verwendung eines bloßen Zeigers an einem solchen Ort? ** Wie erwartet Perl **. Wo benutzt du es?

nimm das Herz. Bei Verwendung mit pack scheint der interne Adresswert, der die Zeichenfolgendaten enthält, serialisiert und in eine Zeichenfolge konvertiert zu werden. Wenn Sie es im Debugger wie folgt betrachten, passt es perfekt zusammen.

Mit gdb in Erinnerung bleiben


$ perl -e '$x="angel_p_57";print pack "p",$x;close STDOUT;sleep 1200'|od -tx8 & sleep 1
[2] 1067
0000000 00007fffbc94a320
0000010
$ ps -fC perl
UID        PID  PPID  C STIME TTY          TIME CMD
angel     1066    12  0 23:53 pts/0    00:00:00 perl -e $x="angel_p_57";print pack "p",$x;close STDOUT;
$ sudo gdb perl
…(Abkürzung)…
(gdb) attach 1066
…(Abkürzung)…
(gdb) x/s 0x00007fffbc94a320
0x7fffbc94a320: "angel_p_57"

Im Gegenteil, wenn es in "entpacken" verwendet wird, bedeutet dies, dass ** die Zeichenfolge deserialisiert und als Adresswert interpretiert wird ** und ein Duplikat der dortigen Zeichenfolge generiert wird. Wenn Sie daher eine zufällige Zeichenfolge angeben, handelt es sich sofort um einen unzulässigen Speicherzugriff. Wahrscheinlich benötigt x86_64-Linux Perl jedoch 8 Zeichen, um den Adresswert zu deserialisieren. Daher verwende ich die Zeichenfolge "11111111" in "1x8". (X ist ein String-Wiederholungsoperator)

Nein, ich wusste nicht, dass ** pack eine solche Funktion hat, und ich konnte nicht anders als zu denken, dass Perl immer noch tief ist **.

abschließend

Überraschenderweise hatte ich Mühe, nicht autorisierten Speicherzugriff zu erstellen, und dies war die Methode, die ich mir ausgedacht hatte. ** Der Speicherbereich selbst sollte illegal behandelt werden **. Danach lernte ich das Auspacken, das sich anfühlte, als würde man die Tiefen von Perl berühren. Wenn es einen anderen interessanten Weg gibt, bitte.

Darüber hinaus ist es eine Liste von Artikeln, die an Segfo gerichtet sind.

Recommended Posts

Machen Sie Perl Segfo in einer Zeile
Segfo Python in einer Zeile
Lassen Sie Python in einer Zeile segfo, ohne ctypes zu verwenden
Mach ein Janken-Spiel in einer Zeile (Python)
Lassen Sie einen Papagei LINE Bot mit AWS Cloud9 zurückgeben
Machen Sie einen LINE BOT
Fizzbuzz in Python (in einer Zeile)
Stellen Sie iPython unter OSGeo4W zur Verfügung
Stellen Sie Cython unter Windows zur Verfügung.
Machen Sie einen LINE BOT (Chat)
Segfo Python in 2 Zeilen
Online-Übertragung mit Python