РАЗБОР На проверке

Атаки на слабые алгоритмы шифрования: разбор

Сергей Попов
Сергей Попов Red Team · 6,5 тыс. сообщений
Подписаться
38
[ обложка статьи ]
Режим чтения
Печатная плата сетевого устройства на антистатическом коврике: обугленный криптографический чип со следами пайки, рядом щуп логического анализатора. На экране диагностики светятся искажённые строки...


4 096 запросов к серверу - и plaintext лежит перед тобой без единого бита ключа. Первый раз я собрал padding oracle вручную на криптографическом CTF-таске, где сервер возвращал два разных ответа: «invalid padding» и «bad MAC». Два кода ошибки - классический оракул, 256 попыток на байт, 16 байт в блоке AES. Математика элементарная, а вот результат - нет. Именно атаки на слабые алгоритмы шифрования стабильно ломают реальные приложения, причём не где-то в теории. По данным OWASP, Cryptographic Failures сидит на второй строке Top 10 (A02:2021), а padding oracle остаётся одним из самых воспроизводимых векторов в этой категории. Ниже - разбор атак, которые регулярно встречаются и на CTF, и на реальных пентестах: padding oracle, CBC bit-flipping, слабый RSA и эксплуатация ECB-режима.

Криптография для пентестера: зачем разбираться в криптоатаках​

Криптография для пентестера - не академическая дисциплина, а рабочий инструмент. На реальном ассессменте доказывать теоремы не придётся, а вот подменять байты в зашифрованном cookie, расшифровывать токены через оракул или факторизовать слабый RSA-ключ - вполне. Это не баг в коде приложения. Это баг в выборе или реализации криптографического механизма.

В терминологии MITRE ATT&CK такие действия попадают в технику Weaken Encryption (T1600, Defense Impairment), конкретнее - Reduce Key Space (T1600.001), где атакующий эксплуатирует ослабленное шифрование для доступа к данным. Отдельная техника Private Keys (T1552.004, Credential Access) покрывает случаи, когда атакующий находит и утаскивает сохранённые приватные ключи (файлы .pem, .key и т.д.) на скомпрометированной системе. Криптоаналитическое извлечение ключа - через факторизацию RSA-модуля с малой экспонентой или side-channel - точного маппинга в ATT&CK не имеет, потому что фреймворк описывает поведение атакующего в системе, а не математические атаки. T1600.001 иногда используют как условное приближение, хотя строго эта техника про ослабление шифрования до генерации ключа.

Бизнес-логика атакующего проста: слабая криптография превращает зашифрованные данные в данные с декоративной защитой. Красивый фантик, а внутри - plaintext. Монетизация - от кражи сессий (подмена cookie через bit-flipping) до прямого доступа к секретам (расшифровка через padding oracle). Для пентестера это вектор, который стабильно пропускают автоматические сканеры: Burp Suite покажет, что приложение использует AES-CBC, но не скажет, уязвим ли оракул. Ручной анализ ответов сервера - единственный надёжный способ.

Padding Oracle Attack - от теории к эксплуатации​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

статистически находится в середине диапазона. Как пишет Cloudflare, «an attacker can construct 256 ciphertexts whose last bytes decrypt to the numbers 0x00 to 0xFF» - максимум 256 попыток на каждый байт.

POODLE (CVE-2014-3566) - padding oracle в дикой природе​

POODLE (Padding Oracle On Downgraded Legacy Encryption) - одна из самых известных реализаций padding oracle в реальном протоколе. CVE-2014-3566 затрагивает SSL 3.0: протокол использует недетерминированный CBC-padding, что позволяет MitM-атакующему расшифровать данные.

По данным NVD: CVSS 3.4 (LOW) с вектором CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N - сетевой доступ, высокая сложность (AC:H), требуется действие пользователя (UI:R), но изменение scope (S:C) позволяет воздействовать за пределами уязвимого компонента. CWE-310 (Cryptographic Issues) и CWE-329 (Not Using an Unpredictable IV with CBC Mode) описывают два аспекта проблемы.

А вот дальше - интересно. CVSS говорит LOW (3.4), но EPSS (Exploit Prediction Scoring System) - 1.0000, percentile 1.0000. CVE в абсолютном топе по вероятности эксплуатации среди всех CVE в базе. Причина: атака воспроизводима, инструментарий публичен (PoC-репозиторий mpgn/poodle-PoC на GitHub, 267 звёзд), а SSL 3.0 до сих пор живёт в legacy-системах. CVSS оценивает severity удара, EPSS - вероятность того, что ударят. POODLE - случай, когда «низкая severity» совсем не значит «неопасно».

Механика: атакующий через JavaScript на HTTP-странице заставляет браузер жертвы отправлять запросы к HTTPS-серверу, подбирает длину URL для выравнивания данных по границам блоков, затем копирует целевой блок шифротекста в позицию последнего блока (где padding). Если сервер принимает запрос - padding корректен, атакующий узнаёт один байт. Максимум 256 запросов на байт cookie. Для 16-байтного cookie - не более 4 096 запросов, по времени - несколько минут.

PadBuster: автоматизация атаки на padding oracle​

На CTF и реальных пентестах padding oracle автоматизируют через PadBuster (Perl) или собственные скрипты на Python. Типичный вызов:
Bash:
padbuster http://target/api/decrypt \
  "E3B0C44298FC1C14..." 16 \
  -encoding 0 \
  -errorstring "Invalid padding"
Аргумент 16 - размер блока AES, -encoding 0 - hex (1 для Base64), -error - строка, по которой PadBuster отличает «плохой padding» от всего остального. Инструмент перебирает до 256 вариантов для каждого байта (в среднем около половины) и восстанавливает plaintext.

На CTF часто попадаются нестандартные оракулы: timing oracle (разница в 0.1 мс при валидном и невалидном padding), различие по HTTP status code или по длине тела ответа. PadBuster с такими не справляется - нужен собственный скрипт: цикл по позициям байтов, внутри - цикл по 256 значениям, отправка модифицированного ciphertext и анализ ответа. По данным Microsoft, «it's now believed that this is a practical threat for all languages and libraries when the application's response to failure is taken into account» - даже минимальная разница во времени обработки достаточна для оракула.

CBC Bit-Flipping - атака на шифротекст без знания ключа​

Если padding oracle позволяет расшифровать данные, то CBC bit-flipping позволяет их модифицировать - опять же без знания ключа. Атаки разные, но обе эксплуатируют структуру CBC.

XOR-арифметика для эксплуатации​

Формула дешифровки CBC: P[i] = D(C[i]) XOR C[i-1]. Промежуточное значение D(C[i]) зависит только от ключа и блока C - оно фиксировано. Меняешь байт в C[i-1] - меняется соответствующий байт в P[i]. Контроль через один XOR.

Допустим, в позиции j блока P[i] стоит символ 'u' (часть строки «user»), а нужен 'a' (чтобы получить «admin»). XOR'им C[i-1][j] с ord('u') XOR ord('a'):

C'[i-1][j] = C[i-1][j] XOR ord('u') XOR ord('a')

После дешифровки: P'[i][j] = D(C[i])[j] XOR C'[i-1][j] = P[i][j] XOR ord('u') XOR ord('a') = ord('u') XOR ord('u') XOR ord('a') = ord('a').

Побочный эффект: блок P[i-1] станет мусорным, потому что мы изменили C[i-1]. Если приложение не проверяет целостность этого блока - атака проходит. Именно поэтому encrypt-then-MAC блокирует и padding oracle, и bit-flipping: модифицированный ciphertext не пройдёт проверку HMAC.

Практика: подмена роли в зашифрованном cookie​

Классический CTF-сценарий: сервер выдаёт cookie вида role=user;name=guest, зашифрованный AES-CBC. Задача - получить cookie с role=admin. Если role= попадает в конец первого блока, а значение user - в начало второго, модифицируем байты IV или предыдущего блока:
Python:
import base64

cookie = base64.b64decode(encrypted_cookie)
iv, ct = cookie[:16], cookie[16:]

# 'user' → 'admi' в начале второго блока
mod = bytearray(iv)
mod[0] ^= ord('u') ^ ord('a')
mod[1] ^= ord('s') ^ ord('d')
mod[2] ^= ord('e') ^ ord('m')
mod[3] ^= ord('r') ^ ord('i')

forged = base64.b64encode(bytes(mod) + ct).decode()
Четыре XOR-операции - и user превращается в admi. На реальных CTF расположение целевых байтов нужно вычислить (или подобрать через recon формата cookie), но принцип тот же. Bit-flipping - одна из самых быстрых криптоатак: если знаешь формат plaintext, подмена занимает минуты.

На пентесте CBC bit-flipping атака работает против любого приложения, которое шифрует структурированные данные (cookie, токены авторизации, параметры API) без проверки целостности. И это не экзотика - свежие микросервисы с AES-CBC без HMAC встречаются чаще, чем хотелось бы.

RSA атаки CTF - слабые ключи и математические ошибки​

RSA - фундамент асимметричного шифрования, но кривая реализация превращает его в задачу уровня «школьная алгебра». В терминах MITRE ATT&CK эксплуатация слабого RSA попадает в Private Keys (T1552.004) - извлечение приватного ключа через криптографическую слабость, а также в Password Cracking (T1110.002) при брутфорсе коротких ключей.

Малая публичная экспонента (e=3)​

Если публичная экспонента e = 3 и plaintext m достаточно мал (m³ < n), то c = m³ mod n = m³ - модульная арифметика просто не вступает в игру. Дешифровка сводится к извлечению кубического корня:
Python:
from gmpy2 import iroot

c = 0x...  # шифротекст из задачи
m, exact = iroot(c, 3)
if exact:
    print(m.to_bytes((m.bit_length() + 7) // 8, 'big'))
Три строки - и plaintext восстановлен. На CTF это встречается регулярно: таск выдаёт публичный ключ с e=3 и шифротекст. Если plaintext - ASCII-строка длиной до ~40 символов, m³ гарантированно меньше типичного 2048-битного n.

Вариации с e=17 или e=65537 при нескольких получателях (Hastad's broadcast attack): один plaintext зашифрован разными ключами с одинаковым e. Через CRT (Chinese Remainder Theorem) восстанавливается m^e, затем извлекается корень. Если e=3 и есть три шифротекста с разными модулями - CRT даёт точный m³, из которого корень извлекается тривиально.

Общий модуль (Common Modulus Attack)​

Если два пользователя используют одинаковый n, но разные e₁ и e₂ (при gcd(e₁, e₂) = 1), из двух шифротекстов c₁ = m^e₁ mod n и c₂ = m^e₂ mod n можно восстановить m через расширенный алгоритм Евклида. Находим a, b такие что a·e₁ + b·e₂ = 1, затем m = c₁^a · c₂^b mod n. Без факторизации, без приватного ключа.

На CTF эту атаку часто маскируют: дают два «разных» ключа, но с одинаковым n. Первым делом проверяй: n₁ == n₂? Если да - common modulus attack, решение за секунды.

RsaCtfTool - автоматизация рутины​

RsaCtfTool (GitHub) объединяет десятки атак на RSA: факторизация через базы (factordb), метод Ферма, Wiener's attack (малый d), Boneh-Durfee, Hastad, common modulus и другие. На CTF часто хватает одной команды: python3 RsaCtfTool.py --publickey key.pub --uncipher ciphertext.enc. Инструмент сам определяет слабость и применяет подходящую атаку.

Но полагаться только на автоматизацию - ошибка. RsaCtfTool не покрывает кастомные варианты: нестандартный padding, комбинированные схемы, ошибки в реализации OAEP. Для таких случаев нужен ручной разбор с pycryptodome и gmpy2. По сути, RsaCtfTool - это initial access к RSA-задачам, а privilege escalation на сложных тасках требует ручного анализа. Инструмент хорош, но не серебряная пуля.

ECB Mode - детектирование и эксплуатация уязвимостей шифрования​

ECB (Electronic Codebook) - режим, в котором каждый блок шифруется независимо одним ключом. Одинаковые блоки plaintext дают одинаковые блоки ciphertext. Отсюда знаменитая «проблема Tux»: зашифрованное ECB-изображение пингвина Linux сохраняет контуры оригинала, потому что одинаковые пиксели дают одинаковые блоки шифротекста. Структура данных полностью сохраняется - шифрование есть, а толку от него нет.

Как обнаружить ECB на пентесте​

На CTF ECB детектируется прямолинейно: отправь plaintext с повторяющимися блоками (32 байта символа 'A') и проверь, есть ли повторяющиеся 16-байтные блоки в ciphertext. Если ciphertext[0:16] == ciphertext[16:32] - это ECB. Готово.

В реальных приложениях: зашифрованные cookie или токены с повторяющимися блоками при одинаковых входных данных - маркер ECB. CyberChef удобен для визуального анализа: загрузи hex-дамп, разбей на 16-байтные блоки, подсвети дубликаты. Ещё один fingerprint - отсутствие IV в начале ciphertext. CBC всегда добавляет 16 случайных байт (IV), ECB - нет. Если длина шифротекста точно кратна длине plaintext с padding - подозрительно.

ECB Cut-and-Paste​

Если приложение шифрует структурированные данные в ECB (допустим, email=user@test.com&role=user), атакующий переставляет блоки шифротекста, собирая нужную комбинацию. Как матрёшка наоборот: разбираешь и собираешь заново, но уже с нужным содержимым.

Сценарий: регистрируешься с email длиной, которая выравнивает role= на границу блока. Отдельно регистрируешься с email, содержащим admin + PKCS#7 padding (11 байт со значением \x0b - значение равно длине padding, как требует PKCS#7), чтобы получить блок с зашифрованным «admin + padding». Берёшь нужный блок из второго шифротекста, подставляешь вместо последнего блока первого - и получаешь role=admin с корректным padding.

Защита от ECB - CBC, CTR или AEAD-режимы (GCM, ChaCha20-Poly1305). Но CBC без MAC, как показано выше, тоже уязвим. Современная рекомендация - AEAD (Authenticated Encryption with Associated Data): шифрование со встроенной проверкой целостности. TLS 1.3 полностью отказался от CBC в пользу AEAD-режимов, что убирает padding oracle как класс атак на транспортном уровне. А вот прикладной уровень - cookie, токены, API-параметры - по-прежнему зависит от выбора разработчика.

Половина криптографических CTF-тасков решается не высшей математикой, а паттерн-матчингом: увидел ECB - пробуй cut-and-paste, увидел CBC без MAC - пробуй padding oracle и bit-flipping, увидел RSA с маленьким e - извлекай корень. Реальные пентесты устроены похоже: legacy-системы всё ещё используют CBC без HMAC, IoT-устройства шифруют одним ключом на всю партию, а SSL 3.0 живёт в корпоративных VPN.

Криптографические уязвимости пропускают не потому что они сложные, а потому что не знают, что искать. Padding oracle не требует PhD - требует понимания, что два разных ответа сервера на ошибку дешифровки и есть оракул. Bit-flipping не требует ключа - требует знания формата plaintext и одной XOR-операции. Взлом слабой криптографии RSA не требует суперкомпьютера - требует проверки экспоненты и модуля на очевидные слабости.

На реальных ассессментах CBC без MAC попадается регулярно. Не в legacy-системах из 2005 года - в свежих микросервисах, где разработчик «взял пример с Stack Overflow». Padding oracle на таком сервисе собирается за час. Bit-flipping на cookie с role=user в role=admin - за десять минут, если знаешь формат. Это рабочие векторы, которые дают initial access или privilege escalation, а не теоретические конструкции из учебника. Если в арсенале есть PadBuster, RsaCtfTool и пара десятков строк на Python с pycryptodome - этого хватит для закрытия 80% криптографических задач на CTF и выявления слабой криптографии на ассессментах. Оставшиеся 20% - кастомные схемы, которые ломаются разбором кода, а не готовым инструментом. Если хочется отработать эти цепочки руками - crypto-категория на HackerLab.pro покрывает padding oracle, RSA и block cipher атаки с разной глубиной погружения.
Полезно

Комментарии

0