• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья XOR для самых маленьких || htb the last dance

BazarVokzal

HDD-drive
Пользователь
Регистрация
05.08.2022
Сообщения
36
Реакции
20

Салют! Всех с наступающим 2023 годом! =)​

или с уже наступившим, в зависимости когда вы это читаете)

Предисловие​

Специально для xss.pro <3

Этот материал я решил написать по нескольким причинам: во-первых это будет мой первый опыт в написании статей, во-вторых челендж the last dance хоть и очень простой, но я надеюсь, что эта статья будет кому-то полезной. В основном новичкам, те кто немного разбираются в криптографии вряд-ли откроют для себя что-то новое, тут всё довольно просто. Ещё инфы по этому челенджу довольно мало (хотя вполне достаточно, чтобы решить задачу), и она вся на английском языке. Поэтому решил написать... Если понравится такой формат, то продолжу разбирать всякие задачки, но уже более сложные. Теперь приступим.

Теория​

И начнём с теории. Об операции xor я думаю ничего говорить не надо, если что всё есть в гугле. Я лучше просто отправлю смешных картинок.
pic1.png
pic2.png


Потоковый шифр (stream cipher) - это симметричный шифр, в котором каждый символ открытого текста преобразуется в символ шифрованного текста в зависимости не только от используемого ключа, но и от его расположения в потоке открытого текста. Поточный шифр реализует другой подход к симметричному шифрованию, нежели блочные шифры (взял из википедии). То есть зависит ещё от того, в каком месте открытого текста расположен этот символ, который нужно зашифровать.

Алгоритм chacha20, что используется в данном челлендже потоковый. А ещё он является вариантом семейства salsa20.

Атаки на потоковые шифры​


Потоковые шифры, в которых биты открытого текста (дальше обозначим как A или B) объединяются с потоком битов шифрования (дальше в статье обозначим как C) с помощью операции xor, могут быть очень безопасными при правильном использовании. Однако они уязвимы для атак, если не соблюдаются определенные меры предосторожности, поэтому:
1. НИКОГДА, ЗАПОМНИ, НИКОГДА БЛИН НЕ ИСПОЛЬЗУЙ КЛЮЧ ДВАЖДЫ. ПОВТОРЯЮ, НЕ ШИФРУЙ НИЧЕГО ОДНИМ И ТЕМ ЖЕ КЛЮЧОМ ДВА И БОЛЕЕ РАЗ.
2. Правильная расшифровка данных не должна указывать на подлинность. (здесь нам это не пригодится)

Атака на чела, переиспользовавшего ключ.​


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

E() - так обозначим функцию шифрования, которая принимает в качестве аргумента сообщение и шифрует его.
C() - так обозначим функцию потокового шифра, которая генерирует строку битов. Принимает ключ, как аргумент.

Допустим лох хочет отправить два сообщения A и B одинаковой длины. В таком случае потоковый шифр создаст строку битов C(K) той же длины, что и сообщения. Сразу скажу, что чтобы ксорнуть сообщения разной длины мы просто обрезаем длинное сообщение до размеров меньшего. Ну и так как потоковый шифр создаст одинаковую строку, потому что мамонт использовал один и тот же ключ, мы делаем вывод:

E(A) = A xor C
E(B) = B xor C


Если мы перехватим E(A) и E(B), то сможем узнать E(A) xor E(B).

xor коммутативен и обладает таким свойством, что С xor С = 0 (это называется самоинверсия). Поэтому

E(A) xor E(B) = (A xor C) xor (B xor C) = A xor B xor C xor C = A xor B xor 0 = A xor B


То есть ксор двух зашифрованных сообщений это то же самое, что и ксор двух незашифрованных сообщений. Панятненько? Это всё, что нам нужно знать, чтобы решить задачку.

the last dance​

А вот теперь я настоятельно рекомендую самому пройти это, подумать и получить удовольствие от прохождения. Я, когда решал, честно говоря тупил первое время, потому что
не знал того, что написано сверху. Потом просто начал гуглить, думать и у меня всё получилось. Ну а если ты тоже решил, то продолжение в спойлере:
Качаем архив с заданием и видим два файла: source.py и out.txt. В source.py мы видим, что ключ переиспользуется, а сообщение открыто. В out.txt есть iv (он нам нафиг ненужон), зашифрованное сообщение в формате hex и зашифрованный флаг тоже в формате hex. Зашифрованный флаг и зашифрованное сообщение мы дехексим, а дальше ксорим. Ну и т.к. E(M) xor E(F) = M xor F, то мы можем получить флаг путём (E(M) xor E(F)) xor M. Всё действительно очень просто, если знать теорию. Ну и сам декриптор:
Python:
import codecs 

message = b"Our counter agencies have intercepted your messages and a lot days all of them will be captured"
encrypted_message = codecs.decode("7aa34395a258f5893e3db1822139b8c1f04cfab9d757b9b9cca57e1df33d093f07c7f06e06bb6293676f9060a838ea138b6bc9f20b08afeb73120506e2ce7b9b9dcd9e4a421584cfaba2481132dfbdf4216e98e3facec9ba199ca3a97641e9ca9782868d0222a1d7c0d3119b867edaf2e72e2a6f7d344df39a14edc39cb6f960944ddac2aaef324827c36cba67dcb76b22119b43881a3f1262752990", "hex")
encrypted_flag = codecs.decode("7d8273ceb459e4d4386df4e32e1aecc1aa7aaafda50cb982f6c62623cf6b29693d86b15457aa76ac7e2eef6cf814ae3a8d39c7", "hex")

em_xor_ef = []
for i in range(len(encrypted_flag)):
    em_xor_ef.append(encrypted_message[i] ^ encrypted_flag[i])

flag = []
for i in range(len(em_xor_ef)):
    flag.append(em_xor_ef[i] ^ message[i])

print("".join([chr(i) for i in flag]))

Конец​

Вот такой получилась моя первая статья. Надеюсь, что всё было понятно. Всех с наступающим!!!))):smile10:
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх