Так называемая, Byte Flipping атака на AES в режиме CBC. Сама атака заключается в том, что мы можем изменять байты открытого текста, изменяя байты инициализирующего вектора (или байты шифротекста):
Давайте посмотрим на задание и попробуем понять, как эта атака тут применяется.
Мы можем получить какое-то значение cookie, которое состоит из двух частей:
- Инициализирующий вектор (IV) — первые 16 байт.
- Зашифрованная строка.
Также мы можем передать две эти части в функцию check_admin() для проверки. В этой функции зашифрованная строка расшифровывается с помощью неизвестного нам ключа и переданного нами IV, а дальше проверяется, есть ли в строке “admin=True;”. Если есть, то мы получаем флаг.
Однако мы видим, что в изначальной строке записано “admin=False;” и мы не можем управлять этим текстом. Но мы можем менять либо шифротекст, либо инициализирующий вектор.
Менять шифротекст нет смысла, потому что данные, которые мы хотим изменить, находятся в первом блоке. Поэтому при любом малейшем изменении шифротекста после расшифровки мы получим не изначальную строку, а какую-то полную неразбериху из-за лавинного эффекта.
Значит надо менять инициализирующий вектор. Тут мы вспоминаем про XOR и его свойства. Из схемы расшифровки, приведённой выше, видно, что после процесса расшифровки для получения исходного текста нужно полученные данные ещё проксорить с инициализирующим вектором, значит тут мы можем сделать всё, что нашей душе угодно.
Давайте по порядку. Во-первых, у нас есть инициализирующий вектор:
IV = fff44b182176a547ed2cf05320cd7ac4
Во-вторых, мы знаем, что при ксоре данных, полученных после расшифровки (T) с IV мы получим строку, которая начинается с admin=False;:
IV ^ T = “admin=False;…”
И в-третьих, мы хотим, чтобы эта строка начиналась с admin=True;:
IV ^ T = “admin=True;…”
Для этого сделаем следующее:
- Определим данные, получаемые при расшифровке, для этого проксорим IV c “admin=False;”:
T = IV ^ “admin=False;” = 9e9026714f4be326815f956841a917ad
2. Теперь изменим IV:
IV = T ^ “admin=True;” = fff44b182176b754f43aae0925c47ec3
Вот и всё, теперь надо только отправить серверу шифротекст с этим инициализирующим вектором, чтобы получить флаг: