Главная / Блог / Криптография CTF: ломаем шифр Цезаря, Виженера и XOR в CyberChef и Python

15 мин.00

Криптография CTF: ломаем шифр Цезаря, Виженера и XOR в CyberChef и Python

Криптография CTF: ломаем шифр Цезаря, Виженера и XOR в CyberChef и Python

Криптография CTF: ломаем шифр Цезаря, Виженера и XOR в CyberChef и Python

Строка Wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj — новички на CTF тратят на такое десять-пятнадцать минут, тыкая Base64 и Hex-декодеры наугад. Опытный участник распознаёт шифр Цезаря за секунды: только латиница, пробелы на месте, длина совпадает с ожидаемым plaintext. Один рецепт ROT13 Brute Force в CyberChef — и через полминуты на экране The quick brown fox jumps over the lazy dog со сдвигом 3. Разница между «завис на час» и «сдал за минуту» — не в знании высшей математики, а в навыке распознавания паттернов. Ниже — разбор трёх классических шифров, которые покрывают большинство задач категории crypto на соревнованиях начального и среднего уровня: Цезарь, Виженер и XOR.

Как определить тип шифра за 60 секунд

Прежде чем ломать шифр, нужно понять, с чем имеешь дело. Категория crypto на CTF устроена предсказуемо: подавляющее большинство задач укладывается в полдюжины паттернов. Главная ошибка новичков — бросаться в инструменты, не проведя первичную классификацию шифротекста. Подход «набор символов → индекс совпадений → частотный профиль» решает задачи быстрее любого автоматического детектора.

Набор символов — первый фильтр

Скопируйте шифротекст в текстовый редактор и ответьте на три вопроса.

Какие символы присутствуют?

Наблюдение Вероятный тип Следующий шаг
Только 0-9 и A-F Hex-кодировка Декодировать в ASCII
A-Z, a-z, 0-9, +, /, заканчивается на = Base64 Декодировать, проверить результат
Только 0 и 1, группы по 8 Binary Перевести в ASCII
Только латиница (A-Z) Классический шифр Считать индекс совпадений
Пары букв, чётная длина Playfair или Hill Анализ диграфов

Соотношение длин. Шифротекст на треть длиннее ожидаемого plaintext — скорее всего Base64. Ровно вдвое — Hex. Длины совпадают — подстановочный или перестановочный шифр.

Видимые паттерны. Повторяющиеся последовательности через равные интервалы — полиалфавитный шифр с коротким ключом. Группы по 5 букв — формат военного шифра. Сохранённые пробелы и пунктуация — скорее всего простая подстановка.

Частая ловушка на CTF — многослойное кодирование. Авторы задач любят наворачивать цепочки-матрёшки: оригинал → Base64 → Hex → ROT13, и где-то внутри — флаг. Первым делом прогоняйте «бесключевые» преобразования (Base64, Hex, Binary, URL decode) — они бесплатны по времени. После каждого слоя ищите формат флага (flag{, CTF{, префикс конкретного соревнования). Подход аналогичен технике Deobfuscate/Decode Files or Information (T1140, MITRE ATT&CK) — аналитики вредоносного ПО снимают слои кодировок по тому же алгоритму.

Индекс совпадений: моноалфавитный или полиалфавитный шифр

Если шифротекст состоит только из букв и бесключевые декодеры молчат — считайте индекс совпадений (IC, Index of Coincidence). По сути IC показывает, насколько «неравномерно» распределены буквы в тексте. Для тех кто в танке — если буквы распределены как в обычном английском тексте, IC будет высоким. Если распределение плоское (каждая буква встречается примерно одинаково) — низким.

Формула: IC = сумма(ni * (ni - 1)) / (N * (N - 1)), где ni — количество каждой буквы, N — общее число букв.

Арифметика уровня пятого класса, но диагностическая ценность огромная:

IC Что это значит Тип шифра
Около 0.067 Распределение как в английском Моноалфавитная подстановка (Цезарь, простая замена) или перестановка
Около 0.038 Распределение близко к равномерному Полиалфавитный шифр (Виженер)
Между 0.038 и 0.067 Промежуточное значение Виженер с коротким ключом

Алгоритм принятия решений прост. IC около 0.067 — попробуйте все 25 сдвигов Цезаря, это 30 секунд работы. Не сработало — полная подстановка, нужен частотный анализ. IC низкий (около 0.04) — определяйте длину ключа Виженера методом Касиски, потом разбирайте каждую позицию отдельно. IC около 0.067, но частоты не совпадают с английским профилем — перестановочный шифр: буквы правильные, порядок нарушен.

Для русского текста пороговое значение IC другое — около 0.053. Если соревнование русскоязычное, корректируйте ожидания.

Шифр Цезаря — взлом перебором 25 ключей

Шифр Цезаря сдвигает каждую букву открытого текста на фиксированное число позиций в алфавите. Ключ — число от 1 до 25 (сдвиги 0 и 26 — одно и то же). Самый элементарный шифр в криптографии CTF, но встречается регулярно — и как самостоятельная задача начального уровня, и как компонент сложных многоступенчатых цепочек.

Математически: c = (p + k) mod 26, где p — позиция буквы открытого текста (a=0, b=1, ..., z=25), k — ключ, c — позиция буквы шифротекста. Расшифровка: p = (c - k) mod 26. Частный случай ROT13 — Цезарь со сдвигом 13 — настолько распространён, что заслужил собственные рецепты во всех криптоинструментах.

CyberChef для CTF: автоматический перебор сдвигов

CyberChef — первое, что стоит открыть при встрече с Цезарем. Рецепт для brute force ключа шифрования:

  1. Вставьте шифротекст в поле Input
  2. Перетащите операцию ROT13 Brute Force из панели Operations в область Recipe
  3. CyberChef покажет все 25 вариантов расшифровки одновременно
  4. Визуально найдите осмысленный текст — он обычно виден мгновенно

Для расшифровки с конкретным сдвигом используйте операцию ROT13 с параметром Amount. Чтобы расшифровать шифр Цезаря онлайн, помимо CyberChef подойдёт dCode.fr — он автоматически определяет наиболее вероятный сдвиг по частотному профилю. Но на CTF с ограниченным доступом к интернету оффлайн-сборка CyberChef (скачайте zip с GitHub заранее) и Python-скрипт надёжнее.

В Python перебор всех ключей Цезаря укладывается в пару строк. Для каждого k от 0 до 25 примените chr((ord(c) - ord('a') - k) % 26 + ord('a')) к каждому символу шифротекста (предварительно приведённому к нижнему регистру) и выведите результат. Осмысленный вариант заметен сразу.

Когда брутфорс Цезаря не работает

Стандартный перебор 25 сдвигов ломается в нескольких случаях.

Нестандартный алфавит. Задание использует кириллицу (33 буквы вместо 26), цифры или спецсимволы — ROT13 Brute Force в CyberChef не поможет. Нужно адаптировать алфавит в Python-скрипте: задать строку алфавита явно и делать сдвиг по её длине.

ROT47. Вариант Цезаря, работающий с печатными ASCII-символами от кода 33 до 126 (94 символа). Если шифротекст содержит цифры и пунктуацию в хаотичном порядке — попробуйте ROT47 в CyberChef (отдельная операция).

Цезарь как компонент цепочки. Текст сначала кодируется в Base64, затем к результату применяется ROT13. Или наоборот. Тут важно правильно определить порядок операций: ищите характерные признаки Base64 (символы +, /, =) в шифротексте до и после применения ROT.

В реальной безопасности простые ротации символов по-прежнему встречаются «в дикой природе». Техника Obfuscated Files or Information (T1027, MITRE ATT&CK) фиксирует, что вредоносное ПО использует ROT13 и подобные сдвиги для маскировки строк от статического анализа. Не как криптографическую защиту — а как минимальную обфускацию, достаточную для обхода простых сигнатурных детектов. Казалось бы, кто в 2025-м шифрует ROT13? А вот малварь — шифрует, и этого хватает, чтобы проскочить мимо ленивого антивируса.

Шифр Виженера — расшифровка через индекс совпадений

Виженер — полиалфавитный шифр, который применяет разный сдвиг Цезаря к каждой букве открытого текста в зависимости от позиции ключевого слова. Если ключ — KEY, то первая буква сдвигается на 10 (K=10), вторая на 4 (E=4), третья на 24 (Y=24), четвёртая снова на 10, и так далее циклически.

Главное преимущество перед Цезарем: частотный анализ в лоб не работает, потому что одна и та же буква открытого текста шифруется разными символами в зависимости от позиции. IC для шифротекста Виженера падает ниже значения для естественного языка — это и есть диагностический признак полиалфавитного шифра.

Расшифровка шифра Виженера сводится к двум этапам: найти длину ключа, затем восстановить каждый символ ключа отдельно.

Определяем длину ключа: метод Касиски

Метод Касиски основан на простом наблюдении: если одинаковое слово открытого текста попадает на одну и ту же позицию ключа, оно зашифруется одинаково. Повторяющиеся последовательности в шифротексте — следы таких совпадений.

Алгоритм:

  1. Найдите повторяющиеся последовательности длиной 3+ символов в шифротексте
  2. Запишите расстояния между началами повторов
  3. Вычислите НОД всех расстояний — он указывает на длину ключа или её делитель

Пример: последовательность «XYZ» встречается на позициях 5, 17 и 65. Расстояния — 12 и 48. НОД(12, 48) = 12. Длина ключа — делитель числа 12: вероятно 3, 4, 6 или 12. Проверьте каждый вариант через IC подпоследовательностей.

Второй способ — перебор через IC. Для предполагаемой длины n разбейте шифротекст на n подпоследовательностей (каждая n-я буква). При правильной длине каждая подпоследовательность зашифрована одним сдвигом, и её IC будет близок к 0.067. Python-функция для вычисления IC:

def ic(text):
    text = [c for c in text.lower() if c.isalpha()]
    n = len(text)
    if n < 2:
        return 0.0
    freqs = [text.count(chr(i + 97)) for i in range(26)]
    return sum(f * (f - 1) for f in freqs) / (n * (n - 1))

Переберите предполагаемые длины от 2 до 20, для каждой вычислите средний IC по подпоследовательностям. Длина с максимальным средним IC — наиболее вероятная.

В CyberChef встроенного взломщика Виженера с автоматическим определением длины ключа нет — тут он бесполезен. Для полного криптоанализа нужен Python или онлайн-инструменты: dCode.fr имеет автоматический взломщик Виженера, quipqiup хорошо справляется с простыми подстановками.

Частотный анализ криптография: восстанавливаем ключ посимвольно

После определения длины ключа задача распадается на несколько независимых задач взлома Цезаря. Длина ключа 4 — берёте каждую 4-ю букву шифротекста (начиная с 1-й, 2-й, 3-й и 4-й позиции) и для каждой подпоследовательности ищете сдвиг.

Для каждой подпоследовательности:

  1. Подсчитайте частоту каждой буквы
  2. Самая частая буква, вероятно, соответствует «E» (в английском) или «О» (в русском)
  3. Разница между позицией самой частой буквы и позицией «E» / «О» — предполагаемый сдвиг, он же символ ключа

На коротких текстах (менее 100 символов) частотный анализ ненадёжен. Распределение не успевает «устаканиться», и самая частая буква может не соответствовать «E». В таких случаях для каждой позиции попробуйте все 26 сдвигов и визуально оцените результат — осмысленные фрагменты обычно заметны даже при частичном восстановлении.

Лайфхак для CTF. Ключевое слово часто связано с тематикой соревнования. CTF про космос — ключом может быть MARS или ORBIT. Тема — история — попробуйте CIPHER, VIGENERE, SECRET. Проверка тематических слов до полного криптоанализа иногда экономит минуты. На одном CTF я угадал ключ CRYPTO за 10 секунд, пока соседняя команда писала скрипт Касиски.

Атака известным открытым текстом. Если вы знаете, что открытый текст начинается с flag{, вычислите первые символы ключа напрямую: key[i] = (ciphertext[i] - plaintext[i]) mod 26. Пять символов формата флага — это пять символов ключа. Для короткого ключа (3-5 букв) этого часто достаточно для полного восстановления.

Когда метод не работает. Автоключевой Виженер (autokey), где ключ продлевается самим открытым текстом, описанным методом не ломается — каждая позиция использует уникальный сдвиг. На CTF начального и среднего уровня автоключевые варианты встречаются редко, но знать о них стоит, чтобы не тратить час на тупиковый путь.

XOR шифр Python — brute force и восстановление ключа

XOR (исключающее ИЛИ) — самая практически востребованная операция из классической криптографии CTF. В отличие от Цезаря и Виженера, XOR работает не с буквами, а с байтами, что делает его универсальным для шифрования произвольных данных: текста, бинарных файлов, исполняемых файлов. В реальных атаках XOR-шифрование встречается повсеместно: техника Encrypted/Encoded File (T1027.013, MITRE ATT&CK) описывает применение XOR для сокрытия пейлоадов в малвари, а техника Symmetric Cryptography (T1573.001) — использование XOR для шифрования C2-коммуникаций.

Ключевые свойства XOR для криптоанализа: a XOR b = c означает c XOR b = a и c XOR a = b. Шифрование и расшифровка — одна и та же операция. Ещё одно свойство, которое ломает весь шифр: anything XOR 0x00 = anything. Нулевые байты в открытом тексте — прямая утечка ключа: в шифротексте на месте нулевого байта стоит сам байт ключа. Запомните это — на CTF нулевые байты в бинарных файлах встречаются постоянно.

Brute force ключа шифрования: однобайтовый XOR

Однобайтовый XOR — каждый байт открытого текста XOR-ится с одним и тем же байтом ключа. Всего 256 возможных ключей (0x00–0xFF). Перебор тривиален, но нужен способ автоматически отличить осмысленный результат от шума. Стандартный приём — скоринг по частоте «английских» символов:

def score(data):
    return sum(1 for b in data if chr(b) in ' etaoinshrdlu')

ct = bytes.fromhex('1b37373331363f78151b7f2b783431333d')
for k in range(256):
    pt = bytes(b ^ k for b in ct)
    if score(pt) > len(ct) // 3:
        print(f"key=0x{k:02x}: {pt}")

Функция score считает, сколько байт результата попадают в набор самых частотных английских символов (пробел, e, t, a, o, i, n, s, h, r, d, l, u). Порог len(ct) // 3 — если хотя бы треть символов «типичный английский», вариант стоит проверить. Адаптация под русский текст: замените строку частотных символов на ' оеаинтсрвлк'.

В CyberChef для однобайтового XOR используйте операцию XOR Brute Force: она покажет все 256 вариантов, и осмысленный текст обычно бросается в глаза.

XOR cipher key recovery с повторяющимся ключом

Если ключ длиннее одного байта, он циклически повторяется по длине открытого текста. Взлом XOR шифра Python в этом случае следует той же двухэтапной логике, что и Виженер: определить длину ключа, затем восстановить каждый байт.

Определение длины ключа. Вычислите нормализованное расстояние Хэмминга между первым и вторым блоками шифротекста для предполагаемых длин от 2 до 40. Расстояние Хэмминга между двумя байтовыми строками — количество различающихся битов: sum(bin(a ^ b).count('1') for a, b in zip(block1, block2)). Нормализуйте делением на длину блока. Длина с наименьшим нормализованным расстоянием — наиболее вероятная длина ключа.

Восстановление ключа. Разбейте шифротекст на подпоследовательности по длине ключа (каждый i-й байт). Каждая подпоследовательность зашифрована однобайтовым XOR — примените перебор 256 вариантов с автоскорингом к каждой. Собранные байты — полный ключ.

Атака известным открытым текстом — самый быстрый путь. На CTF формат флага (flag{, CTF{, picoCTF{) — это известный фрагмент. XOR-ните начало шифротекста с известным префиксом, и вы получите начало ключа. Если ключ короткий (3-8 байт), этого достаточно для восстановления. Пример: шифротекст начинается с \x0a\x01\x00\x0c\x17, открытый текст — с flag{. Результат XOR первого байта: 0x0a ^ 0x66 = 0x6c — символ 'l'. Продолжайте для остальных байт, и если в ключе проявляется осмысленный паттерн — задача решена.

Ограничение. Если ключ равен по длине открытому тексту и состоит из криптографически случайных байт — это одноразовый блокнот (One-Time Pad), и взлом математически невозможен. На CTF таких задач почти не бывает, но понимание этого предела полезно: если перебор и Хэмминг молчат, а ключ не восстанавливается — возможно, вы смотрите на OTP и нужно искать другой вектор (утечку ключа, ошибку генератора).

CyberChef криптоанализ — цепочки рецептов для CTF crypto задач

CyberChef — основной инструмент для решения крипто задач CTF от начального до продвинутого уровня. Его сила — в возможности строить цепочки рецептов, последовательно применяя операции к данным без написания кода.

Требования к окружению:

  • CyberChef работает в браузере: онлайн-версия на gchq.github.io/CyberChef или оффлайн-сборка (скачайте zip с GitHub для соревнований без интернета)
  • Python 3.8+ для скриптов, когда CyberChef недостаточно (стандартная библиотека, без обязательных внешних зависимостей)
  • ОС: любая с современным браузером и Python

Типовые цепочки рецептов для соревнований:

Многослойное декодирование. From Base64 → From Hex → ROT13 — стандартная CTF-матрёшка. Перетащите три операции в область Recipe в нужном порядке. Если результат содержит формат флага — готово. Нет — меняйте порядок. Операция Magic в CyberChef пытается автоматически определить тип кодировки и предложить декодирование, но на коротких строках часто ошибается — не полагайтесь на неё как на единственный способ.

XOR с известным ключом. Операция XOR принимает ключ в формате Hex, UTF-8 или Base64. Для многобайтового ключа CyberChef автоматически применяет циклическое повторение — удобно для проверки гипотез.

Частотный анализ. Операция Frequency distribution показывает гистограмму распределения символов. Сравните с эталонным профилем: если пики сдвинуты вправо — Цезарь. Распределение почти плоское — Виженер или XOR.

Кодирование C2-трафика. Техники Data Encoding (T1132, MITRE ATT&CK) и Standard Encoding (T1132.001) описывают использование Base64 и Hex для маскировки команд в C2-коммуникациях. CyberChef позволяет воспроизвести и разобрать такие цепочки: From Base64 → XOR с ключом → From Hex — и вот plaintext-команда. Тот же навык, что на CTF, только цена ошибки другая.

Сохраняйте часто используемые цепочки как закладки. URL CyberChef содержит полный рецепт в параметрах — поделитесь ссылкой с командой, и все получат готовую цепочку без объяснений. На командных CTF это экономит минуты, которые решают всё.

Когда CyberChef недостаточен. CyberChef не считает IC, не проводит экзамен Касиски, не перебирает длины ключа Виженера автоматически. Для аналитической работы нужен Python. Оптимальный workflow: быстрая разведка в CyberChef (кодировки, ROT, однобайтовый XOR), затем переход к Python для IC, Касиски и многобайтового XOR. Я обычно держу оба окна рядом — CyberChef слева, терминал справа.

Решение крипто задач CTF — чеклист для соревнований

Шпаргалка — пробегите по ней в первую минуту каждой крипто-задачи:

  1. Скопируйте шифротекст, запишите точную длину
  2. Определите набор символов: hex, Base64, только буквы, бинарный
  3. Прогоните бесключевые декодеры: Base64, Hex, Binary, URL decode — ищите флаг после каждого слоя
  4. Для текста из букв вычислите IC (Python-функция выше)
  5. IC около 0.067 — перебор 25 сдвигов Цезаря (ROT13 Brute Force в CyberChef)
  6. IC около 0.067, но Цезарь не сработал — простая подстановка (частотный анализ) или перестановка
  7. IC около 0.04 — Виженер: длина ключа через Касиски или IC подпоследовательностей, затем частотный анализ каждой позиции
  8. Бинарные данные — XOR Brute Force для однобайтового ключа, затем XOR с известным plaintext (формат флага) для многобайтового
  9. Ведите лог попыток — под давлением таймера легко повторить тупиковый путь

Этот чеклист — отправная точка. На продвинутых соревнованиях HackTheBox и CryptoHack задачи уходят в RSA, AES, эллиптические кривые и решётки. Но фундамент закладывается здесь, на классических шифрах, и навык быстрой идентификации паттернов переносится на любой уровень сложности.

После нескольких сотен решённых крипто-задач на CryptoHack и PicoCTF становится очевидно: подавляющее большинство задач начального и среднего уровня решаются описанными методами. Проблема в том, что участники учат криптографию CTF по академическим учебникам, где теория занимает 90% объёма. Формулы IC и Касиски бесполезны, если вы не можете за секунду отличить Base64 от Hex по виду строки. Навык распознавания паттернов тренируется только практикой — возьмите 20 задач категории General и Classic на CryptoHack и прорешайте подряд. После пятой CyberChef-рецепты начнут складываться рефлекторно, после десятой вы будете определять тип шифра до того, как дочитаете условие.

Новички боятся крипто-категорию, считая её «математической». Математика в классических шифрах — сложение по модулю, XOR, деление с остатком. Настоящая сложность — инженерная: автоматизация перебора, обработка крайних случаев вроде нестандартных алфавитов и бинарных данных, быстрое переключение между CyberChef и Python. Кто умеет написать десятистрочный скрипт для XOR brute force и знает три рецепта CyberChef — тот решает задачи быстрее, чем выпускник с красным дипломом по математике, но без практики в терминале. Потренировавшись «на кошках» в CryptoHack, можно смело двигаться к RSA и AES — там та же логика, просто числа побольше.

🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».

Поделиться

0 комментариев

Пожалуйста, войдите, чтобы оставить комментарий.

Загрузка комментариев...