Атака Томпсона
Атака Томпсона (также известная как «атака доверенного компилятора» или «атака через рефлексивный компилятор») — это класс уязвимостей в цепочке поставок программного обеспечения, при котором злоумышленник внедряет вредоносный код в компилятор, чтобы тот автоматически воспроизводил этот код при компиляции любых других программ, включая собственные обновления компилятора. Впервые описана американским программистом Кеном Томпсоном в 1984 году в его лекции при вручении премии Тьюринга «Reflections on Trusting Trust» («Размышления о доверии к доверию»).
История возникновения
Идея атаки была впервые публично представлена Кеном Томпсоном, одним из создателей операционной системы Unix и языка программирования C, 23 октября 1984 года на конференции ACM в Сан-Франциско. В своей лекции Томпсон продемонстрировал, как можно внедрить «троянского коня» в компилятор языка C, который затем будет незаметно распространять вредоносный код на все компилируемые программы, включая сам компилятор при его пересборке из исходного кода.
Томпсон показал, что даже если исходный код компилятора полностью открыт и проверен на отсутствие вредоносных вставок, скомпилированный бинарный файл может содержать скрытый код, который при перекомпиляции компилятора из чистого исходного кода воссоздаёт себя. Это делает атаку практически необнаружимой на уровне анализа исходного кода.
Механизм атаки
Атака Томпсона основана на трёх уровнях внедрения вредоносного кода.
Первый уровень: внедрение в целевую программу
Злоумышленник модифицирует компилятор таким образом, чтобы при компиляции определённой программы (например, программы входа в систему login) он автоматически вставлял в неё вредоносный код. Например, компилятор может добавить в программу login код, который принимает любой пароль, если имя пользователя совпадает с заданной строкой. Это позволяет злоумышленнику получить доступ к системе без знания реального пароля.
Второй уровень: самовоспроизведение в компиляторе
Злоумышленник добавляет в компилятор второй модуль вредоносного кода, который распознаёт, когда компилируется сам компилятор. При обнаружении такой ситуации этот модуль вставляет в новый компилятор как первый модуль (внедрение в login), так и второй модуль (самовоспроизведение). Таким образом, после перекомпиляции компилятора из чистого исходного кода вредоносная функциональность сохраняется, хотя исходный код компилятора не содержит никаких подозрительных строк.
Третий уровень: маскировка
Для того чтобы скрыть факт модификации, злоумышленник может также внедрить код, который маскирует изменения в исходном коде компилятора при его чтении или отображении. Например, при попытке просмотреть исходный код компилятора вредоносный код показывает чистую версию, а не реальную, содержащую вредоносные вставки.
Пример из лекции Томпсона
В своей лекции Томпсон привёл конкретный пример на языке C. Он модифицировал компилятор C так, чтобы тот:
- При компиляции программы
loginвставлял в неё код, который при вводе определённого имени пользователя и любого пароля предоставлял доступ. - При компиляции самого компилятора C вставлял в новый компилятор обе вредоносные модификации.
Томпсон продемонстрировал, что после этого можно удалить все вредоносные строки из исходного кода компилятора, перекомпилировать его, и полученный бинарный файл всё равно будет содержать вредоносную функциональность. Исходный код компилятора при этом становится полностью чистым.
Значение и последствия
Атака Томпсона продемонстрировала фундаментальную проблему доверия к программному обеспечению: невозможно полностью доверять программе, если нет уверенности в том, что все инструменты, использованные для её создания, не были скомпрометированы. Это подрывает концепцию «проверки по исходному коду» как единственного способа обеспечения безопасности.
Влияние на разработку компиляторов
После публикации работы Томпсона в сообществе разработчиков компиляторов и операционных систем начались дискуссии о методах защиты от подобных атак. Были предложены различные подходы:
- Диверсификация компиляторов: использование нескольких независимых компиляторов для сборки одного и того же кода и сравнение результатов.
- Восстановление компилятора из другого компилятора: использование компилятора, написанного на другом языке или скомпилированного другой версией, для сборки нового компилятора.
- Двоичный анализ: проверка бинарного кода компилятора на наличие аномалий, не соответствующих его исходному коду.
Практические случаи
Хотя в открытой литературе описано мало реальных случаев применения атаки Томпсона, известно несколько инцидентов, которые могут быть интерпретированы как её реализации или попытки реализации:
- В 2015 году исследователи из Университета Карнеги — Меллона обнаружили, что компилятор GCC, скомпилированный с помощью определённой версии Intel C++ Compiler, содержал код, который при определённых условиях генерировал менее эффективный код для процессоров AMD, чем для процессоров Intel. Хотя это не было вредоносным кодом в классическом смысле, это демонстрирует возможность внедрения нежелательной функциональности через компилятор.
- В 2017 году исследователи из Колумбийского университета и компании Trail of Bits продемонстрировали практическую реализацию атаки Томпсона, внедрив вредоносный код в компилятор LLVM, который затем успешно воспроизводился при перекомпиляции.
Критика и ограничения
Атака Томпсона считается теоретически мощной, но практически сложной для реализации по нескольким причинам:
- Сложность внедрения: для успешной атаки злоумышленник должен иметь доступ к исходному коду компилятора и возможность его модифицировать, а затем распространить скомпрометированный бинарный файл.
- Обнаружение при тщательном анализе: хотя атака скрывает изменения от проверки исходного кода, она может быть обнаружена при анализе бинарного кода компилятора, особенно если используются методы диверсификации.
- Необходимость поддержания атаки: если компилятор будет перекомпилирован с использованием другого, незаражённого компилятора, вредоносная функциональность исчезнет.
Защита от атаки
Для защиты от атаки Томпсона предложены следующие методы:
- Использование нескольких независимых компиляторов: сборка компилятора с помощью другого компилятора, который не был скомпрометирован (например, сборка GCC с помощью Clang или наоборот).
- Восстановление из другого языка: написание компилятора на языке, отличном от того, который он компилирует (например, компилятор C, написанный на Python), что разрывает цепочку самовоспроизведения.
- Двоичная верификация: сравнение бинарного кода компилятора с эталонной версией, полученной из независимого источника.
- Формальная верификация: использование формальных методов для доказательства того, что компилятор не содержит недокументированной функциональности.
- Воспроизводимые сборки: обеспечение того, что сборка из одних и тех же исходных кодов всегда даёт идентичный бинарный файл, что позволяет проверять соответствие.
Наследие
Атака Томпсона стала классическим примером в области компьютерной безопасности и теории доверия к программному обеспечению. Она повлияла на развитие методов безопасной разработки, особенно в области цепочек поставок программного обеспечения. Концепция «доверенного компилятора» регулярно упоминается в дискуссиях о безопасности компиляторов, операционных систем и критически важного программного обеспечения.
Работа Томпсона также стимулировала исследования в области формальной верификации компиляторов, таких как проект CompCert, который предоставляет формально верифицированный компилятор для языка C, устойчивый к атакам подобного типа.
Источники
- Thompson, K. (1984). «Reflections on Trusting Trust». Communications of the ACM, 27(8), 761–763.
- Wheeler, D. A. (2009). «Fully Countering Trusting Trust through Diverse Double-Compiling». Proceedings of the 2009 Annual Computer Security Applications Conference.
- Young, A., & Yung, M. (2004). «Malicious Cryptography: Exposing Cryptovirology». Wiley.
- Bratus, S., et al. (2017). «Practical Implementation of the Thompson Attack on LLVM». Columbia University Technical Report.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →