Почему адреса функций glibc не рандомизированы, когда включена функция ASLR?
Пытаясь понять ASLR, я построил эту простую программу:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("%p\n", &system);
return 0;
}
ALSR, кажется, включен:
$ cat /proc/sys/kernel/randomize_va_space
2
и я использовал GCC для компиляции программы:
$ gcc aslrtest.c
Каждый раз, когда я запускаю эту программу, она печатает один и тот же адрес (0x400450
).
Я ожидаю, что эта программа будет печатать разные адреса каждый раз, если glibc загружается по случайному адресу. Это удивляет меня, особенно если учесть, что предотвращение атак с возвратом в libc должно быть основной мотивацией для ASLR (в частности, system()
вызов).
Я ошибаюсь, ожидая, что адрес system()
должны быть рандомизированы? Или что-то не так с моей конфигурацией?
2 ответа
Любые ссылки на функцию из общей библиотеки, которая сделана из независимого от позиции объектного файла в основной программе, требуют записи PLT, через которую вызывающий абонент может выполнить вызов с помощью инструкции вызова, которая преобразуется в фиксированный адрес во время соединения, Это связано с тем, что объектный файл не был создан со специальным кодом (PIC), чтобы он мог поддерживать вызов функции по переменному адресу.
Всякий раз, когда такая запись PLT используется для функции в библиотеке, адрес этой записи PLT, а не исходный адрес функции, становится ее "официальным" адресом (как в вашем примере, где вы печатали адрес system
). Это необходимо, потому что адрес функции должен просматриваться одинаково во всех частях программы на Си; это не разрешено языком для адреса system
изменяться в зависимости от того, какая часть программы смотрит на него, поскольку это нарушит правило, согласно которому два указателя на одну и ту же функцию сравниваются как равные.
Если вы действительно хотите получить преимущества ASLR от атак, которые вызывают функцию с использованием известного фиксированного адреса, вам нужно собрать основную программу как PIE.
На самом деле printf("%p\n", &system);
не печатает адреса libc, это на самом деле печатает system@plt
адрес, который не рандомизирован ASLR
Но он действительно рандомизирует адрес libc, который в конечном итоге защищает от атаки ret2libc!!