Ключ шифрования в MuPDF имел всего 512 вариантов, и скрипт взламывает его за 11 мс
Генератор случайных чисел засевали один раз текущим временем и брали биты не из тех позиций. У 128-битного ключа AES осталось девять бит реальной энтропии.
MuPDF до версии 1.28.5 засевал генератор в стиле drand48 текущим Unix-временем и брал байты из битов, которые почти не зависят от засева. Поэтому метки времени с разницей в 512 секунд дают одинаковые ключи. Автор перебирает все 512 примерно за 11 мс на неоптимизированном Python.
У Foxit Reader есть связанная уязвимость. Уже опубликованные PDF задним числом защитить нельзя.

Как метка времени свелась к девяти битам

Разбор показывает, что MuPDF засевает 48-битный LCG один раз Unix-временем в секундах и берёт каждый байт ключа из битов с 17 по 24 состояния. Умножение и сложение переносят влияние только вверх, поэтому старшие биты на эти выходы не влияют, а младшие 16 бит — фиксированная константа. Значимыми остаются только 9 битов времени. Это даёт 512 возможных ключей файла. Исправлено в MuPDF 1.28.5.
PDF Reader от Foxit 2026.1.3.36551 выводит ключ как SHA-256 от метки времени, 32 фактически нулевых байтов и константы. OpenPDF 3.0.5 и iText 9.7.1 засевают поток ARC4 миллисекундными часами и объёмом свободной памяти JVM. Это более слабая проблема, которую автор называет «проблемой с большей дисперсией».
Тред: дело не в количестве битов
«…число битов в пространстве ключей — не главное; ключи просто не являются криптографически случайными.» — tptacek
Документы, уже зашифрованные уязвимой версией, остаются открытыми. Всё чувствительное, отправленное таким образом, стоит считать доступным для чтения.
Получайте такие разборы каждый день
Главные истории Hacker News — на email, в Telegram или RSS.
Alpine обновила GitLab, но осталась уязвимой: исправление лежало в патче Ruby
Уязвимость с CVSS 10.0 сидела в регулярных выражениях Ruby, а GitLab применяет исправление только в своих пакетах. В образе Alpine был стандартный Ruby.