Выполнить или пропустить код разделяемой библиотеки ld.so.preload в зависимости от условий - PullRequest
1 голос
/ 06 июля 2019

TL; DR: можно ли просто пропустить загрузку совместно используемой библиотеки, помещенной в ld.so.preload, или конкретного кода из нее при выполнении двоичного файла и RUID! = UID?

Hi.

Я пишу общий объект, библиотеку, которую загружаю через ld.so.preload, чтобы перехватить некоторые функции.Я хочу знать, могу ли я, основываясь на некоторых условиях, пропустить загрузку такой библиотеки или некоторых ее частей.

Контекст: я работаю с TOCTTOU (время проверки к времениИспользуйте) уязвимость, и я пишу библиотеку userland , которая будет загружаться через загрузчик linux ld.so.preload с функцией .Основная идея состоит в том, чтобы перехватить все функции, которые работают с файлами, выполнить некоторые проверки и затем вызвать исходную функцию, чтобы она была прозрачной для пользователей и других программ.

Теперь дело в том, что, поскольку я не хочу перегружать систему и хочу, чтобы моя библиотека имела как можно меньшее влияние, накладные расходы, я бы хотел выполнить ее, то есть перехватитьфункции, только когда RUID! = EUID.Это одна из предпосылок TOCTTOU на основе файлов, это происходит, когда злоумышленник имеет меньшие привилегии, чем уязвимое приложение.

Единственный способ, который мне приходит в голову на данный момент, заключается в том, чтобы окружить каждое объявление функции:

if(RUID == EUID){
   call original function;
} else {
   do my checkings;
   call original function;
}

РЕДАКТИРОВАТЬ: вышеуказанный код может быть заменен его эквивалентным, более коротким:

if(RUID != EUID){
   do my checkings;
}
call original function;

Но это на самом деле довольно ужасно, так как я перехватываю почти 50 функций плюс работаю с конструктором и деструктором __attribute, и это будет означать заполнение моего кода блоками if-else в каждой функции,

Имейте в виду, что ld.so.preload загружает перечисленные библиотеки перед любой другой библиотекой.

Я хотел бы знать, есть ли способ просто не загружать библиотеку на основе условия RUID != EUID или, альтернативно, загрузить библиотеку, но пропустить код перехвата.

1 Ответ

0 голосов
/ 07 июля 2019

Поскольку моя библиотека общесистемная, я не могу создать для нее никакой оболочки.

Вы хотите предварительно загрузить вашу библиотеку only в программы setuid или setgid.

Поскольку число таких программ в любой системе довольно мало и статически известно (вы можете найти их все с заданием cron каждый час), самое простое решение - создать оболочку для каждой такой программы.

Оболочка сама по себе может быть одной очень маленькой программой, которая имеет те же самые права setuid / setgid, что и у "целевой" программы, и выполняет эквивалент

/bin/env "LD_PRELOAD=..." target-prog args
...