Введение: Не каждую систему защиты нужно преодолевать с использованием дизассемблера. Иногда достаточно открыть инструменты разработчика, изучить код JavaScript фронтенда и понять логику принятия решений приложением о блокировке функций. В данной работе мы рассмотрим механизм проверки лицензии в Java-приложении с веб-интерфейсом, проанализируем архитектуру фреймворка Angular с использованием NgRx, и оценим эффективность применения искусственного интеллекта при анализе минифицированного кода.
Важное уведомление: Данный материал носит исключительно информационный характер и предназначен для специалистов в области информационной безопасности, проводящих авторизованное тестирование защиты. Автор и издатели не несут ответственность за любой ущерб, причиненный использованием описанной информации. Создание, распространение и применение вредоносного программного обеспечения, а также несанкционированное вмешательство в работу систем преследуется по закону.
Базовые принципы защиты
Мы достаточно тщательно изучили различные типы защитных механизмов, чтобы усвоить простую и очевидную истину: независимо от сложности и изощренности системы защиты, её надежность определяется уязвимостью наиболее слабого звена, в которое она интегрирована. Несмотря на кажущуюся банальность этого утверждения, многие разработчики не уделяют должного внимания этому аспекту и совершают ошибку, устанавливая защитные механизмы даже на веб-фронтенд собственного приложения. Логично предположить, что для отключения подобной защиты не требуется обладать специальными навыками взлома — достаточно владеть базовыми знаниями веб-технологий, и даже простой скрипт справится с этой задачей.
Начало исследования
Не переживайте: для воспроизведения описанных далее действий не потребуется тратить какие-либо ресурсы или использовать сложные инструменты. Наша основная цель — выявить потенциальные уязвимости в системе защиты, если таковые существуют.
Объект анализа
Рассмотрим практический пример: приложение, которое требует активации при запуске (как онлайн, так и офлайн режимы). Основной исполняемый файл приложения не представляет для нас интереса благодаря своему небольшому размеру (менее одного мегабайта). Даже без специальных знаний видно, что это лаунчер для значительно более крупного Java-архива (около одного гигабайта), расположенного в подпапке /app рабочей директории программы.
Однако не будем торопиться с разбором структуры на отдельные классы — об этом подробно рассказано в наших предыдущих публикациях. Сегодня задача значительно проще и требует совершенно другого подхода.
Обнаружение веб-компонента
Для проверки гипотезы откроем системный монитор задач, чтобы изучить процессы, запускаемые приложением при загрузке окна активации. Помимо основного лаунчера (который использует минимальные ресурсы) приложение создает несколько процессов с названием Java Chromium Embedded Framework (JCEF) Helper. Эти процессы реализуются модулем jcef_helper.exe, находящимся в подпапке /jcef-bundle программной директории.
Поиск в сети показывает, что этот фреймворк позволяет Java-приложениям встраивать полноценный веб-браузер (на основе движка Chromium) прямо в графический интерфейс. Фактически перед нами веб-приложение, встроенное в Java-контейнер. С подобными решениями мы встречались ранее, однако в прошлых случаях приложение запускалось напрямую из веб-браузера, а здесь браузер интегрирован непосредственно в Java-приложение.
Доступ к инструментам разработчика
Наша текущая задача — разобраться в структуре окна активации и выяснить причину его появления при запуске неактивированной программы. Для просмотра HTML-кода, генерируемого jcef_helper.exe, требуется получить доступ к встроенным инструментам разработчика Chromium (Developer Tools). Представим, что это обычный браузер Google Chrome с открытой веб-страницей.
К счастью, хотя щелчок правой кнопкой мыши в окне приложения заблокирован, разработчики забыли запретить нажатие клавиши F12. Это очень упрощает нам задачу, так как в противном случае пришлось бы настраивать отладку через удаленный порт обычного браузера, что значительно сложнее. При нажатии F12 открывается окно Developer Tools, в котором переходим на вкладку Sources.
Анализ структуры приложения
Окно активации представляет собой локальную веб-страницу, размещенную по адресу http://localhost:8072/en-US/user/license-activation-wizard. Она динамически генерируется с помощью скриптов и модульного сборщика WebPack. К сожалению, эта страница защищена от кросс-доменных запросов или требует авторизации, поэтому прямой доступ к ней из системного веб-браузера невозможен. Нам остается использовать открытый инструмент Developer Tools, которого достаточно для анализа.
Проверка гипотезы
Нас интересует код JavaScript-скриптов, формирующих эту страницу. Проверяем предположение, что логика проверки лицензии и загрузка окна активации находятся именно в этих скриптах, а значит, могут быть отключены путем модификации текстового кода.
Задача сложнее, чем может показаться изначально. Как видно на скриншоте, код скомпилирован, оптимизирован, минифицирован и разделен на так называемые чанки. В части экрана видна структура одного такого фрагмента, отвечающего за окно активации — файл 804.30ceda3d3520d8ea.js. Если обратиться к анализу заголовка этого модуля, то можно увидеть типовые конструкции JavaScript:
-
'use strict';— указание на использование строгого режима JavaScript, который обеспечивает улучшенную проверку ошибок, запрещает устаревшие синтаксические конструкции и повышает производительность; -
self.webpackChunkalx— глобальный массив в контексте window или Worker, используемый Webpack для хранения и синхронизации всех модулей приложения; -
self.webpackChunkalx || []— защитная инициализация: если массив уже существует, использует его; в противном случае создает новый пустой массив для предотвращения ошибок при случайной загрузке скриптов; -
.push([[804], { 75804: (...) => {...} }])— добавление нового модуля в систему модульного загрузчика.
Поиск точки входа
Используя встроенный глобальный поиск в Developer Tools, находим вхождение маршрута user/license-activation-wizard в модуле 480.7c8d50d85606ddd0.js. Этот код демонстрирует, как приложение определяет необходимость загрузки окна активации и инициирует этот процесс.
Дополнительный анализ подтверждает предположения о структуре приложения и раскрывает детали его разработки и архитектурных решений, используемых при создании этого Java-приложения с встроенным веб-интерфейсом.
