Защита систем. Чему «Звездные войны» учат инженера ПО — страница 7 из 68

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

Спуфинг файлов

Путаница в том, какой именно файл представлен некоторым именем, может быть результатом человеческой неточности или подмены файла злоумышленником. И, в отличие от C-3PO, большинство компьютеров не спрашивают: «Какие планы? О чем ты говоришь?» Люди дают файлам самые ужасные имена и сохраняют файлы в нескольких каталогах, но угрозы возникают там, где злоумышленник может подменить файл.

Открытие файлов

Идентификатор файла – это имя файла. Оно может быть подделано, когда файл указан недостаточно определенно (open «config.txt»). Если файл содержит удаленную ссылку, такую как http://example.com/config.txt, связь с example.com может быть подделана.

Простейшей формой поддельных файлов является невозможность получить файл, когда вы его открываете. Например, какой файл открывает fd = open («./file.txt»)?

Если вы скажете своему компьютеру open(«~/.ssh/id_rsa»), то файл, который вы в результате получите, зависит от реализации open() и от эффективного либо реального UID-процесса. Было бы ошибкой уделять здесь слишком много внимания определению «угрозы спуфинга». Гораздо важнее, чтобы ваш код обрабатывал эти потенциальные неточности или неоднозначности безопасным, надежным и защищенным способом. Что еще более важно: если вы не уверены в том, какой именно ресурс вы собираетесь получить или как он сопоставляется с вашими ожиданиями и историей с этим файлом, существуют риски безопасности, с которыми должен справиться ваш код, читающий этот файл.

Полный путь является лучшим подтверждением идентичности. Вы можете быть уверены, когда вызываете open(«/etc/passwd») или когда добавляете тщательно проверенный префикс (/usr/local). Но это не всегда позволит вам получить тот файл, который вы ожидаете!

Например, /tmp/file.txt может принадлежать любому пользователю системы и иметь удивительное содержимое. Добавление случайных чисел не защищает вас; open(«/tmp/file2345.txt») требует только, чтобы злоумышленник создал 10 000 файлов (или символических ссылок), чтобы гарантировать, что они контролируют файл, который вы открываете.

Открытие неожиданного файла становится более неприятным, когда открытый файл интерпретируется как код, например, когда open заменяется на dlopen или LoadLibrary. (Открытие файла и его неожиданная интерпретация как кода еще более неприятны, это описано в главе 8 «Распознавание и порча».) Каждая функция загрузки библиотеки имеет путь поиска, и на этот путь поиска можно повлиять. В Unix-системах LD_LIBRARY_PATH и другие переменные окружения влияют на то, что открывается, создавая проблему, особенно для setuid-кода. В Windows набор путей для поиска библиотек по умолчанию уже давно включает текущую папку (.), и это создает проблемы для кода, выполняемого из общей папки загрузок. Все, что нужно сделать злоумышленнику, это найти библиотеку, которая есть не во всех системах, а затем загрузить ее в папку для загрузок, и любые программы, запущенные оттуда, будут послушно использовать эту библиотеку. Это часто называют проблемой «попутной загрузки», но на самом деле это проблема поддельной библиотеки.

Введение новой библиотеки в «доверенные» каталоги может изменить поведение уже установленных программ. Конечно, существуют и другие способы открытия программы, такие как семейство вызовов exec, все они могут быть вызваны с помощью неспецифических путей. Существует вариант, в котором нужный файл имеет имя типа npm: leftpad или BigBankValidationLibrary. Многие системы сборки также имеют путь поиска, и поэтому будут искать BigBankValidationLibrary всякий раз, когда ищут пакеты, такие как NPM или Maven. И оказывается, что ответ меняется, так что, если вчера эта библиотека была в приватном репозитории, а сегодня есть версия в публичном репозитории, что ж, мы должны взять публичную версию, верно? (В 2021 году исследователь безопасности Алекс Бирсан (Alex Birsan) создал впечатляющую демонстрацию этого с помощью различных трюков, чтобы показать, что запускаются именно его библиотеки, чтобы он мог собирать вознаграждения за обнаруженные ошибки [Montalbano, 2021].)

Природа пути к файлу становится еще более непростой, когда имя сформировано не от корня локальной машины. Один из пределов сложности образуют URL-адреса, которые обсуждаются в главе 8. Может случиться так, что указание файла через URL-адрес сделает указатель более конкретным, или добавит безопасности за счет TLS. Но это также может усложнить синтаксический анализ, привести к сбоям или возможностям для атаки, даже если URL-адрес является статической строкой в коде. Сложность добавляется тем, что библиотека должна взять путь file:///etc/passwd, распознать, что это URL-адрес файла, и следовать соответствующей ветке кода. При вызове удаленных компьютеров появляются дополнительные режимы сбоя. Если вы ссылаетесь на файл как на https://example.com/style.css, есть вероятность, что этот файл стилей будет недоступен или вы получите либо старую, либо искусно вставленную кэшированную версию. Если вы владеете доменом example.com и лично поддерживаете его, этот риск снижается. И наоборот, становится выше по мере ослабления вашего контроля. Существуют также вредоносные режимы сбоя, которые также более подробно рассматриваются в главе 8. А пока представьте, что кто-то взломал www.example.com и заменил файл, на который вы полагаетесь. Разумно предположить, что такой инцидент больше соответствует определению «подделки», но примеры, когда хост подделывается, более сложны для объяснения и рассматриваются в разделе «Спуфинг машин».

Подделка файлов

Другой способ подмены файла – заставить кого-то открыть файл, который, по его мнению, аутентифицирован. Злоумышленник может сделать это, захватив компьютер, чтобы предложить поддельные файлы, изменить цифровые подписи или воспользоваться слабостями в схемах аутентификации. Например, возможно, когда R2-D2 открывает файлы на «Звезде смерти», эти файлы поступают из приманки (сервера-ловушки), и именно поэтому так легко удается найти, где содержится принцесса Лея.

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

Кроме того, можно изменить файл, не нарушая схему подписания. Это более распространено, чем вы могли бы ожидать. Например, в Windows можно добавить дополнительную информацию в подписанный файл и выполнить его. (Детали сложны, но вариантам проблемы были присвоены идентификаторы CVE-2012-0151 и CVE-2013-3900.)

Спуфинг процессов

Файлы – это не единственное пространство имен на компьютере. Процессы также имеют имена и способы обращения к ним. Многие протоколы локальной межпроцессной связи предполагают, что только правильный код может прослушивать определенный порт или файловый сокет. Точно так же в коде часто предполагается, что владельцем удаленного процесса должен быть root, потому что он прослушивает порт с номером меньше 1024.

После того как R2-D2 был похищен джавами, ему удается избежать контроля со стороны «блокиратора», который они установили, и продолжить свою миссию по доставке сообщения Оби-Вану Кеноби. Возможно, он запустил виртуальную машину и позволил блокиратору перенастроить ее, а не свою основную систему? Или, может быть, я слишком много об этом думаю. (На эту двусмысленность впервые указал Джим Дэвис.)

Спуфинг машин

Начнем с простой модели коммуникации между двумя машинами: назовем исходную машину SRC, а целевую машину – DST, как показано на рисунке 1.3. SRC отправляет пакет, и он прибывает к DST. Волшебно, правда? И до тех пор, пока SRC и DST находятся в сети, свободной от угроз, это легко! Но в интернете может быть более одной машины с именем DST. Могут быть DST.example.org и DST.example.com, а также могут быть другие машины, которые отправляют или получают пакеты, выдавая себя за то или иное. Это полезная и распространенная мысленная модель того, как машины общаются, и, как и все модели, она неверна. Злоумышленник может отправлять пакеты, различными способами утверждая, что они исходят от машины с именем SRC. Многие системы, которые авторизуются на основе IP-адреса, такие как rsh, устарели и были выведены из обращения, но другие, например межсетевые экраны, продолжают широко использоваться.


Рис. 1.3. Простая модель коммуникации


Имена машин подвержены подмене на каждом уровне сетевого стека и при каждом взаимодействии между такими именами. Рассмотрим «простой» запрос на dst.threatsbook.com/index.html и уточним потоки данных, поддерживающие этот запрос. Как показано на рисунке 1.4, создается множество соединений, каждое из которых подвержено спуфингу.

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


Рис. 1.4. Множество соединений, поддерживающих запрос


Возможно, машина, которой притворяется взломщик, авторизована для отправки почты или для разрешения входа в систему без многофакторной аутентификации. Поддельные адреса отправителя часто ломают авторизацию, связанную с отправителями, или могут использоваться для обеспечения дополнительных уровней сбоя аутентификации. Когда поддельное сообщение является IP- или UDP-пакетом, вы можете подделать его «вслепую». Фальшивый источник будет получать ответы, но у вас нет необходимости управлять порядковыми номерами или другими вещами. Это становится все труднее сделать, если вы находитесь на расстоянии значительного количества сетевых переходов, так как многие сети теперь реализуют фильтрацию адресов источника и не будут пересылать пакеты, которые не должны были исходить из их сетей.