Как обнаружить, если KASLR включен или отключен во времени выполнения?
Проверьте командную строку вашего ядра. (пример на debian 8)
$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-`uname -r` root=/dev/mapper/`hostname`-root ro quiet
kASLR доступен начиная с Ubuntu 14.10, но по умолчанию он не включен. Укажите параметр «kaslr» в командной строке ядра, чтобы использовать kASLR.
Примечание: Включение kASLR отключит возможность перехода в режим гибернации.
blockquote>
KASLR (Рандомизация Расположения Адресного пространства Ядра) по большей части удерживается от использования и заменяется КАЙЗЕРОМ (Изоляция Адреса ядра, чтобы удалить каналы Стороны Эффективно), который в свою очередь удерживается от использования и заменяется KPTI (Изоляция Таблицы страниц Ядра). Эти три "K-шага" являются всей частью "Укрепления Ядра".
Однако отвечать на вопрос:
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.14.27-041427-generic root=UUID=f3f8e7bc-b337-4194-88b8-3a513f6be55b ro quiet splash loglevel=0 vga=current udev.log-priority=3 fastboot kaslr acpiphp.disable=1 crashkernel=384M-2G:128M,2G-:256M vt.handoff=7
I was' Я не удовлетворен предыдущими ответами, поскольку они действительно не доходят до сути проверки того, что такое KASLR, особенно встроенных или пользовательских ядер, которые не реализуют тот же интерфейс командной строки ядра (например, ARM64 требует, чтобы выбранное дерево устройств узел с именем kaslr-seed должен присутствовать при загрузке ядра. Обычно это реализуется загрузчиком с использованием безопасного генератора случайных чисел).
Во время выполнения я знаю две вещи, которые вы можете проверить:
/proc/kallsyms
, чтобы увидеть адреса символов в адресном пространстве виртуальной памяти. lsmod
, чтобы увидеть адреса модулей ядра в адресном пространстве виртуальной памяти. Примечание. На некоторых машинах lsmod
может не отображать адреса. В этом случае попробуйте использовать cat /proc/modules
как root. Если не используется root, все адреса могут быть нулевыми (очищено из соображений безопасности). ~~Спасибо пользователю @crass за комментарий!~~Проверки 1 и 2 аналогичны, но в зависимости от того, что доступно в вашей системе, вам может понадобиться использовать тот или иной вариант.
Для этого просто посмотрите на первые несколько строк /proc/kallsyms
:
root@device:~# head -n 3 /proc/kallsyms
ffffff8008080000 t _head
ffffff8008080000 T _text
ffffff8008080800 T do_undefinstr
Обратите внимание, что адрес, например,, _head
равно ffff ff80 0808 0000
.
Теперь перезагрузите компьютер и проверьте еще раз.
root@device:~# head -n 3 /proc/kallsyms
ffffff9fc8c80000 t _head
ffffff9fc8c80000 T _text
ffffff9fc8c80800 T do_undefinstr
Обратите внимание, что адрес, например, _head
теперь ffff ff9f c8c8 0000
.
Сравните байты высокого уровня и обнаружите, что ffffff80080 != 0xffffff9fc8c
, поэтому адреса меняются при перезагрузке => KASLR включен.
Аналогичен методу /proc/kallsyms
выше: проверьте lsmod, перезагрузитесь, снова проверьте lsmod и сравните адреса.
root@device:~# lsmod
iptable_filter 16384 0 - Live 0xffffffa1c49b9000
ip_tables 28672 1 iptable_filter, Live 0xffffffa1c49ad000
Обратите внимание, что адрес, например, для iptable_filter
— ffff ffa1 c49b 9000
.
Теперь перезагрузите компьютер и проверьте еще раз.
root@device:~# lsmod
iptable_filter 16384 0 - Live 0xffffff2100716000
ip_tables 28672 1 iptable_filter, Live 0xffffff210070a000
Обратите внимание, что адрес, например, iptable_filter
теперь ffff ff21 0071 6000
.
Сравните байты высокого уровня и обнаружите, что ffffff2100716 != 0xffffffa1c49b9
, поэтому адреса меняются при перезагрузке => KASLR включен.
Эти тесты можно выполнять многократно, чтобы определить качество случайности. Насколько отличаются адреса при перезагрузке? Есть ли очевидные закономерности? Преимущество безопасности KASLR пропорционально качеству случайности или энтропии.
Ссылки:
Отладка ядер Linux с помощью KASL
База данных драйверов ядра Linux для RANDOMIZE_BASE
Мне нравится ответ @bhass1 здесь, однако я не хочу перезагружать свой компьютер, чтобы выполнить тест. Таким образом, вы можете выполнить практически тот же тест, но на виртуальной машине, если она вам доступна. Я использую qemu
с опциями -kernel
и -initrd
, и вот как я это делаю:
Во-первых, я проверяю, какое у вас ядро. re работает, посмотрев на cat /proc/cmdline
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-5.2.0-42-generic root=/dev/sda1 ro vt.handoff=7
Поэтому я использую kernel vmlinuz-5.2.0-42-generic
.
Нам нужно запустить ядро с помощью initrd, чтобы иметь минимальное окружение для проверки адресов. Я использую initrd, соответствующий моему ядру, чтобы сделать симуляцию более реальной, но на самом деле это не имеет значения. Я также использую командную строку работающего ядра, чтобы максимально приблизить симуляцию к работающему ядру, и добавляю break=top
в командную строку ядра, чтобы как можно быстрее перейти к оболочке.
Далее я запускаю виртуальную машину qemu
:
sudo qemu-system-x86_64 -m 1024 -kernel /boot/vmlinuz-5.2.0-42-generic \
-append "$(cat /proc/cmdline) break=top" -initrd /boot/initrd.img-5.2.0-42-generic
Когда я попадаю в оболочку, я получаю адреса загруженных модулей:
(initramfs) cat /proc/modules
usbhid 57344 0 - Live 0xffffffffc0269000
hid 131072 1 usbhid, Live 0xffffffffc0248000
Теперь я проверю работающую систему, чтобы узнать, что за модуль адрес для одного из модулей, чтобы увидеть, отличается ли он:
sudo grep hid /proc/modules
hid_generic 16384 0 - Live 0xffffffffc20ac000
usbhid 57344 0 - Live 0xffffffffc1a09000
hid 131072 2 hid_generic,usbhid, Live 0xffffffffc1c96000
Итак, мы можем видеть здесь, что адреса для модуля hid различны (рабочий: 0xffffffffc1c96000
и виртуальный: 0xffffffffc0248000
). Итак, мое ядро работает с kASLR, , хотя его нет в командной строке ядра (теперь оно включено по умолчанию в некоторых дистрибутивах).
Вы можете снова проверить адрес модуля в другом экземпляре qemu
и убедиться, что адрес модуля меняется при каждом запуске qemu. Кроме того, вы можете добавить nokaslr
в командную строку ядра (параметр -append
qemu
) и запустить qemu
пару раз, чтобы убедиться, что адрес модуля не изменить.