Введение
Класс программных ошибок
В разработке программного обеспечения, состояние между проверкой и использованием (TOCTOU, TOCTTOU или TOC/TOU) — это класс программных ошибок, вызванных гонкой данных, возникающей при проверке состояния части системы (например, учетных данных безопасности) и последующем использовании результата этой проверки. Гонки TOCTOU часто встречаются в Unix при операциях с файловой системой, но могут возникать и в других контекстах, включая локальные сокеты и некорректное использование транзакций базы данных. В начале 1990-х годов почтовая утилита BSD 4.3 UNIX содержала уязвимость, связанную с гонкой данных при работе с временными файлами, из-за использования функции mktemp. Ранние версии OpenSSH также имели уязвимость, связанную с гонкой данных при работе с Unix domain sockets. Данная проблема остаётся актуальной и в современных системах: по состоянию на 2019 год, гонка TOCTOU в Docker позволяла получить права root-пользователя к файловой системе хост-платформы. На конкурсе Pwn2Own 2023 в Ванкувере команда хакеров смогла скомпрометировать шлюз обновлённой Tesla Model 3, используя эту уязвимость.
In software development, time of check to time of use (TOCTOU, TOCTTOU or TOC/TOU) is a class of software bugs caused by a race condition involving the checking of the state of a part of a system (such as a security credential) and the use of the results of that check. TOCTOU race conditions are common in Unix between operations on the file system, but can occur in other contexts, including local sockets and improper use of database transactions. In the early 1990s, the mail utility of BSD 4.3 UNIX had an exploitable race condition for temporary files because it used the mktemp function. Early versions of OpenSSH had an exploitable race condition for Unix domain sockets. They remain a problem in modern systems; as of 2019, a TOCTOU race condition in Docker allows root access to the filesystem of the host platform. In the 2023 Pwn²Own competition in Vancouver, a team of hackers was able to compromise the gateway in updated Tesla model 3 using this bug.
Надежное время TOCTOU
Использование уязвимости TOCTOU требует точной синхронизации, чтобы операции атакующего и жертвы выполнялись в нужном порядке. В приведенном выше примере атакующий должен выполнить системный вызов создания символической ссылки точно между проверкой доступа и открытием файла. Для наиболее общей атаки атакующий должен быть запланирован для выполнения после каждой операции жертвы, что также известно как "пошаговое" выполнение жертвы. Это применимо к почтовой утилите BSD 4.3 и mktemp, а также к атакам, основанным на алгоритмической сложности. В обоих случаях атакующий манипулирует состоянием операционной системы, чтобы контролировать планирование жертвы. "Файловые лабиринты" вынуждают жертву читать запись каталога, отсутствующую в кэше ОС, и ОС переводит жертву в состояние ожидания, пока она считывает каталог с диска. Атаки, основанные на алгоритмической сложности, вынуждают жертву тратить весь квант времени на выполнение внутри одного системного вызова, обходя хэш-таблицу ядра с кэшем имен файлов. Атакующий создает большое количество файлов с именами, которые хешируются в то же значение, что и файл, который будет искать жертва.
Как предотвратить ОБЯЗАНИЕ
Несмотря на концептуальную простоту, условия гонки TOCTOU трудно избежать и устранить. Один из общих методов – использование обработки ошибок вместо предварительной проверки, в соответствии с философией EAFP – "легче попросить прощения, чем разрешения", а не LBYL – "смотри, прежде чем прыгать". В этом случае проверка отсутствует, а нарушение предположений сигнализируется возвратом ошибки. В контексте условий гонки TOCTOU в файловой системе, основная задача заключается в обеспечении невозможности изменения файловой системы между двумя системными вызовами. В 2004 году был опубликован результат, доказывающий невозможность существования переносимого, детерминированного метода предотвращения условий гонки TOCTOU при использовании системных вызовов UNIX access и open для файловой системы. После публикации этого результата, исследователи предложили библиотеки для отслеживания дескрипторов файлов и обеспечения корректности. Альтернативным решением, предложенным в научном сообществе, является внедрение транзакций в файловую систему или ядро ОС UNIX. Транзакции предоставляют абстракцию управления параллелизмом для ОС и могут быть использованы для предотвращения гонок TOCTOU. Хотя ни одно производственное ядро UNIX пока не внедрило транзакции, для Linux были разработаны исследовательские прототипы, включая файловую систему Valor и ядро TxOS. Microsoft Windows добавила транзакции в свою файловую систему NTFS, но Microsoft не рекомендует их использовать и заявила о возможности их удаления в будущей версии Windows. Блокировка файлов – распространенный метод предотвращения условий гонки для отдельного файла, однако он не распространяется на пространство имен файловой системы и другие метаданные, плохо работает с сетевыми файловыми системами и не может предотвратить условия гонки TOCTOU. Для setuid-бинарников возможным решением является использование системного вызова seteuid для изменения эффективного пользователя, а затем выполнения операции открытия файла. Различия в реализации setuid между операционными системами могут быть проблематичными.