23

Читая это, я обнаружил следующий эксплойт:

% cp /usr/bin/id ~
% chmod -x ~/id
% ls -al ~/id
-rw-r--r-- 1 edd edd 22020 2012-08-01 15:06 /home/edd/id
% ~/id
zsh: permission denied: /home/edd/id
% /lib/ld-linux.so.2 ~/id
uid=1001(edd) gid=1001(edd) groups=1001(edd),1002(wheel)

Этот фрагмент показывает, что мы можем тривиально обойти разрешения на выполнение файловой системы как обычный непривилегированный пользователь. Я запустил это на Ubuntu 12.04.

Хотя загрузчик Linux является общим объектом в соответствии с файлом (1), он также имеет точку входа, которая позволяет выполнять его напрямую. При выполнении таким способом загрузчик Linux действует как интерпретатор для двоичных файлов ELF.

Однако на моем компьютере с OpenBSD этот эксплойт не эффективен, поскольку вы не можете запускать загрузчик как программу. Страница руководства OpenBSD гласит: «ld.so сам по себе является общим объектом, который изначально загружается ядром».

Попробуйте это на Solaris 9, и вы получите ошибку. Я не уверен, что происходит в другом месте.

Поэтому мои вопросы:

  • Почему загрузчик Linux (при непосредственном выполнении) не проверяет атрибуты файловой системы перед интерпретацией двоичного файла ELF?
  • Зачем реализовывать механизм, который предназначен для запрета выполнения файлов, если он так тривиально обходится? Я что-то пропустил?

3 ответа3

32

Цель разрешения на execute не состоит в том, чтобы предотвратить выполнение в целом. (1) сообщать программам, какие файлы должны быть выполнены, и (2) предотвращать выполнение в качестве привилегированного пользователя, когда указан бит setuid (и т.д.).

Взлом линкера - это не столько эксплойт, сколько кажется. Вы можете выполнить любой неисполняемый файл, который у вас есть права на чтение, еще проще:

$ cp unexecutable_file ~/runme
$ chmod +x ~/runme
$ ~/runme

Смотрите это обсуждение на форуме Arch Linux.

В итоге:

Маркировка файлов, которые должны быть выполнены

Когда вы пишете скрипт оболочки, вы можете пометить его как исполняемый с помощью chmod +x . Это намекает вашей оболочке на то, что вы хотите, чтобы она была исполняемой (в противном случае оболочка знает, что это просто еще один простой текстовый файл). Оболочка может затем показать его на вкладке завершения при вводе ./ Tab .

Точно так же: something.d каталоги (например , init.d содержит запуск или скрипты управления , которые , как правило , выполняются автоматически демонами. Возможно, вы захотите поместить комментарий или файл README в каталог в виде простого текстового файла. Или вы можете временно отключить один из сценариев. Вы можете сделать это, очистив бит выполнения для этого конкретного файла. Это говорит демону пропустить его.

Предотвращение привилегированного исполнения

Бит setuid означает, что когда вы запускаете файл, он исполняется от имени указанного пользователя (например, root).

Сообщение на форуме объясняет это хорошо:

Вы хотите, чтобы исполняемый файл был установлен для некоторого пользователя, но вы хотите, чтобы только люди из определенной группы могли выполнять его как setuid. Они по-прежнему могут выполнять его путем копирования, но флаг setuid теряется, поэтому они будут выполнять его как сами, а не как пользователь, которому принадлежал исходный файл.

9

Если у вас есть доступ для чтения к файлу, вы всегда можете сделать его копию.

Если вы можете сделать личную копию, вы всегда можете пометить эту копию как исполняемую.

Это не объясняет поведение ld-linux, но указывает на то, что это может быть не очень полезной лазейкой в безопасности.

Если вы хотите более строгой безопасности, рассмотрите SELinux

1

Если посмотреть на вопрос немного иначе: как говорит Mechanical Snail, разрешение на выполнение файла не предназначено для предотвращения выполнения. Тем не менее, опция файловой системы "noexec" действительно предотвращает выполнение, и ее не так легко обойти (не поддерживается всеми файловыми системами, но, безусловно, наиболее популярными в Linux). Если администратор хочет запретить пользователям запускать собственные программы, он может указать параметр noexec в домашних каталогах и каталогах tmp, а также в любых других, где пользователи могут создавать файлы.

$ mount -o noexec /dev/sdd1 /test
$ cd /test
$ cp /usr/bin/id .
$ ./id
-bash: ./id: Permission denied

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

От http://linux.die.net/man/8/mount:

поехес

Не разрешайте прямое выполнение любых двоичных файлов в смонтированной файловой системе. (До недавнего времени можно было запускать двоичные файлы в любом случае с помощью команды, подобной /lib/ld*.so /mnt /binary. Этот трюк не работает начиная с Linux 2.4.25 / 2.6.0.)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .