Время проверки до использования - Time-of-check to time-of-use

В разработке программного обеспечения , время-проверки времени в использовании ( TOCTOU , TOCTTOU или TOC / TOU ) является классом программных ошибок , вызванных состоянием гонки с участием проверки состояния части системы (например, учетные данные безопасности) и использование результатов этой проверки.

Условия гонки TOCTOU обычны в Unix между операциями в файловой системе , но могут возникать в других контекстах, включая локальные сокеты и неправильное использование транзакций базы данных . В начале 1990-х почтовая утилита BSD 4.3 UNIX имела уязвимое состояние гонки для временных файлов, потому что она использовала эту mktemp()функцию. Ранние версии OpenSSH имели уязвимое состояние гонки для сокетов домена Unix . Они остаются проблемой в современных системах; с 2019 года состояние гонки TOCTOU в Docker разрешает root-доступ к файловой системе хост-платформы.

Примеры

В Unix следующий код C при использовании в setuidпрограмме содержит ошибку TOCTOU:

if (access("file", W_OK) != 0) {
    exit(1);
}

fd = open("file", O_WRONLY);
write(fd, buffer, sizeof(buffer));

Здесь доступ предназначен для проверки того, может ли реальный пользователь, выполнивший setuidпрограмму, нормально записывать файл (т. accessЕ. Проверяет реальный идентификатор пользователя, а не эффективный идентификатор пользователя ).

Это состояние гонки уязвимо для атаки:

Потерпевший Злоумышленник
if (access("file", W_OK) != 0) {
    exit(1);
}

fd = open("file", O_WRONLY);
// Actually writing over /etc/passwd
write(fd, buffer, sizeof(buffer));
// 
//
// After the access check
symlink("/etc/passwd", "file");
// Before the open, "file" points to the password database
//
//

В этом примере злоумышленник может использовать состояние гонки между accessи, openчтобы обманом заставить setuidжертву перезаписать запись в базе данных системных паролей. Гонки TOCTOU могут использоваться для повышения привилегий , чтобы получить административный доступ к машине.

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

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

Надежно тайминг TOCTOU

Использование состояния гонки TOCTOU требует точного времени, чтобы гарантировать, что операции злоумышленника должным образом чередуются с операциями жертвы. В приведенном выше примере злоумышленник должен выполнить symlinkсистемный вызов точно между символами accessи open. Для наиболее общих атак злоумышленник должен быть запланирован для выполнения после каждой операции жертвы, также известной как «пошаговое выполнение» жертвы.

В случае почтовой утилиты BSD 4.3 и mktemp () злоумышленник может просто продолжать запускать почтовую утилиту в одном процессе, угадывать имена временных файлов и создавать символические ссылки в другом процессе. Атака обычно может быть успешной менее чем за одну минуту.

Методы пошагового выполнения программы-жертвы включают лабиринты файловой системы и атаки с алгоритмической сложностью. В обоих случаях злоумышленник манипулирует состоянием ОС для управления расписанием работы жертвы.

Лабиринты файловой системы вынуждают жертву прочитать запись каталога, отсутствующую в кеше ОС, а ОС переводит жертву в спящий режим, пока она читает каталог с диска. Атаки с алгоритмической сложностью вынуждают жертву тратить весь квант планирования внутри одного системного вызова, просматривая хэш-таблицу имен кэшированных файлов ядра. Злоумышленник создает очень большое количество файлов с именами, хеширующими то же значение, что и файл, который будет искать жертва.

Предотвращение ТОКТУ

Несмотря на концептуальную простоту, условия гонки TOCTOU трудно избежать и устранить. Один общий метод заключается в использовании обработки ошибок вместо предварительной проверки в соответствии с философией EAFP - «Проще просить прощения, чем разрешения», а не LBYL - «смотреть, прежде чем прыгать» - в этом случае проверки нет, и невыполнение предположений сигнализируется возвращением ошибки.

В контексте состояния гонки TOCTOU файловой системы фундаментальной проблемой является обеспечение невозможности изменения файловой системы между двумя системными вызовами. В 2004 году был опубликован результат невозможности, показывающий, что не существует портативного детерминированного метода, позволяющего избежать условий гонки TOCTOU.

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

Альтернативное решение, предложенное в исследовательском сообществе, состоит в том, чтобы системы UNIX использовали транзакции в файловой системе или ядре ОС. Транзакции обеспечивают абстракцию управления параллелизмом для ОС и могут использоваться для предотвращения гонок TOCTOU. Хотя ни одно производственное ядро ​​UNIX еще не поддерживает транзакции, для Linux были разработаны экспериментальные исследовательские прототипы, включая файловую систему Valor и ядро ​​TxOS. Microsoft Windows добавила транзакции в свою файловую систему NTFS , но Microsoft не рекомендует их использовать и указала, что они могут быть удалены в будущей версии Windows.

Блокировка файлов - это распространенный метод предотвращения состояний гонки для одного файла, но он не распространяется на пространство имен файловой системы и другие метаданные, а также блокировка плохо работает с сетевыми файловыми системами и не может предотвратить состояния гонки TOCTOU.

Для двоичных файлов setuid возможным решением является использование seteuid()системного вызова для изменения действующего пользователя, а затем выполнение open(). Различия setuid()между операционными системами могут быть проблематичными.

Смотрите также

использованная литература

дальнейшее чтение