Исследование защиты программы MD5 CrackFAST
Скриншот программы MD5 CrackFAST
Программа MD5 CrackFAST предназначена для взлома хэшей MD5. Взлом выполняется прямым перебором, без использования таблиц, поэтому для больших строк о положительном результате можно сразу забыть. Но и без этого в незарегистрированной версии программы есть принудительное ограничение - восстанавливаются строки не более 3 символов длиной.
По какой-то причине с офсайта были убраны все упоминания об этой программе, ссылок на закачку, соответственно, тоже нет. Удалось найти зеркала на различных FTP, но и там встречаются битые инсталляторы. Вот ссылка на правильный дистрибутив.
Главный исполняемый файл упакован обычным UPX, им же он и распаковывается. Ну или любым другим универсальным распаковщиком, если вдруг вы предпочитаете пользоваться ими. Отправляем распакованный файл в дизассемблер. Файл небольшой, поэтому процесс займет совсем немного времени. После запуска программа в окне лога сообщает, что она не зарегистрирована. При попытке ввести любые левые данные появится сообщение о неправильной регистрации:
Сообщение о неправильной регистрации
Строка сообщения легко обнаруживается в исполняемом файле:
Строка сообщения
Теперь посмотрим в дизассемблерном листинге на условия появления сообщений о правильной или неправильной регистрации:
Code (Assembler) : Убрать нумерацию
- .text:0040C20F call sub_40BA80
- .text:0040C214 mov eax, [esp+6Ch+var_14]
- .text:0040C218 mov [esp+6Ch+var_68], eax ; char *
- .text:0040C21C mov eax, [esp+6Ch+var_18]
- .text:0040C220 mov [esp+6Ch+var_6C], eax ; char *
- ; Проверка введенных данных
- .text:0040C223 call sub_40CAA0
- ; EAX=1, регистрация успешна
- .text:0040C228 cmp eax, 1
- .text:0040C22B mov edi, eax
- .text:0040C22D jz loc_40C3DB
- ; Регистрационные данные введены неправильно
- .text:0040C233 mov eax, [esp+6Ch+var_18]
- .text:0040C237 test eax, eax
- .text:0040C239 jnz loc_40C5C7
- .text:0040C23F mov eax, [esp+6Ch+var_14]
- .text:0040C243 xor esi, esi
- .text:0040C245 mov [esp+6Ch+var_18], esi
- .text:0040C249 test eax, eax
- .text:0040C24B jnz loc_40C5E1
- .text:0040C251 loc_40C251:
- .text:0040C251 xor ebx, ebx
- .text:0040C253 mov [esp+6Ch+var_14], ebx
- .text:0040C257 loc_40C257:
- .text:0040C257 test edi, edi
- .text:0040C259 jnz loc_40C2E7
- .text:0040C25F mov [esp+6Ch+var_6C], offset aInvalidNameKey
- ; "Invalid name/key. Please try again."
- .text:0040C266 call g_strdup_printf
- .text:0040C26B loc_40C26B:
- .text:0040C26B mov ebx, eax
- .text:0040C26D call gtk_window_get_type
- .text:0040C272 mov [esp+6Ch+var_68], eax
- .text:0040C276 mov esi, 2
- .text:0040C27B mov [esp+6Ch+var_6C], ebp
- .text:0040C27E call g_type_check_instance_cast
- .text:0040C283 mov [esp+6Ch+var_6C], eax
- .text:0040C286 cmp edi, 1
- .text:0040C289 mov edx, 1
Code (Assembler) : Убрать нумерацию
- .text:0040CAA0 sub_40CAA0 proc near
- .text:0040CAA0 sub esp, 1Ch
- .text:0040CAA3 mov [esp+1Ch+var_10], ebx
- .text:0040CAA7 mov ebx, [esp+1Ch+arg_0]
- .text:0040CAAB mov [esp+1Ch+var_C], esi
- .text:0040CAAF mov esi, [esp+1Ch+arg_4]
- .text:0040CAB3 test ebx, ebx
- .text:0040CAB5 mov [esp+1Ch+var_8], edi
- .text:0040CAB9 mov [esp+1Ch+var_4], ebp
- .text:0040CABD jz short loc_40CACC
- .text:0040CABF mov [esp+1Ch+var_1C], esi ; char *
- ; Получить длину серийного номера
- .text:0040CAC2 call strlen
- ; Длина должна быть больше 17h, то есть 24 символа и больше
- .text:0040CAC7 cmp eax, 17h
- .text:0040CACA ja short loc_40CAE4
- .text:0040CACC loc_40CACC:
- .text:0040CACC xor edx, edx
- .text:0040CACE loc_40CACE:
- ; Выйти из функции с кодом неправильной регистрации
- .text:0040CACE mov ebx, [esp+1Ch+var_10]
- .text:0040CAD2 mov eax, edx
- .text:0040CAD4 mov esi, [esp+1Ch+var_C]
- .text:0040CAD8 mov edi, [esp+1Ch+var_8]
- .text:0040CADC mov ebp, [esp+1Ch+var_4]
- .text:0040CAE0 add esp, 1Ch
- .text:0040CAE3 retn
- .text:0040CAE4 ; ------------------------------------
- .text:0040CAE4 loc_40CAE4:
- ; Указатель на регистрационное имя
- .text:0040CAE4 mov [esp+1Ch+var_1C], ebx
- ; Проверить наличие имени в "черном списке"
- .text:0040CAE7 call sub_40C800
- .text:0040CAEC test eax, eax
- .text:0040CAEE jnz short loc_40CACC
- .text:0040CAF0 mov [esp+1Ch+var_1C], esi
- .text:0040CAF3 call sub_40C850
- .text:0040CAF8 test eax, eax
- .text:0040CAFA jnz short loc_40CACC
- .text:0040CAFC mov [esp+1Ch+var_1C], 0 ; char *
- .text:0040CB03 mov eax, 6
- .text:0040CB08 mov [esp+1Ch+var_14], eax ; size_t
- .text:0040CB0C lea eax, [esi+11h]
- .text:0040CB0F mov [esp+1Ch+var_18], eax ; char *
- .text:0040CB13 call sub_401A20
- .text:0040CB18 mov [esp+1Ch+var_1C], ebx ; char *
- .text:0040CB1B mov ebp, eax
- .text:0040CB1D call sub_401D70
- .text:0040CB22 mov [esp+1Ch+var_1C], eax ; char *
- .text:0040CB25 mov [esp+1Ch+var_18], ebp ; char *
- .text:0040CB29 call sub_401B20
- .text:0040CB2E test ebp, ebp
- .text:0040CB30 mov edi, eax
- .text:0040CB32 jz short loc_40CB3C
- .text:0040CB34 mov [esp+1Ch+var_1C], ebp ; void *
- .text:0040CB37 call free
- .text:0040CB3C loc_40CB3C:
- .text:0040CB3C mov [esp+1Ch+var_1C], edi ; char *
- .text:0040CB3F call sub_40C9A0
- .text:0040CB44 test edi, edi
- .text:0040CB46 mov ebp, eax
- .text:0040CB48 jz short loc_40CB52
- .text:0040CB4A mov [esp+1Ch+var_1C], edi ; void *
- .text:0040CB4D call free
- .text:0040CB52 loc_40CB52:
- ; Функция сравнения двух строк
- .text:0040CB52 mov [esp+1Ch+var_18], esi ; char *
- .text:0040CB56 mov [esp+1Ch+var_1C], ebp ; char *
- .text:0040CB59 call _stricmp
- .text:0040CB5E test eax, eax
- ; По результатам сравнения установить значение регистра AL
- .text:0040CB60 setz al
- .text:0040CB63 test ebp, ebp
- .text:0040CB65 movzx edi, al
- .text:0040CB68 jz short loc_40CB72
- .text:0040CB6A mov [esp+1Ch+var_1C], ebp ; void *
- .text:0040CB6D call free
- .text:0040CB72 loc_40CB72:
- .text:0040CB72 mov [esp+1Ch+var_1C], ebx
- .text:0040CB75 call sub_40C800
- .text:0040CB7A test eax, eax
- .text:0040CB7C jnz loc_40CACC
- .text:0040CB82 mov [esp+1Ch+var_1C], esi
- .text:0040CB85 call sub_40C850
- .text:0040CB8A test eax, eax
- .text:0040CB8C mov edx, edi
- .text:0040CB8E jz loc_40CACE
- .text:0040CB94 jmp loc_40CACC
- .text:0040CB94 sub_40CAA0 endp
Список забаненных имен
Следующим номером в списке идет название отечественной команды "REVENGE CREW", которая тоже выкладывала свой релиз MD5 CrackFAST. "Черный список" - вполне закономерная реакция аффтара на варез, но никакого практического смысла в нем нет. Я не гордый, не обломлюсь зарегистрировать на другое имя ;)
Снова перезапускам программу, повторяем регистрацию с левым серийником, но на этот раз в качестве регистрационного имени будем использовать "Perm Crack Laboratory". В пошаговом режиме доходим до функции сравнения строк по адресу 0040CB59, и перед ее выполнением в регистрах наблюдаем следующую картину:
Сравнение серийников
Это введенный левый серийник и строка той же длины, с которой он сравнивается. Как вы уже догадались, это и есть правильный серийник. Сохраняем его куда-нибудь в блокнотик, снова перезапускаем программу и в очередной раз открываем окно регистрации. На этот раз в качестве регистрационной пары будет "Perm Crack Laboratory" и "8RBX4T5S8CCYC9DA4890123A".
Программа успешно зарегистрирована
Программа благодарит за покупку (ха-ха три раза), значит регистрационные данные оказались правильными. Для верности перезапустим программу и попробуем восстановить какой-нибудь простенький хэш, например, от строки длиной 4 символа.
Ограничения в программе сняты
В незарегистрированной версии такая строка не прокатила бы, а тут ничего, все нашлось, причем достаточно быстро, меньше чем за секунду. Таким образом защита оказалась нейтрализована. Ну а за "черный список" аффтару спасибо, я посмеялся от души.
Просмотров: 5896 | Комментариев: 7
Метки: исследование защиты, хеши
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(19.08.2015 в 14:29):
Исключения отключаются в настройках отладки. В крайнем случае есть опция Attach к уже работающему процессу. Это как раз касается вопроса необходимости распаковки.
brute
(14.08.2015 в 22:15):
не хочет (у меня:)прога под отладчиками работать - кидает исключения. Можно смотреть в ИДУ и патчить в hex-кодах наугад, потрейсить не получается.
brute
(13.08.2015 в 23:50):
всё получилось! Оказывается, старшие версии UPX не распаковывают младшие! Нужна версия 3.03.
ManHunter
(13.08.2015 в 23:45):
Это старый дистрибутив, в нем меня еще не упомянули :) После этого дистрибутив обновили, версия осталась та же самая, но уже с "черной меткой". В чате есть линк на оба дистрибутива.
==DJ==[ZLO]
(13.08.2015 в 23:41):
Приветствую. Спасибо за статью. Кстати эта версия 1.0 есть 2.10. точнее файл с обновкой для 1.0 (если интересно то вот: http://www.4shared.com/rar/Zld...ackfast.htm) И вней вроде "потерли" тебя. Или я плохо искал ;)
ManHunter
(13.08.2015 в 22:43):
upx -d без вариантов. Больше ничего на файле не навешано.
brute
(13.08.2015 в 22:39):
на двух компах (с ХП и Win7) не получается распаковать этот "обычный" UPX: ни опцией "-d" для UPX 3.91w, ни QuickUnpack_2_3_7, ни RL!dePacker. Автоматическое определение OEP не работает. Оля (и другие отладчики) тоже не трассирует файл. Как его распаковать?!
Добавить комментарий
Заполните форму для добавления комментария