Anatoly Vorobey (avva) wrote,
Anatoly Vorobey
avva

Categories:

линукс и процессы (компьютерное)

Эта запись будет интересна, боюсь, только тем, кто разбирается в Юниксе и особенно в Линуксе.

На израильской линуксовской рассылке кто-то спросил помощь зала в решении проблемы. Проблема следующая. У меня есть процесс, который бежит с администраторскими привилегиями (как root, короче). Мне нужно сделать так, чтобы с помощью обычных ps/top этот факт нельзя было обнаружить: чтобы они показывали его бегущим под другим юзером. При этом можно предположить, что у меня есть root-доступ к этой системе, но я ограничен в некоторых своих действиях. Я не могу менять ядро, загружать новые модули в ядро, а также менять стандартные запускаемые файлы ps/top и стандартные библиотеки. Вопрос: что ещё я могу сделать?

Проблема сформулирована достаточно расплывчато, т.к. неясно в частности, кого нужно обмануть: человека, который запускает эти ps/top, или какой-нибудь скрипт. Но оставим эту расплывчатость, как она есть, и попытаемся придумать какие-нибудь методы. Способ “сменить PATH данному юзеру, чтобы запускались не стандартные ps/top, а другие” тоже отметём, как слишком тривиальный/очевидный/легкообнаруживаемый. Что остаётся?

Я придумал три штуки:

1) это достаточно серьёзное извращение ;), но можно сменить имя рута на данной системе, т.е. назвать uid 0 другим именем вместо root. Неискушённого юзера это вполне может обмануть. Недостаток: возможно, ломаем кучу скриптов/программ, которые полагаются на то, что uid 0 = root. В принципе, строго говоря, они все дефективны, если на это полагаются, но на практике, думаю, они на каждом шагу, в том числе среди скриптов, управляющих процессом загрузки системы.

Добавить ещё одну запись в /etc/passwd с uid 0 и другим именем не помогает, т.к. ps/top пользуются getpwuid(), а она берёт первую подходящую строку. Заставить все программы видеть одного юзера с uid 0, а ps/top другого, таким способом не выйдет.

2) ставим LD_PRELOAD: либо для данного юзера в его стартовых скриптах (рассчитывая на то, что он в этом не разбирается), либо общесистемно в /etc. В LD_PRELOAD ставим имя небольшой библиотеки, которая перекидывает на себя вызовы функции open(). ps/top читают информацию о процессах из "/proc/[pid]/stat" ; значит, наша фальшивая open() будет проверять, не пытаются ли открыть этот файл. Если пытаются, она копирует его в другое место (в /tmp например), меняя при этом нужное поле в нём, потом открывает его вместо настоящего и возвращает этот дескриптор. Тогда ps/top прочитают как миленькие из этого дескриптора и закроют его.

3) программа, бегущая как root, во время своей работы вызывает mount() и ставит поверх /proc/[my pid]/ копию tmpfs. При этом она держит открытый дескриптор старой директории. Раз в секунду она копирует все файлы и симлинки из старой директории в tmpfs, изменяя при этом файл stat, и маскируя свой настоящий uid. Всё.

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

В общем, это всё, что было предложено (идею номер 2) независимо предложили другие участники тоже). Да, есть ещё такая штука, как capabilities, когда программа может бежать не как root, но иметь некоторые рутовские привилегии. Но вроде бы в текущих версиях Линукса она работает плохо, куча багов, и поломаны user-mode утилиты для неё.

Есть ещё что-то существенное, интересно?
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 25 comments