Что устанавливает fs: [0x28] (stack canary)?

Ваше использование parallel неверно.

Каким-то образом 4-й запуск будет выполнен

curl http://127.0.0.1:81/a.php curl http://127.0.0.1:81/a.php

Я не совсем понимаю синтаксис, но это сработает:

yes | head -n4 | parallel ./a.sh

Пояснение из man-страницы

Задание может быть одной командой или небольшим скриптом, который должен быть запущен для каждой из строк во входных данных.

11
06.07.2018, 04:32
2 ответа

Эту инициализацию легко отследить, так как для (почти )каждый процесс straceпоказывает очень подозрительный системный вызов в самом начале запуска процесса:

arch_prctl(ARCH_SET_FS, 0x7fc189ed0740) = 0

Вот что man 2 arch_prctlговорит:

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

Ура, похоже, это то, что нам нужно. Чтобы узнать, кто звонит arch_prctl, поищем бэктрек:

(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 ?? ()

Итак, база сегмента ФС задается ld-linux, входящей в состав glibc, при загрузке программы (, если программа статически компонуется, этот код встраивается в бинарник ). Здесь все происходит.

Во время запуска загрузчик инициализирует TLS . Это включает в себя выделение памяти и настройку базового значения FS, чтобы оно указывало на начало TLS. Это делается с помощью системного вызоваarch_prctl. После инициализации TLSsecurity_initвызывается функция , которая генерирует значение защиты стека и записывает его в ячейку памяти, которая fs:[0x28]указывает на:

А 0x28— это смещение поля stack_guardв структуре, расположенной в начале TLS.

25
27.01.2020, 19:57

То, что вы видите, называется (в GCC )Stack Smashing Protector (SSP ), который является формой защиты от переполнения буфера , созданной компилятор. Значение представляет собой случайное число, сгенерированное программой при запуске и, как упоминается в статье в Википедии, помещается в локальное хранилище потоков (TLS). Другие компиляторы могут использовать другие стратегии для реализации этого типа защиты.

Зачем хранить значение в TLS? Поскольку значение находится там, его адрес недоступен для регистров CS, DS и SS, что очень затрудняет угадывание сохраненного значения, если вы пытаетесь изменить стек с помощью вредоносного кода.

6
27.01.2020, 19:57

Теги

Похожие вопросы