R0 CREW

CrackMe #05

Всем привет.
Сейчас разбираю один интересный CrackMe, хочу поделиться и спросить совет.

Из-за большого числа строк кода я всячески пытался обойти анализ криптоалгоритма.
Я генерировал пароль и перебирал для него логины (так как длина пароля 32 байта, а длина логина начинается от 3-х байт). Нашёл правильную ветку и пытался раскрутить всё обратно. Ничего не помогло и я понял, что анализа алгоритма не избежать :slight_smile:

С ним то и возникает проблема. На первый взгляд он похож на RC5/RC6, из-за характерных констант. Но при детальном разборе выяснилось, что он использует только одну константу и больше похож на TEA (<<4 и >>5). Разобрал 1 раунд, думал посчитаю количество раундов и дело с концом. Но после 11 раунда в алгоритме добавились новые строки, чего я никак не ожидал.

Вопрос такой, возможно ли как-то ускорить анализ большого числа строк или нужно смотреть всё полностью дабы чего не пропустить.

Посмотрел программку, где-то полдня понадобилось на решение. Мегатонны кода, естественно, не разбирал, в них можно погрязнуть на месяцы. Пара подсказок:

  1. Посмотрите процедуры, благо их там совсем немного. Внутрь не лезьте, просто попробуйте догадаться по входу и выходу, что в них происходит. На самом деле это несложно.
  2. Поищите переходы на неудачную проверку. Там их всего 4, по результатам 4-х сравнений. Увидите, что с чем сравнивается, и дальше будет понятно, что надо зашифровать, чтобы после расшифровки проверка сошлась.

Спасибо за подсказки. Но ведь без разбора алгоритма всё равно не обойтись, так как последние 4 проверки сравнивают зашифрованные данные.

Если использован один из “стандартных” алгоритмов без модификации, то при известном ключе можно опознать его по валидным данным вход+выход.

Значения констант подсказывают, в какую сторону смотреть. Автор ведь не имел целью заставить разбирать 5 МБ замусоренного кода, он оставил путь попроще.

Разобрал алгоритм дешифровки, получилось так:

B = B - S[2r + 3]
A = A - S[2r + 2]

for i = r downto 1 do
{
(A, B, C, D) = (C, D, A, B)
u = [C*(2C+1)<<5] OR [C*(2C+1)>>1B]
t = [D*(2D+1)<<5] OR [D*(2D+1)>>1B]
B = [(B - S[2i+1])>>t] OR [(B - S[2i+1])<<(20 - t)] XOR u
A = [(A - S[2i])>>u] OR [(A - S[2i])<<(20 - u)] XOR t
}

C = C - S[1]
D = D - S[0]

где А, B, C, D - шифрованные текст разбитый на блоки по 32 бита, r - количество раундов = 20, S[0, … , 2r + 3] - 32-хбитные ключи для каждого раунда.

Это больше похоже на модифицированный RC6 или есть такой стандартный алгоритм?