Disclaimer
Всё, что вы здесь увидите, может повлиять на ваши психические способности, не применяйте на себе описанное в статье, так как это может причинить вам вред. Автор не несёт никакой ответственности за точность, полноту или качество предоставленной информации.
Что это?
TurboConf — это «шароварная» программа, расширяющая возможности конфигуратора 1с
Первоначальный анализ
После скачивания получаем zip-архив. Распаковываем. Видим несколько exe-файлов. Посмотрим на главное приложение с фирменной иконкой. Если его открыть в простом HEX-редакторе, например, HxD, то легко можно понять, что оно представляет собой сборку под .Net Framework, т. к. видны имена классов стандартной библиотеки .Net:
Далее берем декомпилятор DotPeek и смотрим данную сборку в нем. Байт-код не обфусцирован, поэтому декомпилятор выдает почти оригинальные исходники:
Несложно здесь понять, что далее работа утилиты перемещается на приложение «TurboConf.Application.exe». Открываем его в DotPeek. Это тоже сборка с IL-кодом. Но в отличие от предыдущей сборки, часть методов здесь обфусцирована, скорее всего, с помощью Confuser. Изучая код, становится понятно, что основная логика работы находится в «TurboConf.Service.dll» — и это тоже сборка под .Net, и тоже часть методов обфусцирована. Отлично, этим еще интереснее!
Исследование защиты
При просмотре структуры сборки, в пространстве имен «TurboConf.Service.Utils» обнаруживаем класс «Crypto», а в нем метод с говорящим названием «DecryptStringAES»:
Хотя он и обфусцирован, из него в дальнейшем нетрудно восстановить логику работы. Найдем использование данного метода (Shift+F12):
И сразу же успех! Данный метод вызывается 2 раза в конструкторе класса, отвечающего за лицензирование!
Восстановление исходного кода
Обфускатор зашифровал все строки и поместил их в один ресурсный файл. Получить данный файл можно с помощью майкрософтовского декомпилятора «ildasm.exe», входящего в SDK Windows (и не только):
А вместо оригинальных строк обфускатор подставляет в код следующую конструкцию: «<Module>.c(рандомная_арифмитическая_операция)», где результат арифметической операции представляет некое число, на основании которого высчитывается смещение для ресурсного файла, из которого затем достаются зашифрованные данные и восстанавливается исходная строка. Чтобы облегчить себе задачу расшифровки строк создадим новый проект в Visual Studio, перенесем, немного доработав, класс «<Module>» и ресурсный файл «resource». Таким образом сможем понимать, что в окне DotPeek следующий код
<Module>.c(sizeof (float) - 47, sizeof (int) + 6429, (int) ((uint) k >> 16) >= 0 ? sizeof (int) + 200 : System.Type.EmptyTypes.Length - 1805516213)
это есть строка «User:»
Не спеша восстанавливаем всю логику класса лицензирования. На этом можно было бы остановиться, т. е. сделать простой битхак в исследуемом файле «TurboConf.Service.dll», заменив проверку равенства наличия лицензии на неравенство, но так не интересно. Идем далее…
Принцип защиты
Для получения лицензии необходим уникальный идентификатор оборудования, на котором запускается программа. Данный HardwareID генерируется на основании идентификатора процессора и серийного номера тома диска «Ц». Для получения триальной лицензии программа делает GET запрос c идентификатором оборудования на домен «netlenka1c.ru». И в ответ приходит ключ с указанием даты окончания пробного периода, подписанный … цифровой подписью. В основе защиты программы применяется асимметричный алгоритм RSA с 1024-битным ключом. На этом этапе я понял, что без модификации оригинального файла не обойтись, т. к. получить закрытый ключ практически невозможно (в файлах утилиты он отсутствует).
Мини центр лицензирования
Поняв, как устроена защита, решил сделать себя небольшим божком для данной программы, чтобы самому иметь возможность генерировать ключи. Для этого был разработан патчер, который сначала заменяет открытый ключ цифровой подписи в сборке на само сгенерированный открытый ключ:
А затем разработанная утилита по генерации ключей (как временных на указанный срок действия, так и бессрочных), добавляет цифровую подпись в ключ на основании само сгенерированного закрытого ключа:
В итоге имеем работоспособную зарегистрированную программу с полным функционалом:
Мораль
Обфускация – достаточно неплохой метод запутать реверсера, но это лишь вопрос времени.
P.S.
В статье специально есть недосказанности и пробелы в повествовании, чтобы не подставлять автора программы. Никаких исходников и рабочих программ не прилагается и не будет. Уважайте чужой труд, особенно коллег по «цеху»!
Всем дочитавшим пост – благодарность за внимание!
Комментарии (16)
nata16k8
14.12.2019 22:01Использую для выставления зачетов студентам программу MyTestXPro. Для студентов создаю один *.exe файл теста, при запуске которого студенту предъявляется 20-30 вопросов из 400-500 общего числа заданий. Причем сам *.exe файл автором программы зашифрован.
Однако при запуске *.exe файла ВСЕ задания с ответами расшифровываются в памяти, откуда их студенты успешно копируют и легко проходят тест.
Не порекомендуете что-нибудь похожее на обфускатор для решения этой проблемы.LibrarianOok
14.12.2019 22:36Думается, не обфускатор нужен, а другой подход. Например, клиент-сервер.
nata16k8
15.12.2019 00:09Поставлена задача выдавать тесты студентам на дом, для дистанционного обучения. После прохождения теста студенты присылали зашифрованные файлы с оценками. Так было некоторое время до вскрытия программы.
LibrarianOok
15.12.2019 06:15Поставлена задача выдавать тесты студентам на дом, для дистанционного обучения.
Ну, как видно из практики, такой подход оказался не лучшим.
Ahen
15.12.2019 00:01Написать разработчику о проблеме. Там у них на форуме 200+ страниц обсуждения и разработчик активен.
nata16k8
15.12.2019 00:11С разработчиком переписывался. Предложил не расшифровывать ВСЕ задания и ответы к ним в памяти. Но пока решения нет. Разработчик использует одну из стандартных защит программы.
Rigidus
15.12.2019 03:07Спасибо автору за статью, разбор вполне качественный.
Предлагаю составлять задание не как тест+ответ, а как конечный автомат. Это дает возможность сделать задания со сложной логикой ответа.
Обычный тест — линеен, на вопрос выбирается один из вариантов ответа, иногда можно выбрать несколько одновременно. Это нельзя назвать хорошим подходом.
Древовидный тест позволял бы открывать дополнительные варианты по мере продвижения вглубь дерева, и выполнять «поиск в возвратами».
Еще более общий конечно-автоматный тест позволяет двигаться от одного состояния к другому и превращать тест в квест по уточнению ответа, с начислением баллов за каждый переход в правильном направлении (или штрафом за неправильные).
При этом каждый переход может расшифровывать свое следующее состояние и для того чтобы извлечь все ответы теста (или хотя бы правильные) придется написать виртуальную машину, которая будет снапшотить состояние на каждом шаге и делать все возможные переходы.
Если сделать процедуру расшифровывания достаточно длительной (увеличением размера ключа, например), и с зависимостью от предыдущих шагов, то расшифровывать весь пакет заданий студент будет гораздо дольше, чем если бы готовился обычным способом. Подобрав время и алгоритмы мы могли бы сделать расшифровку более длительной, чем время всех студентов потраченное на обычную подготовку, что делает атаку нецелесообразной. И это я еще не посчитал время и требуемую квалификацию на написание расшифрощика, который будет обходить конечные автоматы.
Taraflex
15.12.2019 03:43Можно попробовать enigmaprotector.com/en/about.html (не реклама)
nata16k8
15.12.2019 16:23Спасибо всем, кто откликнулся.
1. Заметьте, автор-хакер не откликнулся.
2. NeoLab. Стал противником «сообразительных» не в той области студентов.
3. Rigidus. Если бы Вы написали такую оболочку для составления тестов, то я купил бы ее, а не MyTestXPro.
4. Пока выхожу из положения генерацией из оболочки MyTestXPro «бумажных» вариантов теста, которые раздаю студентам: каждому свой вариант теста. Недостаток — проверка ответов вручную.capitannemo
15.12.2019 20:43Как вариант — запихните его на любой VDS.
При аренде с почасовой оплатой затраты небольшие, вплоть до нулевых, на амазоне или у китайцев например.
SerVerOnLine Автор
15.12.2019 21:39Простите, но без погружения в тему данной программы трудно что-либо дельное посоветовать… Можно предлагать различные варианты вплоть до разработки своего защищенного решения, но это равносильно вождению вилами по воде.
Sergani
15.12.2019 21:40Хороший пример бесполезности .Net для написания шароварных программ. Все может быть легко взломано и украдено.
SerVerOnLine Автор
15.12.2019 21:42Скажу даже больше, что всё локальное может быть взломано и украдено, даже если оно будет написано на асме или плюсах с применением своей виртуальной машины. Это вечное противостояние защиты и атаки.
sheknitrtch
Насколько Я знаю, AES — это алгоритм симметричного шифрования. Может всё-таки где-то в исходниках хранится ключ?
SerVerOnLine Автор
ОписАлся в статье. Используется именно RSA с 1024 битным ключом. А AES используется только для установки пароля на свой лицензионный ключ в программе, если используешь её на чужом компьютере (при доработке конфигураций у клиента).