SQL-инъекция через декомпиляцию: от JAR-файла до компрометации учетных данных
SQL-инъекция через декомпиляцию: от JAR-файла до компрометации учетных данных
В ходе легального тестирования на проникновение в корпоративной Java-системе для складского учета была обнаружена критическая уязвимость типа SQL-инъекция. Дефект присутствовал в одном из GET-параметров веб-интерфейса, работающего по протоколу HTTPS, и позволял выполнять произвольные команды к базе данных без какой-либо аутентификации.
Обнаружение скрытой поверхности атаки
Первоначальная поверхность атаки выглядела ограниченно: стандартный веб-портал с формой входа, защищенный TLS-шифрованием. Прямые попытки эксплуатации известных CVE или перебора директорий не давали результата. Поскольку исходный код приложения предоставлен не был, анализ пришлось начинать с бинарных файлов — собранных JAR-архивов, которые можно было свободно скачать с сервера. Этот этап демонстрирует фундаментальную проблему безопасности: наличие исполняемого файла у атакующего равносильно наличию исходного кода. С помощью утилит для декомпиляции байт-кода Java (например, JD-GUI или FernFlower) удалось восстановить читаемый текст сервлетов. Процесс реверс-инжиниринга позволил изучить логику обработки запросов без документации со стороны разработчика.
Анализ бизнес-логики и выявление дефекта
После восстановления кода внимание привлек класс, отвечающий за отображение информации о товарах по их идентификатору. В коде одного из методов была найдена строка, формирующая SQL-запрос путем простой конкатенации:
String query = "SELECT * FROM products WHERE ID=" + request.getParameter("id");
Это классический пример динамического построения запроса, где пользовательский ввод напрямую встраивается в тело команды. Отсутствие использования параметризованных запросов (PreparedStatements) делает приложение абсолютно беззащитным перед манипуляциями с синтаксисом SQL. Разработчик полагался на то, что числовой идентификатор не может содержать буквы, однако серверное приложение не выполняло никакой проверки или приведения типов этого параметра перед передачей его в движок базы данных PostgreSQL.
Подтверждение вектора и слепая инъекция
Для безопасной верификации гипотезы использовалась техника «слепых» инъекций (Blind SQLi), так как веб-приложение не выводило ошибки БД прямо в интерфейс пользователя. Вместо прямого вывода данных применялись функции задержки ответа. Отправка специально сформированного значения id=1; SELECT pg_sleep(10)-- приводила к тому, что сервер отвечал ровно через 10 секунд. Использование встроенной функции СУБД pg_sleep() является стопроцентным доказательством наличия уязвимости, так как позволяет измерить время выполнения команд на стороне сервера. Это подтвердило возможность удаленного выполнения произвольных SQL-команд, включая те, что могут влиять на данные или взаимодействовать с операционной системой через расширения базы данных.
Эскалация привилегий и захват паролей
Получив доступ к выполнению SQL-команд, следующим шагом стал поиск конфиденциальной информации. В корпоративных системах таблицы пользователей часто содержат хеши паролей. Была составлена цепочка запросов для перечисления имен таблиц в схеме public, а затем для извлечения содержимого таблицы app_users. Результат включал столбцы login и password_hash. Хотя сами пароли были зашифрованы, получение списка логинов и соответствующих им соленых хешей переводит атаку на новый уровень. Далее злоумышленник может использовать эти данные для офлайн-брутфорса. Учитывая типичные корпоративные политики сложности, многие пользователи используют слабые пароли, которые вскрываются за считанные минуты с использованием GPU-вычислений. Таким образом, одна ошибка в одной строке Java-кода привела к риску полной компрометации учетных записей сотрудников.
Практические рекомендации для защиты периметра
Чтобы предотвратить подобные сценарии, необходимо внедрить строгие контроли на всех этапах разработки и эксплуатации приложений:
- Полностью исключить формирование SQL-запросов через конкатенацию строк. Все обращения к базам данных должны выполняться исключительно через параметризованные запросы (Prepared Statements) или ORM-библиотеки, корректно экранирующие входные данные.
- Внедрить статический анализ кода (SAST) в CI/CD пайплайн. Инструменты вроде SonarQube или Checkmarx способны автоматически находить небезопасную конкатенацию строк еще на этапе написания кода.
- Ограничить права пользователя базы данных. Приложение никогда не должно работать под суперпользователем (postgres, sa, root). Учетная запись должна иметь доступ только к необходимым схемам и запрет на чтение системных таблиц, таких как
pg_authid. - Использовать средства внешнего сканирования уязвимостей. Регулярный аудит веб-интерфейсов помогает найти точки входа, даже если внутренняя логика системы неизвестна команде ИБ.
Как проверить с помощью Perimeter
Платформа Perimeter EASM позволяет выявить внешние признаки подобных архитектурных изъянов. Модуль сканирования web-уязвимостей способен обнаружить симптомы SQL-инъекций путем отправки специальных полезных нагрузок в GET и POST параметры ваших публичных сервисов. Если система реагирует аномально долго или возвращает специфические маркеры ошибок в теле ответа, платформа зафиксирует это как потенциальный вектор проникновения. Кроме того, модуль OSINT поможет собрать информацию об используемых технологиях (Java, Tomcat, PostgreSQL), позволяя приоритизировать проверку именно тех узлов, где стек технологий совпадает с описанным сценарием риска.