FlawOpen

flawopen.com/Incidents/xz-utils-backdoor-march-2024

● Xz · CVE-2024-3094 · March 2024 · CVSS 10.0 · Критический
Исследования · FlawOpen

Компрометация XZ Utils (CVE-2024-3094)

CVE-2024-3094 затронула архивы XZ Utils 5.6.0/5.6.1. Риск зависел от сборки дистрибутива; найдите и замените уязвимые пакеты.[1], [3], [4], [5], [6]

Вектор CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H[9]
💡 Простыми словами (ELI5)

Представьте репозиторий исходного кода как открытый рецепт, а архив релиза как запечатанный ящик с ингредиентами. Даже если рецепт выглядит верно, кухня проверяет печать и накладную. Одного названия блюда на ящике недостаточно, чтобы отправить его в производство. Манифест, проверенный по отдельному доверенному каналу, может выявить подмену ящика, но даже действительная подпись поставщика не доказывает безвредность авторизованного ящика: скомпрометированные архивы XZ были официальными релизами. Замените затронутые пакеты по рекомендациям дистрибутива; используйте проверку манифеста только как отдельную меру против подмены.[5], [6]

Ключевые понятия и термины

Архив релиза
Архив исходного кода, опубликованный для установки или пакетирования. Он может отличаться от файлов, полученных из репозитория, поэтому его нужно проверять как отдельный артефакт.[3], [4], [6]
Происхождение сборки
Доказательства того, из какого проверенного исходного кода, каких шагов сборки и от какого издателя получен артефакт. Они помогают решить, можно ли доверять загрузке.[5], [6]
Проверка артефакта
Сопоставление хеша или подписи артефакта с ожидаемым значением, полученным через независимый доверенный канал, до использования в сборке или публикации.

Связи со стандартами

  • Ссылка CWE для слабого места, описанного в этом руководстве: CWE-506

Хронология инцидента

24 февраля 2024 г.

Вышел XZ 5.6.0; в последующем заявлении проекта сказано, что его архив релиза содержал бэкдор.[3], [6]

9 марта 2024 г.

Вышел XZ 5.6.1; в том же заявлении сказано, что его архив релиза содержал бэкдор.[4], [6]

До 29 марта 2024 г.

Freund сообщил о внедрённом скрипте сборки в распространяемых архивах, отсутствовавшем в соответствующем исходном файле, после того как необычное использование CPU в SSH и ошибки Valgrind начали расследование.[5], [6]

29 марта 2024 г.

Andres Freund публично сообщил о проблеме.[5]

Пошаговый сценарий атаки

Шаг 1

Репозиторий и распространяемый архив не тождественны

В опубликованном анализе говорится, что в распространяемом архиве были изменения скриптов сборки, отсутствовавшие в соответствующих файлах вышестоящего репозитория. Одной проверки коммитов недостаточно, чтобы доказать безопасность архива.[5], [6]

Шаг 2

Последствия зависели от пути сборки

Проблема проявлялась в конкретных условиях пакетирования и сборки. В официальном отчёте указано, что при сборке из Git соответствующий код не внедрялся; нельзя обобщать область действия на каждую установку XZ или Linux.[5], [6]

Шаг 3

Аномалии стали началом расследования

Andres Freund сообщил о необычном использовании CPU и ошибках Valgrind в процессе SSH. Наблюдаемые признаки привели к расследованию и публичному раскрытию.[5]

Шаг 4

Реагирование начинается с замены и проверки

Рассматривайте это как инцидент с затронутыми пакетами и происхождением сборки. Следуйте рекомендациям дистрибутива и замените затронутые пакеты. Для будущих артефактов проверяйте происхождение и подписи: это помогает выявить подмену, но не доказывает безвредность авторизованного релиза.[1], [6]

Исходный код: Уязвимый vs Защищённый вариант

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
# Принимает загруженный вход сборки, не доказывая его идентичность.
from pathlib import Path

def stage_release(artifact: Path, build_inputs: Path) -> None:
    build_inputs.joinpath(artifact.name).write_bytes(artifact.read_bytes())

# Успешное копирование не доказывает, что архив соответствует
# проверенному выпуску или доверенному манифесту издателя.
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
# Учебный шлюз: проверяет ожидаемый SHA-256 из доверенного манифеста.
import hashlib
import hmac
from pathlib import Path

def verify_release(artifact: Path, expected_sha256: str) -> None:
    digest = hashlib.sha256(artifact.read_bytes()).hexdigest()
    if not hmac.compare_digest(digest, expected_sha256.lower()):
        raise ValueError("артефакт выпуска не соответствует доверенному манифесту")

# Получайте expected_sha256 через отдельно аутентифицированный процесс выпуска
# и вызывайте verify_release до того, как архив станет входом сборки.

# Это выявляет подмену, но не вредоносный авторизованный релиз; следуйте рекомендациям для затронутых пакетов.

Чек-лист по защите системы для инженеров

Источники