Blog. Just Blog

Исследование защиты программы MD5 CrackFAST

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы MD5 CrackFAST
Скриншот программы MD5 CrackFAST

Программа MD5 CrackFAST предназначена для взлома хэшей MD5. Взлом выполняется прямым перебором, без использования таблиц, поэтому для больших строк о положительном результате можно сразу забыть. Но и без этого в незарегистрированной версии программы есть принудительное ограничение - восстанавливаются строки не более 3 символов длиной.

По какой-то причине с офсайта были убраны все упоминания об этой программе, ссылок на закачку, соответственно, тоже нет. Удалось найти зеркала на различных FTP, но и там встречаются битые инсталляторы. Вот ссылка на правильный дистрибутив.

Главный исполняемый файл упакован обычным UPX, им же он и распаковывается. Ну или любым другим универсальным распаковщиком, если вдруг вы предпочитаете пользоваться ими. Отправляем распакованный файл в дизассемблер. Файл небольшой, поэтому процесс займет совсем немного времени. После запуска программа в окне лога сообщает, что она не зарегистрирована. При попытке ввести любые левые данные появится сообщение о неправильной регистрации:

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

Строка сообщения легко обнаруживается в исполняемом файле:

Строка сообщения
Строка сообщения

Теперь посмотрим в дизассемблерном листинге на условия появления сообщений о правильной или неправильной регистрации:
  1. .text:0040C20F                 call    sub_40BA80
  2. .text:0040C214                 mov     eax, [esp+6Ch+var_14]
  3. .text:0040C218                 mov     [esp+6Ch+var_68], eax ; char *
  4. .text:0040C21C                 mov     eax, [esp+6Ch+var_18]
  5. .text:0040C220                 mov     [esp+6Ch+var_6C], eax ; char *
  6. ; Проверка введенных данных
  7. .text:0040C223                 call    sub_40CAA0
  8. ; EAX=1, регистрация успешна
  9. .text:0040C228                 cmp     eax, 1
  10. .text:0040C22B                 mov     edi, eax
  11. .text:0040C22D                 jz      loc_40C3DB
  12. ; Регистрационные данные введены неправильно
  13. .text:0040C233                 mov     eax, [esp+6Ch+var_18]
  14. .text:0040C237                 test    eax, eax
  15. .text:0040C239                 jnz     loc_40C5C7
  16. .text:0040C23F                 mov     eax, [esp+6Ch+var_14]
  17. .text:0040C243                 xor     esi, esi
  18. .text:0040C245                 mov     [esp+6Ch+var_18], esi
  19. .text:0040C249                 test    eax, eax
  20. .text:0040C24B                 jnz     loc_40C5E1
  21. .text:0040C251 loc_40C251:
  22. .text:0040C251                 xor     ebx, ebx
  23. .text:0040C253                 mov     [esp+6Ch+var_14], ebx
  24. .text:0040C257 loc_40C257:
  25. .text:0040C257                 test    edi, edi
  26. .text:0040C259                 jnz     loc_40C2E7
  27. .text:0040C25F                 mov     [esp+6Ch+var_6C], offset aInvalidNameKey
  28. ; "Invalid name/key. Please try again."
  29. .text:0040C266                 call    g_strdup_printf
  30. .text:0040C26B loc_40C26B:
  31. .text:0040C26B                 mov     ebx, eax
  32. .text:0040C26D                 call    gtk_window_get_type
  33. .text:0040C272                 mov     [esp+6Ch+var_68], eax
  34. .text:0040C276                 mov     esi, 2
  35. .text:0040C27B                 mov     [esp+6Ch+var_6C], ebp
  36. .text:0040C27E                 call    g_type_check_instance_cast
  37. .text:0040C283                 mov     [esp+6Ch+var_6C], eax
  38. .text:0040C286                 cmp     edi, 1
  39. .text:0040C289                 mov     edx, 1
Теперь посмотрим на вызываемую функцию проверки регистрационного имени и серийного номера. Она небольшая, приведу ее текст полностью и прокомментирую самые важные участки кода:
  1. .text:0040CAA0 sub_40CAA0      proc near
  2. .text:0040CAA0                 sub     esp, 1Ch
  3. .text:0040CAA3                 mov     [esp+1Ch+var_10], ebx
  4. .text:0040CAA7                 mov     ebx, [esp+1Ch+arg_0]
  5. .text:0040CAAB                 mov     [esp+1Ch+var_C], esi
  6. .text:0040CAAF                 mov     esi, [esp+1Ch+arg_4]
  7. .text:0040CAB3                 test    ebx, ebx
  8. .text:0040CAB5                 mov     [esp+1Ch+var_8], edi
  9. .text:0040CAB9                 mov     [esp+1Ch+var_4], ebp
  10. .text:0040CABD                 jz      short loc_40CACC
  11. .text:0040CABF                 mov     [esp+1Ch+var_1C], esi ; char *
  12. ; Получить длину серийного номера
  13. .text:0040CAC2                 call    strlen
  14. ; Длина должна быть больше 17h, то есть 24 символа и больше
  15. .text:0040CAC7                 cmp     eax, 17h
  16. .text:0040CACA                 ja      short loc_40CAE4
  17. .text:0040CACC loc_40CACC:
  18. .text:0040CACC                 xor     edx, edx
  19. .text:0040CACE loc_40CACE:
  20. ; Выйти из функции с кодом неправильной регистрации
  21. .text:0040CACE                 mov     ebx, [esp+1Ch+var_10]
  22. .text:0040CAD2                 mov     eax, edx
  23. .text:0040CAD4                 mov     esi, [esp+1Ch+var_C]
  24. .text:0040CAD8                 mov     edi, [esp+1Ch+var_8]
  25. .text:0040CADC                 mov     ebp, [esp+1Ch+var_4]
  26. .text:0040CAE0                 add     esp, 1Ch
  27. .text:0040CAE3                 retn
  28. .text:0040CAE4 ; ------------------------------------
  29. .text:0040CAE4 loc_40CAE4:
  30. ; Указатель на регистрационное имя
  31. .text:0040CAE4                 mov     [esp+1Ch+var_1C], ebx
  32. ; Проверить наличие имени в "черном списке"
  33. .text:0040CAE7                 call    sub_40C800
  34. .text:0040CAEC                 test    eax, eax
  35. .text:0040CAEE                 jnz     short loc_40CACC
  36. .text:0040CAF0                 mov     [esp+1Ch+var_1C], esi
  37. .text:0040CAF3                 call    sub_40C850
  38. .text:0040CAF8                 test    eax, eax
  39. .text:0040CAFA                 jnz     short loc_40CACC
  40. .text:0040CAFC                 mov     [esp+1Ch+var_1C], 0 ; char *
  41. .text:0040CB03                 mov     eax, 6
  42. .text:0040CB08                 mov     [esp+1Ch+var_14], eax ; size_t
  43. .text:0040CB0C                 lea     eax, [esi+11h]
  44. .text:0040CB0F                 mov     [esp+1Ch+var_18], eax ; char *
  45. .text:0040CB13                 call    sub_401A20
  46. .text:0040CB18                 mov     [esp+1Ch+var_1C], ebx ; char *
  47. .text:0040CB1B                 mov     ebp, eax
  48. .text:0040CB1D                 call    sub_401D70
  49. .text:0040CB22                 mov     [esp+1Ch+var_1C], eax ; char *
  50. .text:0040CB25                 mov     [esp+1Ch+var_18], ebp ; char *
  51. .text:0040CB29                 call    sub_401B20
  52. .text:0040CB2E                 test    ebp, ebp
  53. .text:0040CB30                 mov     edi, eax
  54. .text:0040CB32                 jz      short loc_40CB3C
  55. .text:0040CB34                 mov     [esp+1Ch+var_1C], ebp ; void *
  56. .text:0040CB37                 call    free
  57. .text:0040CB3C loc_40CB3C:
  58. .text:0040CB3C                 mov     [esp+1Ch+var_1C], edi ; char *
  59. .text:0040CB3F                 call    sub_40C9A0
  60. .text:0040CB44                 test    edi, edi
  61. .text:0040CB46                 mov     ebp, eax
  62. .text:0040CB48                 jz      short loc_40CB52
  63. .text:0040CB4A                 mov     [esp+1Ch+var_1C], edi ; void *
  64. .text:0040CB4D                 call    free
  65. .text:0040CB52 loc_40CB52:
  66. ; Функция сравнения двух строк
  67. .text:0040CB52                 mov     [esp+1Ch+var_18], esi ; char *
  68. .text:0040CB56                 mov     [esp+1Ch+var_1C], ebp ; char *
  69. .text:0040CB59                 call    _stricmp
  70. .text:0040CB5E                 test    eax, eax
  71. ; По результатам сравнения установить значение регистра AL
  72. .text:0040CB60                 setz    al
  73. .text:0040CB63                 test    ebp, ebp
  74. .text:0040CB65                 movzx   edi, al
  75. .text:0040CB68                 jz      short loc_40CB72
  76. .text:0040CB6A                 mov     [esp+1Ch+var_1C], ebp ; void *
  77. .text:0040CB6D                 call    free
  78. .text:0040CB72 loc_40CB72:
  79. .text:0040CB72                 mov     [esp+1Ch+var_1C], ebx
  80. .text:0040CB75                 call    sub_40C800
  81. .text:0040CB7A                 test    eax, eax
  82. .text:0040CB7C                 jnz     loc_40CACC
  83. .text:0040CB82                 mov     [esp+1Ch+var_1C], esi
  84. .text:0040CB85                 call    sub_40C850
  85. .text:0040CB8A                 test    eax, eax
  86. .text:0040CB8C                 mov     edx, edi
  87. .text:0040CB8E                 jz      loc_40CACE
  88. .text:0040CB94                 jmp     loc_40CACC
  89. .text:0040CB94 sub_40CAA0      endp
Первое, что мы узнаем из функции проверки, это длина серийника - не менее 24 символов. Отлично. Снова перезапустим программу под отладчиком и попробуем зарегистрировать с парой "ManHunter / PCL" и левым серийником подходящей длины, например, что-то типа "123456789012345678901234". В пошаговом режиме проходим проверку длины, но по адресу 0040CAE7 вызывается следующая функция проверки, которой передается регистрационное имя, и по ее результатам отладчик сразу же перебрасывает на выход с кодом неправильной регистрации. В чем же дело? Трассировкой заходим в нее и обнаруживаем сравнение введенного регистрационного имени с внутренним "черным списком". И, как легко убедиться, на первом месте этого списка красуется "ManHunter / PCL". Дело в том, что несколько лет назад я уже релизил эту программу на паблик.

Список забаненных имен
Список забаненных имен

Следующим номером в списке идет название отечественной команды "REVENGE CREW", которая тоже выкладывала свой релиз MD5 CrackFAST. "Черный список" - вполне закономерная реакция аффтара на варез, но никакого практического смысла в нем нет. Я не гордый, не обломлюсь зарегистрировать на другое имя ;)

Снова перезапускам программу, повторяем регистрацию с левым серийником, но на этот раз в качестве регистрационного имени будем использовать "Perm Crack Laboratory". В пошаговом режиме доходим до функции сравнения строк по адресу 0040CB59, и перед ее выполнением в регистрах наблюдаем следующую картину:

Сравнение серийников
Сравнение серийников

Это введенный левый серийник и строка той же длины, с которой он сравнивается. Как вы уже догадались, это и есть правильный серийник. Сохраняем его куда-нибудь в блокнотик, снова перезапускаем программу и в очередной раз открываем окно регистрации. На этот раз в качестве регистрационной пары будет "Perm Crack Laboratory" и "8RBX4T5S8CCYC9DA4890123A".

Программа успешно зарегистрирована
Программа успешно зарегистрирована

Программа благодарит за покупку (ха-ха три раза), значит регистрационные данные оказались правильными. Для верности перезапустим программу и попробуем восстановить какой-нибудь простенький хэш, например, от строки длиной 4 символа.

Ограничения в программе сняты
Ограничения в программе сняты

В незарегистрированной версии такая строка не прокатила бы, а тут ничего, все нашлось, причем достаточно быстро, меньше чем за секунду. Таким образом защита оказалась нейтрализована. Ну а за "черный список" аффтару спасибо, я посмеялся от души.

Поделиться ссылкой ВКонтакте
Просмотров: 6263 | Комментариев: 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 не работает. Оля (и другие отладчики) тоже не трассирует файл. Как его распаковать?!

Добавить комментарий

Заполните форму для добавления комментария
Комментарии отключены администратором сайта
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2026
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.09 сек. / MySQL: 2 (0.0129 сек.) / Память: 4.5 Mb
Наверх