c1ph3r: writeup
Сслылка на задачу http://f8tasks.ru/challenges#c1ph3r-32
c1ph3r
| Category | Crypto |
| Difficulty | Easy |
| Cipher | Vigenere |
| Key | cphr |
| Flag | flag{v1g1n3r_c1ph3r} |
Recon
Единственный артефакт задачи:
hahx{x1v1u3i_e1eo3i}
Структура сразу указывает на CTF-флаг: фигурные скобки, буквенно-цифровое содержимое, _ как разделитель. Прямого смысла в буквах нет — применено шифрование.
Гипотезы первого уровня:
- ROT13 / Caesar — не дают осмысленного результата
- Simple substitution — нет стандартных частотных паттернов
- Vigenere — подозрение усиливается после анализа префикса
Known-plaintext entry point: в CTF флаг почти всегда начинается с flag{. Префикс шифротекста — hahx{ — ровно 4 буквы + {. Сопоставление с известным открытым текстом flag{ даёт 4 пары (cipher, plain), достаточных для восстановления ключа.
Known-Plaintext Attack: восстановление ключа
При шифровании Виженером каждая буква сдвигается на позицию соответствующей буквы ключа:
cipher_pos = (plain_pos + shift) mod 26
Из этого напрямую следует формула восстановления ключа:
shift = (cipher_pos - plain_pos) mod 26
key_char = chr(shift + ord('a'))
Пример ручного расчёта для первой буквы:
cipher: 'h' → позиция 7 (a=0, b=1, ... h=7)
plain: 'f' → позиция 5
shift = (7 - 5) mod 26 = 2
key_char = chr(2 + ord('a')) = 'c'
То же самое для всех четырёх букв префикса:
| # | Cipher | Позиция | Plain | Позиция | Сдвиг | Key char |
|---|---|---|---|---|---|---|
| 0 | h | 7 | f | 5 | 2 | c |
| 1 | a | 0 | l | 11 | 15 | p |
| 2 | h | 7 | a | 0 | 7 | h |
| 3 | x | 23 | g | 6 | 17 | r |
Ключ: cphr
Ключ циклически повторяется на всю длину строки. Цифры (1, 3), {, } и _ шифрованию не подвергались — в шифротексте они стоят на своих исходных позициях.
Decryption
Расшифровка hahx{x1v1u3i_e1eo3i} ключом cphr:
Cipher: h a h x { x 1 v 1 u 3 i _ e 1 e o 3 i }
Key: c p h r c p h r c p h c
Plain: f l a g { v 1 i 1 g 3 r _ c 1 p h 3 r }
Результат: flag{v1g1n3r_c1ph3r}
Флаг самодокументируемый — содержимое прямо называет применённый шифр.
Automation
#!/usr/bin/env python3
FLAG = "hahx{x1v1u3i_e1eo3i}"
KEY = "cphr"
def vigenere_decrypt(value: str, key: str) -> str:
result = []
key_index = 0
for char in value:
if char.isalpha():
shift = ord(key[key_index % len(key)]) - ord("a")
base = ord("a") if char.islower() else ord("A")
decoded = chr((ord(char) - base - shift) % 26 + base)
result.append(decoded)
key_index += 1
else:
result.append(char)
return "".join(result)
def main() -> None:
print(vigenere_decrypt(FLAG, KEY))
if __name__ == "__main__":
main()
python3 solve.py
# flag{v1g1n3r_c1ph3r}
Key Takeaways
Анализ паттернов. CTF-флаги следуют стандартному формату
flag{...}. Умение читать структуру шифротекста и сопоставлять её с известным шаблоном — первый шаг к любому криптоанализу.Работа с ASCII. Шифр Виженера реализован через арифметику кодовых позиций символов (
ord/chr). Понимание того, что буква — это число, критично для работы с текстовыми шифрами в коде.Автоматизация дешифровки. Ручной расчёт по таблице и скрипт на Python дают идентичный результат. Автоматизация необходима там, где ключ длиннее четырёх символов или шифротекст занимает тысячи строк.
