Blog. Just Blog

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

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

В поисках очередных пациентов для PHPiD наткнулся на софтину под названием PHP Locker. "Мощная программа для шифрования ваших PHP-скриптов. Она превращает исходный код в нечто трудное для понимания и реверсивного исследования. В отличие от других систем шифрования, не требует установки дополнительных модулей на серверную часть". Это мнение о программе самих разработчиков, так что "мопед не мой, я просто разместил объяву" :) Там же на офсайте вывешен целый иконостас орденов и медалей, коими наградили этот продукт различные популярные софтообозревательные сайты. И да, к слову, цена за персональную лицензию 180$, а за корпоративную аж все 2800$.

Посмотрим на это чудо повнимательнее. Скачиваем дистрибутив, устанавливаем. Предварительным анализом файла определяем, что исполняемый файл ничем не упакован и написан на Delphi. На попытку ввода неправильных регистрационных данных программа реагирует сообщением "The wrong username or registration code!" Поиск строки в файле показывает, что она находится в секции ресурсов. Но и просмотр этой секции особо не поможет, потому что файл написан на Delphi, зато мы можем узнать название формы, в которой открывается сообщение об ошибке - TfrmError.

Форма в ресурсах
Форма в ресурсах

Для борьбы с Delphi на помощь приходит другой инструмент - декомпилятор для Delphi под названием DeDe. Эта программа написана уже давно, но она до сих пор помогает в исследованиях. Загоняем в нее исполняемый файл, ждем когда закончится декомпиляция, сохраняем проект. В папке с проектом поиском по файлам по строке "TfrmError" находится вот такой кусок кода:
  1. * Reference to TfrmError instance
  2. |
  3. 004F6C4D   A150F65100             mov     eax, dword ptr [51F650]
  4. 004F6C52   8B00                   mov     eax, [eax]
  5.  
  6. * Reference to: Forms.TCustomForm.Show(TCustomForm);
  7. |
  8. 004F6C54   E8E7A7F9FF             call    00491440
  9. 004F6C59   33C0                   xor     eax, eax
  10. 004F6C5B   5A                     pop     edx
  11. 004F6C5C   59                     pop     ecx
  12. 004F6C5D   59                     pop     ecx
  13. 004F6C5E   648910                 mov     fs:[eax], edx
Конструкция Forms.TCustomForm.Show как раз и отвечает за открытие окна с сообщением о неправильной регистрации. Отлично, теперь мы знаем, в каком месте файла по какому адресу происходит интересующее нас действие. От декомпилятора переходим к дизассемблеру, смотрим в нем условия срабатывания этой ветки алгоритма. Можно, конечно, это сделать и в листинге декомпилятора, но в дизассемблере как-то привычнее.
  1. ...
  2. ; Вызвать процедуру проверки регистрации
  3. CODE:004F6BD3                 call    sub_510B10
  4. ; Если она вернула AL=0, то программа незарегистрирована
  5. CODE:004F6BD8                 test    al, al
  6. CODE:004F6BDA                 jz      short loc_4F6C4D
  7. ; Сохранить регистрационные данные
  8. CODE:004F6BDC                 mov     eax, ds:off_51F6A0
  9. CODE:004F6BE1                 mov     eax, [eax]
  10. CODE:004F6BE3                 mov     ecx, [eax+314h]
  11. CODE:004F6BE9                 mov     dl, 1
  12. CODE:004F6BEB                 mov     eax, off_43E728
  13. CODE:004F6BF0                 call    sub_43E7D8
  14. CODE:004F6BF5                 mov     ebx, eax
  15. CODE:004F6BF7                 mov     eax, [ebp+var_8]
  16. CODE:004F6BFA                 push    eax
  17. CODE:004F6BFB                 mov     ecx, offset aUsername_0 ; "username"
  18. CODE:004F6C00                 mov     edx, offset aUser_info ; "user_info"
  19. CODE:004F6C05                 mov     eax, ebx
  20. CODE:004F6C07                 mov     edi, [eax]
  21. CODE:004F6C09                 call    dword ptr [edi+4]
  22. CODE:004F6C0C                 mov     eax, [ebp+var_C]
  23. CODE:004F6C0F                 push    eax
  24. CODE:004F6C10                 mov     ecx, offset aRegcode ; "regcode"
  25. CODE:004F6C15                 mov     edx, offset aUser_info ; "user_info"
  26. CODE:004F6C1A                 mov     eax, ebx
  27. CODE:004F6C1C                 mov     edi, [eax]
  28. CODE:004F6C1E                 call    dword ptr [edi+4]
  29. CODE:004F6C21                 mov     eax, ebx
  30. CODE:004F6C23                 call    sub_403DD4
  31. CODE:004F6C28                 mov     eax, ds:off_51F6A0
  32. CODE:004F6C2D                 mov     eax, [eax]
  33. CODE:004F6C2F                 mov     ecx, [ebp+var_C]
  34. CODE:004F6C32                 mov     edx, [ebp+var_8]
  35. CODE:004F6C35                 call    sub_511AC0
  36. ; Вывести сообщение об удачной регистрации
  37. CODE:004F6C3A                 mov     eax, offset aThankYouForReg
  38. ; "Thank you for registering PHP Locker,pl"...
  39. CODE:004F6C3F                 call    sub_43871C
  40. CODE:004F6C44                 mov     eax, esi
  41. CODE:004F6C46                 call    sub_491438
  42. CODE:004F6C4B                 jmp     short loc_4F6C59
  43. CODE:004F6C4D ; -------------------------------------------
  44. ; Триальная ветка алгоритма, сообщение о неуспешной регистрации
  45. CODE:004F6C4D loc_4F6C4D:
  46. ...
По адресу 004F6BD3 происходит вызов процедуры проверки введенного ключа. Криптоанализаторы показывают наличие в ней Blowfish, бороться с этим криптоалгоритмом у меня нет никакого желания. Поэтому просто пропатчим процедуру по адресу 00510B10, записав в ее начало команды MOV AL,1; RET. После этого программа из триального режима переходит в зарегистрированный, снимаются все ограничения, в окне регистрации кнопка Register становится неактивной.

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

Последний штрих: открываем в Блокноте файл registration.ini, который находится в папке с программой, и вписываем в него нужное регистрационное имя и какой-нибудь серийный номер. Теперь это имя будет отображаться в заголовке окна.

[user_info]
username="Manunter / PCL"
regcode="Have a Nice Day!"
serial=

C программой закончили, теперь посмотрим на результаты ее творчества, заодно проверим, не осталось ли в ней каких-нибудь еще скрытых триальных ограничений. Закодируем какой-нибудь простейший скрипт в несколько строчек, получим примерно такой текст:

<? $d='t';$h='hudgu';$b = str_replace($h,$d,'eJw1jb0KgzAYAF/FIRBDXSy1COK
ggkPhudguUGhudgu/bBeJ8VOoP4lGrfr0FaHbHRwcqm2cYgvlNgY68++Ki2Irsu+SDkRFGag
o11ChudguYTghudgun0jK8d674by1oS79958n17/QveCBvvnEvKIV87UxvJJDeyuN3YsHUU/
N+Pw0Y8cZHs4QYmLBSCu1WIaG8Vp0IKWaUgnHQ5IB49l6Xwgh1g+UGTlD');eval(gzuncom
press(base64_decode($b))); ?>

Для распаковки этого чуда нам понадобится обычный Блокнот и настроенный web-сервер, или какая-нибудь IDE для разработки на PHP со своим встроенным сервером. Подразумевается, что с самим языком PHP вы уже знакомы. Запускаем секундомер. Первый шаг: в Блокноте заменяем слово eval на echo и запускаем скрипт на выполнение. Получаем на экране что-то типа:

$m='b';$f='eayow';$z = str_replace($f,$m,'eJzjSssvUtBQyeayowQ1sFZQyeayow
QxBFPa2poK1eayowxcCgqpyRn5CkoeqTk5+YoKSta8XLW8XAAuVAuQ');eval(gzuncompre
ss(base64_decode($z)));

Копируем полученный текст обратно в Блокнотик, дополняем открывающими и закрывающими PHP-тегами, заменяем eval на echo, сохраняем и снова запускаем. На этот раз у нас получается полностью открытый исходный код скрипта. В моем случае это был вот такой коротенький пример:
  1. for ($i=0$i<10$i++) {
  2.   echo "Hello! ";
  3. }
Как видите, за два несложных шага скрипт расшифровался в точности до исходного кода, со всеми переносами строк и отступами, имена переменных тоже не тронуты. Останавливаем секундомер. Затраченное время на расшифровку - меньше минуты. Вот мне и непонятно, как можно требовать за подобную "защиту" такие деньги? И как могут доверять аффтары свои ненаглядные скрипты этой поделке почти за три килобакса, если защита снимается в обычном Блокноте? Грустно :)

Поделиться ссылкой ВКонтакте
Просмотров: 5633 | Комментариев: 15

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Андрей (04.10.2010 в 19:25):
У меня к сожалению не получается снять защиту с программы. (((
bodrox (29.06.2010 в 22:01):
каков уровень обозревателей из софтверных сайтов, которые высоко оценили эту галиматью?
64-ядерный процессор (24.05.2010 в 23:41):
ManHunter, я вот всегда тестирую "многообещающий" софт на виртуальной машине - во многих случаях все изъяны выявляются. Да и в некоторых случаях потом приходиться ОС на виртуальной машине переустанавливать.
ManHunter (24.05.2010 в 20:12):
Цель та же самая, что и у PE-пакеров и протов. Некоторые [ч|м]удаки пытаются заработать, продавая свои скрипты. Еще некоторые [м|ч]удаки шифруют всякие шеллы и трояны, но это малая часть. Основная целевая аудитория подобных поделок - шароварщики.
Isaev (24.05.2010 в 19:56):
ManHunter ещё вопросик: Для чего шифровать php скрипт вообще если можно просто ограничить доступ к нему и его и так никто не увидит?
Или иногда это необходимо?
64-ядерный процессор (22.05.2010 в 22:13):
Вот поэтому я никогда таким софтом не пользуюсь. Зачем? Ведь то что можно зашифровать через общедоступный алгоритм, то можно легко и расшифровать.
ManHunter (22.05.2010 в 21:39):
Isaev, про _некоторые_ возможные грабли ниже в камментах написал MaxIkar, я тоже добавил. После обработки триальной версией скрипты получаются НЕ работоспособны, из-за принудительного добавления в код ихней дебильной ссылки. Плюс еще грабля: теоретически не везде на хостингах есть поддержка gzip, а тут эта функция дефолтная и не отключается. Ну а о "стойкости" защиты я все написал в статье.
Isaev (22.05.2010 в 17:28):
Хостинг крутой для столь дорогой утильки :)))) 4.4 кб/с отдача!

На счёт патча я промолчу :) Хотя снова слабенькое RSA вроде и можно было бы сделать прикольный пример с криптокейгеном, хотя внимательно не смотрел... Где ты находишь такие идеальные поделки для новичков?
А может она этого и не заслуживает... Столько понавешать всего и сделать слабое место с патчем в 1 байт! Хмм... Стоит ли пользоваться такой поделкой?

А как защита с точки зрения программиста php?
И какие последствия для исполняемого скрипта? (в смысле скорости исполнения или может дополнительные ограничения для используемого хостинга)

А дочитал на счёт защиты, класс :))))))))))
MaxIkar (21.05.2010 в 12:57):
ManHunter, ага, я так и понял по нотису на их сайте.
Мол, это не баг, это фича)
А что еще могут сделать такие мега-кодеры? Защита под стать информации о продукте в шароварной версии.
ManHunter (21.05.2010 в 12:39):
Это еще фигня :) В триальной версии в каждый скрипт записывается html-ссылка на их сайт. И эта фича "документирована" в программе, типа "если у вас вывалится ошибка что заголовки уже отосланы и все такое, то это типа так у нас работает триалка". На скриншоте как раз виден этот нотис. И если бы вдруг у меня даже возникло желание и возможность купить эту поделку, то после таких закидонов это желание точно бы пропало.

У нормальных шароварщиков в подобном софте ограничение по количеству скриптов, по времени работы, по доступным функциям, а тут решили выебнуться.
MaxIkar (21.05.2010 в 12:34):
Эх... Как же хорошо это решение подходит для высоконагруженных сайтов!
А кешировщики опкодов вообще тащатся от eval'a.
Молчу про base64_decode, gzip и str_replace по всему исходнику...
аффтары забыли это все обернуть в
ob_start();
echo gzuncompress(base64_decode($z));
$code = ob_get_clean();
eval($code);

А еще можно на каждую страничку вызывать SOAP-сервис с сайта производителя софтины, дабы проверить, что ее точно не сперли.
diwriter (21.05.2010 в 06:58):
Спасибо, очень наглядно, но и, правда, грустно.
user (20.05.2010 в 14:28):
Программинг профанируется(((
ManHunter (20.05.2010 в 13:14):
Увы, ни к одному из трех определений эта поделка не относится.
user (20.05.2010 в 13:12):
Цена внушает... кому- то, возможно, даже веру в то, что перед ним качественный продукт. Качественный, надёжный, неприступный.

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

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

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