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 символа.

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

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

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 4170 | Комментариев: 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 не работает. Оля (и другие отладчики) тоже не трассирует файл. Как его распаковать?!

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

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2018
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.11 сек. / MySQL: 2 (0.0076 сек.) / Память: 4.75 Mb
Наверх