SSTI в Spring Boot 3.3.4: уязвимость, приводящая к RCE

Безопасность Thymeleaf оказалась слабее, чем ожидалось.


zuga196pl539qk3vpalzlwn0nvpuje3b.jpg


Исследователь безопасности продемонстрировал эксплуатацию уязвимости SSTI (Server-Side Template Injection) в Spring Boot 3.3.4 при использовании шаблонизатора Thymeleaf. В ходе тестирования удалось добиться удалённого выполнения кода ( RCE ), несмотря на встроенные механизмы защиты.

Во время пентеста специалисты обнаружили, что заголовок Referer используется в шаблоне Thymeleaf без надлежащего экранирования. Анализ показал, что шаблон применяет механизм двойной интерпретации выражений, что позволяет внедрять произвольный Java -код.

Первоначальные попытки эксплуатации затруднялись HTML-кодированием. Инъекция одинарной кавычки отражалась в закодированном виде, что изначально мешало эксплуатации. Однако парсер Thymeleaf исправлял ошибки синтаксиса, позволяя выполнить произвольное выражение.

Локальное тестирование подтвердило возможность выполнения кода. Инъекция выражения ${7*7} вывела 49, подтверждая наличие SSTI. Однако попытка выполнить команду через SSTI-запрос:

${T(java.lang.Runtime).getRuntime().exec('calc')}  
привела к ошибке TemplateProcessingException. Исследователи выяснили, что Thymeleaf запрещает доступ к статическим классам и методам в шаблонах.

Для обхода ограничений использовалась рефлексия. Несмотря на блокировку многих потенциально опасных классов, в приложении была загружена библиотека Apache Commons Lang3, содержащая класс MethodUtils, который позволял выполнять приватные методы.

Этот класс позволил обойти защиту и вызвать метод Runtime.getRuntime(), что привело к выполнению команд:

"".class.forName("org.apache.commons.lang3.reflect.MethodUtils").invokeMethod( "".class.forName("java.lang.Runtime")  .getMethod("getRuntime")  .invoke(null), "exec", "whoami")
Команда whoami выполнилась успешно, подтвердив возможность удалённого выполнения кода.

Из-за запрета на исходящие соединения исследователь использовал файловый ввод-вывод для передачи данных. Запрос заголовка Referer позволял записывать результат в файл, а затем извлекать его через HTTP-ответ:

bash -c {echo,d2hvYW1p}|{base64,-d}|{bash,-i}>abc  
Финальный эксплойт позволял выполнять удалённые команды, но требовал использования файлового вывода из-за ограничений среды.