Многие угрозы расширения полномочий связаны с нарушением преднамеренно разработанных средств контроля, в то время как другие полагаются на неожиданное поведение этих средств контроля.
В этой главе мы рассмотрим те общие привилегии, которые являются как целями, так и отправными точками для распространенных форм атаки. Каждая из них нарушает цель авторизации. Авторизация похожа на английское значение authorization: давать разрешение, согласие или одобрение. Такие учетные записи, как root, имеют право делать с вашим компьютером гораздо больше, чем веб-сайт.
Механизмы расширения и их действие
Несмотря на то что детали варьируются бесконечно, все механизмы, используемые злоумышленниками для расширения полномочий, довольно похожи. Джедаи, ситхи и даже охотники за головами пробираются на корабль, и их локальное местоположение дает им полный доступ к компьютерам. В нашем мире те уязвимости, которые позволяют удаленно выполнять код из-за ошибки синтаксического анализа или выполнения, приводят к тому, что злоумышленник получает больше полномочий. Более подробно они обсуждаются в главе 8 «Распознавание и порча». Вкратце, удаленное выполнение кода может произойти из-за того, что обработчик инструкций ошибочно воспринимает (входные) данные как код. Это происходит, когда процессор получает инструкции в вершине стека. Это также происходит, когда оболочка Unix видит точку с запятой или обратные кавычки, указывающие на следующую за ними команду, или выполняет содержимое обратных кавычек. Это же происходит, когда синтаксический анализатор SQL получает точку с запятой или прямые кавычки. В каждом случае возникает путаница между кодом и данными.
Злоумышленник также может получить полномочия, если мы намеренно запускаем его код, не зная, что это такое.
Рассмотрим такой распространенный пример:
curl $URL | bash
В этом примере bash не знает, откуда curl получает свои данные. Проектная философия Unix основана на использовании «маленьких программ, которые хорошо делают что-то одно» и объединения их с помощью каналов. Поскольку программы обычно выполнялись в одном и том же пользовательском контексте, предполагается, что вводимые данные не являются вредоносными. А как же иначе? Оболочка bash, как правило, ожидает, что ее входные данные поступают из надежного источника.
Если вы не сталкивались с таким примером, curl – это запуск веб-клиента из командной строки, и он будет извлекать содержимое (предположительно удаленного) URL-адреса и передавать эти команды непосредственно в оболочку bash, предоставляя этому сайту полномочия вашей локальной оболочки и, возможно, устанавливая (как минимум) нужное вам программное обеспечение. Некоторые специалисты по безопасности приходят в шок от этого примера, который ненамного хуже, чем другие методы установки. Мне не нравится шаблон для интерактивного использования, и я больше беспокоюсь о нем, когда он используется в сценариях сборки, обращающихся к произвольным сайтам, потому что он игнорирует репозитории кода или артефактов и тем самым делает ваши сборки менее надежными.
Код, находящийся в середине такой цепочки, часто, сам того не желая, помогает злоумышленникам продемонстрировать эту точку зрения. Иногда они изменяют поток управления; в других случаях поток управления остается в соответствии с первоначальным замыслом, а аргументы или результат выполнения оказываются неожиданными.
Например, внедрение SQL-кода происходит из-за того, что веб-сервер включает свои входные данные в SQL-команды, которые он посылает базе данных. Поток управления веб-сервера не изменяется. База данных доверяет веб-интерфейсу отправлять ему правильно сформированный код.
Выполнение кода, написанного кем-то другим, обычно приводит к тому, что этот код имеет те же полномочия, что и ваша учетная запись. (В меньшей степени это относится к современным операционным системам телефонов.) Это в равной степени относится как к скомпилированному коду, так и к скрипту оболочки. Веб-браузеры представляют собой необычный случай. Они усердно работают над тем, чтобы ослабить полномочия, которые они предоставляют HTML, JavaScript или WASM, и даже те, которые они предоставляют расширениям браузера.
Код, который тщательно проверяет свои входные данные на валидность для четко определенных целей, может быть атакован, если он тестирует эти входные данные, в то время как злоумышленник все еще может их изменить. Например, если вы встроите проверку в код JavaScript, который выполняется в браузере, владельцу браузера будет несложно его изменить.
Код – не единственное, о чем вы можете пожалеть, приняв его за входные данные. Если программа принимает имена файлов и может действовать от имени многих пользователей, например веб-сервера или почтового сервера, то необходимо убедиться, что пользователь может работать с этим конкретным файлом. Эта проблема сложна из-за таких тонкостей, как канонизация имен файлов, символические ссылки, объединенные представления файловых систем или карантины для интернет-файлов. Это пример проблемы «сбитый с толку представитель», которую мы обсудим подробнее в этой главе.
Канонизация – это сложно
Чтобы сделать сложности более конкретными, давайте рассмотрим ограничение доступа к файлу. HTAccess, исполняемое веб-сервером Apache на Mac. Должен ли Apache HTTPd распознавать его как файл, определяющий управление доступом? Файловая система Mac HFS не чувствительна к регистру, в то время как Apache вообще-то создавался с предположением, что лежащая под ним файловая система чувствительна к регистру. Таким образом, перенос идеальной копии веб-сайта с Linux на macOS может изменить его поведение. (Или, возможно, Apache учитывает это – проверка требует большего, чем простое исполнение команды grep над кодом.) В качестве другого примера, все еще на Mac, рассмотрим случай скромного приложения «Калькулятор» в /Applications. Если вы откроете /Applications в Finder, вы увидите приложение. Но если вы откроете терминал и наберете ls/Applications, его там не будет (во всяком случае, в macOS Monterey). Что из этого правильно? У меня есть свое мнение, но более важно то, что вы должны понимать: эти представления файловой системы могут быстро становиться запутанными.
Если вы не знаете ответов, насколько аккуратно вы можете делегировать полномочия?
Последним важным случаем расширения полномочий являются разрешения, техническое значение которых шире, чем некогда предполагалось. Это может произойти из-за недостатков удобства использования (usability) в системе контроля доступа или из-за того, что уровень контроля был ослаблен для отладки, а как только все заработало, контроль редко возвращается к более строгому уровню.
Существует множество начальных и конечных точек, когда кто-то расширяет свои полномочия, и в таблице 6.1 приведены некоторые распространенные примеры. (Названия конкретных брендов приведены только в качестве примеров.) Я использую слово «обычный» для обозначения учетной записи без прав или привилегий администратора.
Таблица 6.1. Примеры расширения полномочий[1]
Полномочия в конкретных сценариях
Как бы ни были сложны полномочия для традиционных настольных компьютеров, по крайней мере, их диапазон управления был локальным, а пользовательские интерфейсы могли быть богатыми. В умных устройствах же часто непонятно, кто какими полномочиями обладает, иногда по замыслу, а иногда из-за отсутствия замысла. Это всплывает на поверхность с годами эксплуатации и патчей для джейлбрейка телефонов. Облачные системы быстро усложняются. Каждый из этих случаев будет рассмотрен в своем разделе. Для начала мы обсудим новые модели полномочий, которые используют блокчейны.
Биткоин популяризировал новый механизм полномочий: доказательство работы. Выполнив работу по добыче новой монеты, цепочка расширяется таким образом, что все участники должны принять на себя будущие обязательства перед цепочкой. Неясно, насколько это будет важно с течением времени. Системы искусственного интеллекта и машинного обучения не имеют большого количества уникальных угроз расширения полномочий, но они страдают от интересной проблемы, которая заключается в том, что злоумышленник, который может скормить вам обучающие данные, имеет неявную возможность изменить вашу модель и, следовательно, действия вашей системы. Это немного выходит за рамки строгого определения полномочий, потому что, в конечном счете, именно люди наделены правом выбирать обучающие данные.
До этого момента в книге я использовал термин «сбитый с толку представитель» несколько вольно. Пришло время обосновать его в терминах полномочий и объяснить более подробно. Во-первых, C-3PO не является сбитым с толку представителем, потому что его ни разу не обманывают, чтобы использовать его способности на пользу Империи.
Программа, которую мы рассматриваем в качестве представителя, обычно имеет какие-то дополнительные полномочия и старается использовать их ограниченным образом. Сбитый с толку представитель, как мы понимаем со временем, использует свои полномочия не так, как должен был. Существуют отдельные группы программ, которые демонстрируют такую же путаницу.
• Программы, исполняющие команду setuid, недостаточно снижают свои полномочия и непреднамеренно предоставляют их другим.
• Демоны – либо демоны, слушающие сеть, которые передают полномочия удаленным вызывающим акторам, либо локальные привилегированные демоны, которые передают их локальным вызывающим объектам. Иногда один демон с энтузиазмом служит обеим популяциям одновременно! Стремление избежать этого отрицательного примера сказалось на дизайне почтовой транспортной системы qmail.
• Доступные API-серверы являются частным случаем кода демона. К ним относятся общедоступные API, API приложений и приватные API.