LD_PRELOAD с бинарником setuid
Я пытаюсь использовать LD_PRELOAD
для предварительной загрузки библиотеки с приложением, имеющим разрешения setuid. Сначала пробовал LD_PRELOAD
, и казалось, что он игнорируется с помощью бинарного файла setuid, хотя он работал, когда я пробовал его с другими, такими как ls
, dir
и т.д.
Из документации LD_PRELOAD:
LD_PRELOAD
A whitespace-separated list of additional, user-specified, ELF shared
libraries to be loaded before all others. This can be used to
selectively override functions in other shared libraries. For set-
user-ID/set-group-ID ELF binaries, only libraries in the standard
search directories that are also set-user-ID will be loaded.
Я попытался поместить библиотеку в /usr/lib
, /usr/local/lib
и /usr/lib64
с разрешениями setuid в соответствии с этой документацией выше, но она по-прежнему не работает. Если я не даю LD_PRELOAD
путь в случае, когда у меня есть библиотека в стандартном dirs с setuid, она не может найти библиотеку. Если я дам ему путь, он ничего не сделает.
Бинарный файл setuid - это двоичный файл с правами root, который запускается в оболочке пользователя без root. Есть предположения? Не уверен, что мне не хватает пути, переменной среды, или я неправильно понимаю документацию выше.
Изменить: разрешения по запросу:
Библиотека:
-rwsr-sr-x 1 root root 72580 2012-02-10 07:51
приложения:
-rwsr-xr-x 1 root root 137517601 2012-02-10
env | grep LD
LD_LIBRARY_PATH=/usr/lib (I added this manually myself, usually LD_LIBRARY_PATH is empty)
Ответы
Ответ 1
LD_PRELOAD не может использоваться с setuid. Это функция безопасности в Linux.
Для справки проверьте эту статью, в которой подробно описывается, как использовать LD_PRELOAD
для замены некоторых вызовов библиотеки с помощью специального кода, на примере malloc
.
Ответ 2
Если вы используете SELinux, это может быть связано с этим. Одним из вспомогательных векторов ELF, поддерживающих glibc, является AT_SECURE
. Этот конкретный параметр (который либо равен 0 по умолчанию, либо 1) указывает динамическому компоновщику ELF на отмену различных переменных среды, которые считаются потенциально опасными для вашей системы. Один из них - LD_PRELOAD
. Обычно такая санитария среды выполняется, когда вызывается приложение setuid/setgid (чтобы предотвратить очевидные уязвимости). SELinux также улучшил эту санитарию до того, как приложение инициирует переход домена в SELinux (скажем sysadm_t
- mozilla_t
через двоичную метку moz
или что-то еще); SELinux устанавливает флаг AT_SECURE
для загруженного приложения (в примере, mozilla/firefox).
Разрешение noatsecure
отключает деятельность по санитарии окружающей среды для конкретного перехода. Вы можете сделать это с помощью следующей инструкции allow (как это применимо в примере выше):
allow sysadm_t mozilla_t:process { noatsecure };
Ответ 3
В системе с glibc вы можете предварительно загрузить библиотеку другим поддерживаемым способом: добавив библиотеку в /etc/ld.so.preload
. Этот не страдает от ограничений LD_PRELOAD
.
В частности, таким образом я смог предварительно загрузить (бесполезно, просто чтобы продемонстрировать, что он работает) libgtk3-nocsd.so
в /usr/bin/passwd
, и, когда я запустил passwd ruslan
, библиотека появилась в /proc/<PID_OF_PASSWD>/maps
в то время как passwd
был в ожидании текущего ввода пароля.
Одним из недостатков является то, что вы не можете сделать это для каждого приложения, как вы могли бы с LD_PRELOAD
. Если вам это действительно нужно, возможно, вы могли бы изменить свою библиотеку, чтобы попытаться проверить, хочет ли она что-либо сделать, основываясь на том, какой путь к текущему двоичному файлу процесса (обнаружение этого, как описано здесь).
Ответ 4
Установите свой lib как таковой:
- местоположение:/lib или /usr/lib
- разрешений: root: root
- имеет setuid и setgid на
Убедитесь, что LD_PRELOAD экспортируется в вашу среду.
$ export LD_PRELOAD=/usr/lib/yourlib.so
$ env | grep LD_PRELOAD # verify
Затем запустите свою программу.