
Строка Gur synt vf urer — мой первый шифротекст на CTF. Полчаса я долбился в Base64-декодеры и hex-конвертеры, пока кто-то из команды не ткнул в CyberChef операцию ROT13 и не получил The flag is here за две секунды. С тех пор я провожу воркшопы для CTF-новичков и каждый раз вижу одно и то же: crypto-задания пугают. Хотя большинство тасков категории Easy и Medium на PicoCTF и CryptoHack — это классические шифры, которые ломаются за минуты. Надо просто знать, на что смотреть.
Разберём три фундамента crypto CTF: шифр Цезаря, шифр Виженера и XOR-шифрование — от определения типа шифра по виду до готового флага.
Требования к окружению:
pip install xortool (опционально, для многобайтового XOR)| Инструмент | Цезарь | Виженер | XOR | Офлайн | Автовзлом |
|---|---|---|---|---|---|
| CyberChef | Да | Нужен ключ | Да | Да | Частично |
| dcode.fr | Да | Да | Нет | Нет | Да |
| Python-скрипт | Да | Да | Да | Да | Настраиваемый |
| xortool | Нет | Нет | Да | Да | Да |
Первый навык в crypto CTF — не взлом, а диагностика. Правильно определил тип шифра — сэкономил час. Ошибся — будешь перебирать инструменты наугад, как я с тем самым ROT13. Разберём системный подход.
Прежде чем искать ключ, убедитесь, что перед вами вообще шифр, а не кодировка. Кодировки (Base64, hex, URL-encoding) — способ представления данных, «расшифровка» не требует ключа. Шифры — требуют. Авторы CTF-заданий обожают вкладывать одно в другое — Base64 поверх ROT13 поверх hex. Такая матрёшка встречается даже чаще реальных шифров на начальных уровнях (об этом пишут в руководстве InventiveHQ по определению типов шифров в CTF).
Быстрая классификация по набору символов:
A-Za-z0-9+/ и заканчивается на = или == — Base64. Длина кратна 4.0-9 и A-F (или a-f) — hex. Длина чётная.0 и 1 — бинарное представление.A-Z (без цифр, без спецсимволов) — вероятно, классический шифр.Из практики: всегда пробуйте Base64, hex и ROT13 первыми, до любого анализа. В CyberChef кидаете From Base64 или From Hex, смотрите результат. Если на выходе читаемый текст или ещё одна кодировка — продолжаете раскручивать слои. Десять секунд экономят полчаса.
Если перед вами текст из одних латинских букв (возможно, с пробелами), переходите к частотному анализу. Ключевой показатель — индекс совпадений (Index of Coincidence, IC). Он измеряет «неравномерность» распределения букв:
IC = сумма(n_i * (n_i - 1)) / (N * (N - 1))
где n_i — количество вхождений каждой буквы, N — общее число букв.
Эталонные значения IC:
| Значение IC | Что это значит |
|---|---|
| ~0.065-0.067 | Английский текст или моноалфавитный шифр (Цезарь, простая подстановка) |
| ~0.038-0.045 | Полиалфавитный шифр (Виженер) или случайный текст |
| ~0.065, но частоты «не на месте» | Перестановочный шифр (Rail Fence, Columnar) |
Новичку не обязательно считать IC вручную. Вот упрощённое дерево решений для задач Easy-Medium:
Частотный анализ шифра в CyberChef: добавьте операцию Frequency distribution — она построит гистограмму символов. Для Цезаря вы увидите характерный профиль английского языка, просто сдвинутый. Для Виженера профиль будет сглаженным — и это сразу бросается в глаза.
Шифр Цезаря — простейший подстановочный шифр: каждая буква алфавита сдвигается на фиксированное число позиций. Математика элементарная:
где P — номер буквы открытого текста (A=0, B=1, ..., Z=25), K — ключ (величина сдвига), C — номер буквы шифротекста.
Ключевое свойство: ключ — одно число от 0 до 25. Всего 26 вариантов. Брутфорс ключа шифра тривиален даже вручную — тут даже скрипт писать стыдно.
Шифр Цезаря в CTF узнаётся за секунды:
ROT13 — частный случай Цезаря со сдвигом 13. Встречается в CTF чаще прочих вариантов по простой причине: ROT13 — инволюция, повторное применение возвращает исходный текст. Поэтому Gur synt vf urer мгновенно превращается в The flag is here — одна операция ROT13 туда-обратно.
Допустим, в задании вы получили шифротекст:
Wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj
Визуально: только латинские буквы, пробелы сохранены, структура слов похожа на английское предложение. Подозрение — Цезарь.
Шаг 1. Откройте CyberChef, вставьте шифротекст в поле Input.
Шаг 2. Найдите операцию ROT13, добавьте в рецепт. Параметр Amount задаёт величину сдвига. По умолчанию 13 — если повезло, это ответ. Если в Output мусор — меняйте Amount.
Шаг 3. При Amount = 23 (обратный сдвиг на 3, потому что 26 - 3 = 23) получаем: The quick brown fox jumps over the lazy dog. Классический pangram, который часто используют в CTF-заданиях начального уровня.
Альтернатива: на dcode.fr в разделе Caesar Cipher вставьте шифротекст и нажмите «Decrypt» — сервис покажет результат для каждого из 26 сдвигов и подсветит наиболее вероятный.
Ограничение: CyberChef и dcode.fr работают с латиницей A-Z. Если CTF-задание использует кириллический алфавит (32 или 33 буквы), нестандартный набор символов или символы вперемежку с цифрами — стандартные инструменты не справятся, придётся писать скрипт с кастомным алфавитом. Ещё нюанс: если шифротекст совсем короткий (менее 20-30 символов), несколько ключей могут давать осмысленный текст — тут уже выбираете по контексту задания.
Шифр Виженера — полиалфавитный подстановочный шифр, следующая ступень после Цезаря. Вместо одного сдвига для всех букв используется ключевое слово, каждая буква которого задаёт свой сдвиг:
C = (P + K_i) mod 26
где K_i — номер i-й буквы ключа (ключ циклически повторяется по длине текста).
Пример: ключ KEY (K=10, E=4, Y=24), открытый текст THEFLAG:
| Позиция | Открытый текст | Буква ключа | Сдвиг | Шифротекст |
|---|---|---|---|---|
| 1 | T (19) | K (10) | 10 | D (3) |
| 2 | H (7) | E (4) | 4 | L (11) |
| 3 | E (4) | Y (24) | 24 | C (2) |
| 4 | F (5) | K (10) | 10 | P (15) |
| 5 | L (11) | E (4) | 4 | P (15) |
| 6 | A (0) | Y (24) | 24 | Y (24) |
| 7 | G (6) | K (10) | 10 | Q (16) |
Результат: DLCPPYQ. Каждая буква зашифрована разным сдвигом — простой частотный анализ по одной букве уже не катит.
Ключевое отличие от Цезаря: IC шифротекста Виженера существенно ниже — около 0.038-0.045 вместо 0.065-0.067 для моноалфавитных шифров. Частотный профиль в CyberChef (Frequency distribution) будет сглаженным, без характерного «горба» английского языка. Увидели плоскую гистограмму — сразу думайте «Виженер».
Второй признак (описан в руководстве InventiveHQ): повторяющиеся группы символов на регулярных интервалах. Если одно и то же слово открытого текста попадает на ту же позицию ключа, оно шифруется идентично — и в шифротексте появляется повтор.
Ограничение: для коротких шифротекстов (менее 50-100 символов) частотный анализ ненадёжен: IC «плавает», повторяющихся фрагментов может не оказаться. Если шифротекст совсем короткий, методы Касиски и IC не сработают — остаётся словарный перебор ключей через dcode.fr или анализ контекста задания (подсказка в названии, описании).
Взлом Виженера — двухэтапный процесс: сначала длина ключа, потом сам ключ. По сути, вы разбиваете сложную задачу на серию простых — и каждая из них сводится к Цезарю.
Этап 1: длина ключа — метод Касиски. Фридрих Касиски описал этот метод в 1863 году (а Чарльз Бэббидж додумался до него ещё раньше, но не опубликовал — бывает). Суть: ищем в шифротексте повторы из трёх и более символов, измеряем расстояния между ними. НОД расстояний — вероятная длина ключа.
Пример: фрагмент XYZ встречается на позициях 5, 17 и 65. Расстояния: 17 - 5 = 12, 65 - 17 = 48. НОД(12, 48) = 12. Длина ключа — вероятно, делитель числа 12: 3, 4, 6 или 12. Проверяем начиная с наименьшего.
Альтернатива: IC по позициям. Разбиваем шифротекст на группы, предполагая длину ключа n: первая группа — каждый n-й символ, начиная с первого; вторая — начиная со второго, и так далее. Считаем IC каждой группы. Когда n совпадает с реальной длиной ключа, IC каждой группы приближается к 0.065, потому что каждая группа — по сути шифр Цезаря.
Этап 2: ключ — частотный анализ по позициям. Зная длину ключа (допустим, 4), разбиваем шифротекст на 4 группы: каждая 1-я, 5-я, 9-я... буква — первая группа; каждая 2-я, 6-я, 10-я... — вторая. Каждая группа зашифрована одним сдвигом. Самая частая буква в группе, скорее всего, соответствует E (сдвиг = позиция_частой_буквы - 4).
Считать вручную — тоска. Инструменты:
Vigenère Decode требует уже известный ключ — используйте после того, как dcode.fr выдал результат.Порядок действий: (1) вставить шифротекст в dcode.fr, (2) получить вероятный ключ, (3) проверить результат в CyberChef через Vigenère Decode с найденным ключом, (4) забрать флаг.
XOR (исключающее ИЛИ) — побитовая операция, фундамент потоковых шифров. В CTF XOR-шифрование встречается в двух вариантах: с однобайтовым ключом (тривиальный взлом) и с многобайтовым ключом (чуть больше усилий, но тоже ломается).
Принцип: каждый байт открытого текста XOR-ится с байтом ключа. Ключевое свойство — обратимость: A XOR B XOR B = A. Повторное применение XOR с тем же ключом — и есть расшифровка. В отличие от Цезаря и Виженера, XOR работает не с буквами, а с байтами, и шифротекст обычно представлен в hex.
Визуальный признак XOR-шифротекста: строка из символов 0-9, a-f (hex-кодирование). Если hex-строка содержит повторяющиеся пары символов на регулярных интервалах — может указывать на однобайтовый XOR (один ключевой байт даёт одинаковый результат для одинаковых байтов открытого текста).
Если ключ — один байт (0x00 - 0xff), всего 256 вариантов. Проще, чем Цезарь. В CyberChef есть операция XOR Brute Force, которая покажет результат для каждого ключа и подсветит варианты с печатным ASCII.
Но однобайтовый XOR — это тот самый первый скрипт, который стоит написать самому. Он учит думать побайтово, и этот навык пригодится далеко за пределами CTF:
data = bytes.fromhex("4c464b4d5152455857")
for key in range(256):
out = bytes([b ^ key for b in data])
if all(0x20 <= c <= 0x7e for c in out):
print(f"0x{key:02x}: {out.decode()}")
Запускаем — в выводе: 0x2a: flag{xor}. Ключ 0x2a (42 в десятичной — ответ на всё, как обычно) даёт осмысленный текст с характерным форматом флага. Готово.
Что делает скрипт: для каждого возможного ключа (0-255) XOR-ит каждый байт шифротекста и проверяет, попадает ли результат в диапазон печатных ASCII-символов (коды 0x20-0x7e). Большинство ключей дадут мусор. Правильный ключ даёт читаемый текст.
Ограничение: если открытый текст содержит непечатные байты (бинарный файл, изображение), фильтр по printable-символам не поможет. В таких случаях ищите в результате сигнатуры файлов: PK (ZIP-архив), байты 89 50 4e 47 (PNG), 47 49 46 38 (GIF). Если шифротекст короткий (3-5 байт), несколько ключей могут дать «осмысленный» результат — выбирайте по контексту задания.
Когда ключ длиннее одного байта, полный перебор невозможен: для 4-байтового ключа — уже 2^32 (~4 млрд) вариантов. Но многобайтовый XOR ломается по той же логике, что Виженер: сначала длина ключа, потом ключ побайтно. Та же матрёшка, вид сбоку.
Утилита xortool автоматизирует оба этапа:
xortool encrypted.bin # определяем вероятные длины ключа
xortool -l 7 -c 20 encrypted.bin # ищем ключ длиной 7, частый байт = пробел (0x20)
Первая команда анализирует шифротекст и выдаёт вероятные длины ключа на основе расстояний Хэмминга и корреляций между блоками. Вторая — перебирает ключи заданной длины, предполагая, что самый частый байт в открытом тексте — пробел (0x20 в ASCII). Для текстовых файлов на английском это работает в большинстве случаев. Результаты сохраняются в директорию xortool_out — открывайте файлы и ищите тот, где текст читаемый.
Ограничение: для бинарных файлов параметр -c нужно менять. Попробуйте -c 00 (нулевой байт — частый в бинарных данных) или -c ff. Если xortool не справляется — пишите кастомный скрипт: разбиваете шифротекст на блоки по предполагаемой длине ключа и атакуете каждую позицию как однобайтовый XOR.
Оговорка, которую нельзя не сделать: XOR с ключом, равным длине открытого текста и при этом по-настоящему случайным, — это шифр Вернама (one-time pad). Математически неломаемый, что доказал Клод Шеннон в 1945 году. В CTF такие задания встречаются, но в них всегда есть зацепка: часть открытого текста известна (known-plaintext attack), ключ использован повторно, или формат флага предсказуем.
Готовый алгоритм — распечатайте и держите под рукой на соревнованиях:
Frequency distribution в CyberChef. Один сдвинутый пик → Цезарь. Сглаженный профиль → Виженер.ROT13 с разным Amount в CyberChef. Две секунды.Vigenère Decode в CyberChef.XOR Brute Force в CyberChef. Многобайтовый: xortool.Для практики: CryptoHack и PicoCTF содержат десятки crypto-задач от начального до продвинутого уровня — именно на них быстрее всего нарабатывается навык визуального распознавания шифров.
Скажу прямо: главная ошибка новичков в crypto — не нехватка математики, а неумение читать шифротекст как визуальный паттерн. Опытный игрок даже не считает IC — он видит сглаженный частотный профиль и сразу думает «Виженер», видит hex-строку без пробелов и думает «XOR». Этот навык нарабатывается решением 20-30 задач, а не чтением учебников по дискретной математике.
Есть расхожее мнение, что классические шифры в CTF — «детская категория», которую серьёзные игроки проскакивают ради RSA и эллиптических кривых. Я с этим категорически не согласен. Цезарь учит думать модулярной арифметикой. Виженер — разбивать сложную задачу на серию простых подзадач (длина ключа → ключ → открытый текст). XOR — работать с байтами и побитовыми операциями, что напрямую переносится на реальный криптоанализ: атакующие используют XOR для обфускации файлов (T1027 по MITRE ATT&CK), а аналитики применяют ровно те же навыки деобфускации (T1140) для разбора вредоносного ПО. Криптографические сбои стабильно входят в OWASP Top 10 (A02:2021), и умение распознавать слабую криптографию начинается именно с классики.
Кто прыгает сразу к модулярной экспонциации, не поняв, почему Виженер ломается через индекс совпадений, — тот не усвоил сам принцип криптоанализа: находить структуру там, где её, казалось бы, нет. Возьмите любой шифротекст из CryptoHack, прогоните через чеклист выше — и убедитесь сами.
Если хочется отработать эту цепочку на практике — на HackerLab есть лабы с классическими шифрами, где можно набить руку без спешки соревнований.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...