GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was setzt fs:[0x28] (Stack Canary)?

Es ist einfach, diese Initialisierung zu verfolgen, wie bei (fast) jedem Prozess strace zeigt einen sehr verdächtigen Systemaufruf ganz am Anfang des Prozesslaufs:

arch_prctl(ARCH_SET_FS, 0x7fc189ed0740) = 0

Das ist was man 2 arch_prctl sagt:

   ARCH_SET_FS
          Set the 64-bit base for the FS register to addr.

Yay, sieht so aus, als ob wir das brauchen. Zu finden, wer arch_prctl anruft , suchen wir nach einem Backtrace:

(gdb) catch syscall arch_prctl
Catchpoint 1 (syscall 'arch_prctl' [158])
(gdb) r
Starting program: <program path>

Catchpoint 1 (call to syscall arch_prctl), 0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
#1  0x00007ffff7ddd3e3 in dl_main () from /lib64/ld-linux-x86-64.so.2
#2  0x00007ffff7df04c0 in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7dda028 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dd8fb8 in _start () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffecef in ?? ()
#7  0x0000000000000000 in ?? ()

Die FS-Segmentbasis wird also durch ld-linux festgelegt , das ein Teil von glibc ist , während des Programmladens (wenn das Programm statisch gelinkt ist, wird dieser Code in die Binärdatei eingebettet). Hier passiert alles.

Während des Starts initialisiert der Loader TLS. Dies umfasst die Speicherzuweisung und das Festlegen des FS-Basiswerts, um auf den TLS-Anfang zu verweisen. Dies geschieht über arch_prctl Systemaufruf. Nach der TLS-Initialisierung security_init Funktion aufgerufen, die den Wert des Stackguards generiert und an die Speicherstelle schreibt, die fs:[0x28] zeigt auf:

  • Stack Guard-Wert-Initialisierung
  • Stapelschutzwert schreiben, detaillierter

Und 0x28 ist der Offset von stack_guard Feld in der Struktur, das am Anfang von TLS steht.


Was Sie sehen, wird (in GCC) Stack Smashing Protector (SSP) genannt, eine Art Pufferüberlaufschutz, der vom Compiler generiert wird. Der Wert ist eine vom Programm beim Start generierte Zufallszahl und wird, wie im Wikipedia-Artikel erwähnt, im Thread Local Storage (TLS) abgelegt. Andere Compiler verwenden möglicherweise andere Strategien, um diese Art von Schutz zu implementieren.

Warum den Wert in TLS speichern? Da sich der Wert dort befindet, ist seine Adresse für die CS-, DS- und SS-Register nicht zugänglich, was das Erraten des gespeicherten Werts sehr schwierig macht, wenn Sie versuchen, den Stack durch bösartigen Code zu ändern.


Linux
  1. Wie groß darf der Wert einer Linux-Umgebungsvariablen maximal sein?

  2. Was bedeutet Symbolwert vom nm-Befehl?

  3. Was macht ulimit -s unlimited?

  4. Wert des Stapelzeigers ausgeben

  5. Welchen Wert hat JAVA_HOME für CentOS?

Was ist LAMP Stack?

Was ist SSH?

Was ist SFTP?

Was bedeutet null in Linux und Computing

Was kommt in GNOME 42?

Was ist digitaler Analphabetismus?