Отслеживание исполняемого файла без разрешения на чтение

17

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

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

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>

Затем я пытаюсь выполнить исполняемый файл, для которого у меня нет прав на чтение:

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*

Присоединение к этому запущенному процессу не допускается:

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

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

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

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000

Это неожиданно для меня. Это ошибка безопасности, или это стандартная функция?

kasperd
источник
3
@ StéphaneChazelas: Дело в том, что он может отслеживать это, просто используя его в качестве аргумента для проведения. Основная причина, по-видимому, заключается в том, что при execveвызовах права на чтение исполняемого файла не проверяются снова, если процесс уже отслежен. Его вопрос заключается в том , является ли это ошибкой безопасности или обязательной функцией (если последняя, ​​я бы все еще считал это ошибкой безопасности, просто ошибкой безопасности спецификации).
celtschk
@celtschk, извините, я читаю вопрос слишком быстро.
Стефан Шазелас
1
EPERM, Кажется, исходит из get_dumpable()(используется также для проверки демпинг ли ядро разрешено, таким образом , «dumpable») вызывается из __ptrace_may_access()вызывается из ptrace_attach()в kernel/ptrace.c.
ниндзял
Когда программа работает, будет ли отладчику доступна достаточная информация для генерации исполняемого исполняемого файла, содержащего ее код, или загрузчик программы откажется от таких вещей, как исправления перемещений, которые понадобятся для того, чтобы программа действительно работала?
суперкат
@supercat Насколько я знаю, отладчик имеет доступ к одному шагу через весь выполняемый код пользовательского режима, включая код перемещения. При таком уровне доступа не должно быть слишком сложно воспроизвести работающий исполняемый файл.
Касперд

Ответы:

7

Это не ответ, а скорее набор ссылок и мыслей на случай, если кто-то еще захочет учиться. Потому что это довольно интересная вещь.

Соответствующий ответ по Unix и Linux, в котором упоминается, что он (или был, не может тестировать с ванильным ядром прямо сейчас) можно вывести таким образом двоичные файлы только для чтения.

Grsecurity пытался исправить эту опцию конфигурации и сам патч (хотя с тех пор он мог измениться)

Этот коммит действительно создает впечатление, что разработчики ядра действительно заботятся только о создании дампов suid.

Но на самом деле из этой строки я бы предположил, что ядро ​​хочет предотвратить сброс нечитаемых двоичных данных о состоянии SUID. И эта строка говорит о том, что двоичные файлы, которые не являются дампами, не должны отслеживаться.

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

Редактировать: еще один вывод, касающийся отладчика, упомянутый в комментариях к оригинальному сообщению - из быстрой проверки (опять же) мне кажется, что GDB использует отслеживаемые двоичные файлы и /proc/<pid>/mem. Как только исполняемый двоичный файл не читается, cat /proc/<pid>/memвозвращается EPERM. Если двоичный файл доступен для чтения, он возвращается EIO. (Протестировано это на Ubuntu 14.10, которая запускает несколько исправлений безопасности, так что это может отличаться от ванильного ядра. Опять же, у меня нет ванильного ядра, работающего где-либо под рукой :()

Лиса
источник