Безопасный доступ к файлам в каталоге, указанном в переменной среды? - PullRequest
3 голосов
/ 13 октября 2008

Может ли кто-нибудь указать на некоторый код, который касается безопасности доступа к файлам по пути, указанному (частично) переменной среды, особенно для Unix и его вариантов, но решения Windows также представляют интерес?

Это большой длинный вопрос - я не уверен, насколько хорошо он соответствует парадигме SO.

Рассмотрим этот сценарий:

Справочная информация:

  • Программный пакет PQR можно установить в месте, выбранном пользователями.
  • Переменная среды $ PQRHOME используется для идентификации каталога установки.
  • По умолчанию все программы и файлы в $ PQRHOME принадлежат специальной группе pqrgrp.
  • Аналогично, все программы и файлы в $ PQRHOME принадлежат либо специальному пользователю, pqrusr, либо пользователю root (и это корневые программы SUID).
  • Несколько программ SUID pqrusr; еще несколько программ SGID pqrgrp.
  • Большинство каталогов принадлежат pqrusr и принадлежат pqrgrp; некоторые могут принадлежать к другим группам, и члены этих групп получают дополнительные привилегии с помощью программного обеспечения.
  • Многие из привилегированных исполняемых файлов должны запускаться людьми, которые не являются членами pqrgrp; программы должны подтвердить, что пользователю разрешено запускать его по тайным правилам, которые непосредственно не касаются этого вопроса.
  • После запуска некоторые привилегированные программы должны сохранять свои повышенные привилегии, потому что они являются долго работающими демонами, которые могут действовать от имени многих пользователей в течение своей жизни.
  • Программам не разрешено менять каталог на $ PQRHOME по ряду загадочных причин.

Текущий контроль:

  • В настоящее время программы проверяют, что $ PQRHOME и каталоги ключей в нем «безопасны» (принадлежат pqrusr, принадлежат pqrgrp, не имеют открытого доступа для записи).
  • После этого программы получают доступ к файлам в $ PQRHOME через полное значение переменной среды.
  • В частности, G11N и L10N достигаются путем доступа к файлам в «безопасных» каталогах и чтения строк формата для printf () и т. Д. Из файлов в этих каталогах, используя полный путь, полученный из $ PQRHOME, плюс известную подпрограмму -структура (например, $ PQRHOME / g11n / en_us / messages.l10n).

Предположим, что значение $ PQRHOME «как установлено» равно /opt/pqr.

Известная атака:

  • Атакующий устанавливает PQRHOME = / home / атакующий / pqr.
  • На самом деле это символическая ссылка на / opt / pqr, поэтому, когда одна из программ PQR, называющая ее pqr-жертва, проверяет каталог, она имеет правильные разрешения.
  • Сразу после успешного завершения проверки безопасности злоумышленник изменяет символическую ссылку, чтобы она указала на / home / attacker / bogus-pqr, который явно находится под контролем злоумышленника.
  • Ужасные вещи случаются, когда жертва pqr теперь получает доступ к файлу в предположительно безопасном каталоге.

Учитывая, что PQR в настоящее время ведет себя так, как описано, и представляет собой большой пакет (несколько миллионов строк кода, разработанный за более чем десятилетие для различных стандартов кодирования, которые в любом случае часто игнорировались), какие методы Вы бы использовали, чтобы исправить проблему?

Известные опции включают в себя:

  1. Измените все вызовы форматирования, чтобы использовать функцию, которая проверяет фактические аргументы на соответствие строкам формата, с дополнительным аргументом, указывающим фактические типы, передаваемые в функцию. (Это сложно и потенциально подвержено ошибкам из-за большого количества операций форматирования, которые должны быть изменены - но если функция проверки сама по себе исправна, работает хорошо.)
  2. Установите прямой путь к PQRHOME и проверьте его на предмет безопасности (подробности ниже), отказываясь запускаться, если он небезопасен, и после этого используйте прямой путь, а не значение $ PQRHOME (если они различаются). (Это требует, чтобы все файловые операции, использующие $ PQRHOME, использовали не значение из getenv (), а сопоставленный путь. Например, для этого потребуется программное обеспечение, чтобы установить, что / home / attacker / pqr является символической ссылкой на / opt / pqr, что путь к / opt / pqr является безопасным, и после этого, всякий раз, когда на файл ссылаются как на $ PQRHOME / some / thing, используемое имя будет / opt / pqr / some / thing, а не / home / attacker / pqr / some / вещь. Это большая база кода - исправить нетривиально.)
  3. Убедитесь, что все каталоги в $ PQRHOME, даже отслеживание по символическим ссылкам, безопасны (подробности ниже, опять же), и программное обеспечение отказывается запускаться, если что-либо небезопасно.
  4. Жесткий код пути к месту установки программного обеспечения. (Это не будет работать PQR; это делает тестирование адом, если не что иное. Для пользователей это означает, что у них может быть установлена ​​только одна версия, а обновления и т. Д. Требуют параллельного запуска. Это не работает для PQR.)

Предлагаемые критерии для безопасных путей:

  • Для каждого каталога владелец должен быть доверенным. ( Обоснование: владелец может изменять разрешения в любое время, поэтому необходимо, чтобы владелец не доверял случайным изменениям, которые нарушают безопасность программного обеспечения. )
  • Для каждого каталога у группы либо не должно быть прав записи (поэтому члены группы не могут изменять содержимое каталога), либо группа должна быть доверенной. ( Обоснование: если члены группы могут изменять каталог, то они могут нарушить безопасность программного обеспечения, поэтому либо они не могут изменить его, либо им следует доверять, чтобы не изменять его. )
  • Для каждого каталога «другие» не должны иметь никаких прав записи в каталог.
  • По умолчанию пользователям root, bin, sys и pqrusr можно доверять (там, где существуют bin и sys).
  • По умолчанию группе с GID = 0 (иначе называемой root, wheel или system), bin, sys и pqrgrp можно доверять. Кроме того, группе, которой принадлежит корневой каталог (которая называется MacOS X с именем администратора), можно доверять.

Функция POSIX realpath() предоставляет картографический сервис, который будет сопоставлять / home / attacker / pqr с / opt / pqr; он не выполняет проверку безопасности, но это нужно делать только по разрешенному пути.

Итак, есть ли какое-то известное программное обеспечение, которое проходит через неопределенно связанные движения, чтобы обеспечить его безопасность? Это чрезмерно параноидально? (Если так, почему - и вы действительно уверены?)

Отредактировано:

Спасибо за различные комментарии.

@S.Lott: атака (обрисованная в общих чертах в вопросе) означает, что по крайней мере одна корневая программа setuid может быть использована для использования строки формата по выбору (непривилегированного) пользователя, и может, по крайней мере, вызвать сбой программы и, следовательно, вероятно, может приобрести корневую оболочку. К счастью, требуется локальный доступ к оболочке; это не дистанционная атака. Требуется немалое количество знаний, чтобы попасть туда, но я считаю неразумным предполагать, что экспертиза не «там».

Итак, я описываю «уязвимость строки формата», и известный путь атаки включает в себя фальсификацию программы, так что, хотя она думает, что обращается к защищенным файлам сообщений, она фактически использует и использует файлы сообщений (которые содержат форматные строки), которые находятся под контролем пользователя, а не под контролем программного обеспечения.

Ответы [ 2 ]

2 голосов
/ 13 октября 2008

Вариант 2 работает, если вы напишите новое значение для $PQRHOME после определения его реального пути и проверки его безопасности. Таким образом, очень мало вашего кода необходимо изменить после этого.

Что касается сохранения привилегий setuid, было бы полезно, если бы вы могли выполнить какое-то разделение привилегий, чтобы любые операции, связанные с вводом от реального пользователя, выполнялись под настоящим uid. Затем привилегированный процесс и процесс real-uid взаимодействуют, используя socketpair или что-то в этом роде.

1 голос
/ 13 октября 2008

Ну, это звучит параноидально, но, если это так или нет, зависит от того, на каких системах запущено ваше приложение и какой урон может нанести злоумышленник.

Итак, если ваша пользовательская база, возможно, враждебна и если урон, возможно, очень велик, я бы выбрал вариант 4, но изменил его следующим образом, чтобы устранить его недостатки.

Позвольте мне процитировать две важные вещи:

1)

Программы в настоящее время проверяют, что $ PQRHOME и ключевые каталоги под ним «безопасно» (принадлежит pqrusr, принадлежат pqrgrp, не имеют публичных доступ для записи).

2)

После этого программы получают доступ к файлам в $ PQRHOME по полной значение переменной среды.

На самом деле вам не нужно жестко кодировать полный путь, вы можете жестко кодировать только относительный путь от «программы», упомянутой в 1), к пути, указанному в 2), где находятся файлы.

Проблема для контроля:

a) вы должны быть уверены, что между путём исполняемого файла и путем к файлам нет ничего «доступного для атакующего» (например, в виде символических ссылок)

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


ИЗМЕНЕНО после 3-го комментария:

Если ваша ОС поддерживает / proc, syslink / proc / $ {pid} / exe - лучший способ решить b)


отредактировано после сна на нем:

Является ли установка "безопасным" процессом? Если это так, вы можете создать (во время установки) скрипт-обертку. Этот сценарий должен быть исполняемым, но не доступным для записи (и, возможно, не читаемым). Он установит переменную $ PQRHOME env в «безопасное» значение, а затем вызовет вашу реальную программу (это может в конечном итоге сделать и другие полезные вещи). Так как в UNIX переменные env работающего процесса не могут быть изменены ничем другим, кроме выполняющегося процесса, вы в безопасности (конечно, env vars может быть изменен родителем до процесс начинается). Я не знаю, работает ли этот подход в Windows.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...