В этой статье рассматривается исследование старого приложения, написанного на Visual Basic, которое использует шифрование для защиты файлов лицензии. Мы проанализируем процесс дешифрования, восстановим алгоритм из дизассемблированного кода и с помощью искусственного интеллекта определим, какой криптографический алгоритм был использован. Кроме того, выясним причины, по которым защита оказалась недостаточно надежной.

На протяжении времени было разработано множество различных криптографических алгоритмов. Некоторые из них стали стандартными решениями и продолжают совершенствоваться, тогда как другие быстро исчезают из употребления. Большинство забытых алгоритмов остаются в памяти исключительно благодаря скандалам и противоречиям, связанным с их использованием или взломом.

Вспомните случай с алгоритмом A5/1, использовавшимся в стандарте GSM. Этот алгоритм был признан неадекватным с точки зрения криптографической стойкости и в итоге был заменен. Подобные инциденты встречаются в истории криптографии неоднократно, поэтому продолжим исследование этой темы.

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

0F300C42D8404EF23FC6F72A2DF008CFBC397DC6ED5C72AF0F5279D83509D94F

Используя инструменты анализа IDA и VB Decompiler, мы локализуем функцию vbaLineInputStr, импортируемую из библиотеки msvbvm60.dll, которая отвечает за чтение текстовой строки из файла. Установив точку прерывания на эту функцию, мы можем наблюдать процесс загрузки лицензионной строки и анализировать код, отвечающий за ее обработку.

При дальнейшем анализе мы обнаруживаем функцию, которая предположительно выполняет расшифровку. Ее второй параметр содержит строку 'AbCdEfG', которая явно является ключом шифрования. Проведя несколько итераций отладки, мы подтверждаем, что эта функция действительно расшифровывает лицензию, преобразуя зашифрованные данные в читаемый формат, такой как 31/07/2026//User//56387429120874480//AA000000000000003156//17F8L1M.

Однако основная сложность заключается в восстановлении самого алгоритма дешифрования. Автоматические инструменты анализа криптографических алгоритмов не могут определить, какой конкретный алгоритм используется. Это происходит потому, что разработчик реализовал необычный подход: весь процесс шифрования осуществляется не через двоичные операции, а через манипуляции с текстовыми строками в шестнадцатеричном формате. Кроме того, инициализация основного массива выполняется поэлементно, что затрудняет автоматическое распознавание.

Анализ процесса формирования расписания ключей раскрывает еще одну необычную особенность. Ключ должен быть преобразован в 20-символную шестнадцатеричную строку, представляющую 10 байт данных. Эти 10 байт затем циклически повторяются для заполнения расписания длиной 132 байта. Однако используемый ключ AbCdEfG не соответствует этому формату: он содержит символы, которые не все являются валидными шестнадцатеричными цифрами.

Прямой анализ основной процедуры расшифровки отдельного 64-битного блока данных требует применения искусственного интеллекта для интерпретации восстановленного кода. Восстановленный из дизассемблированного кода исходный текст невероятно сложен для понимания человеком. Обратившись к нейросети с просьбой идентифицировать алгоритм и переформатировать код, получаем следующую структуру:

Алгоритм работает с 32 раундами обработки, чередуя две различные правила преобразования (Rule A и Rule B). Каждый раунд обрабатывает данные в виде четырех 16-битных слов (W1, W2, W3, W4). Процесс включает применение функции G с использованием расписания ключей и выполнение операций XOR с номером текущего раунда. Чередование между двумя правилами происходит следующим образом: первые 8 раундов используют Rule B, следующие 8 раундов используют Rule A, затем снова 8 раундов Rule B и, наконец, 8 раундов Rule A.

Детальное исследование показывает, что это реализация алгоритма Skipjack — криптографического алгоритма, разработанного Агентством национальной безопасности США в эпоху холодной войны. Алгоритм был предназначен для использования в системе Clipper и привлек значительное внимание в криптографическом сообществе именно потому, что его полная спецификация считалась государственной тайной.

Интересным фактом является то, что криптографическая стойкость алгоритма Skipjack оказалась значительно ниже заявленной. Несмотря на 32 раунда обработки и использование 80-битного ключа, позже были разработаны методы атаки, позволяющие существенно снизить сложность полного перебора. Кроме того, обнаруженные в данной реализации отступления от стандартной спецификации (использование текстовых строк вместо двоичных операций, нестандартное формирование расписания ключей) еще больше снижают его практическую безопасность.

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