Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction — CVE-2025-59059: Ошибочно приписанная RCE в Apache Ranger — исправление статического анализа | Kitploit
Инструменты/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
Статический анализАнализ уязвимостейАнализ КодаЭксплуатацияВеб-безопасностьОбучение и Образование
GitHubpl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction

CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction

CVE-2025-59059: Ошибочно приписанная RCE в Apache Ranger — исправление статического анализа

Репозиторий
426 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2025-59059: RCE в Apache Ranger с ошибочной атрибуцией — исправление

CVE: CVE-2025-59059
Затронутые версии: Apache Ranger <= 2.7.0
Исправлено в: Apache Ranger 2.8.0
CVSS (официально): 9.8 Критический
Фактическая серьёзность (по мнению автора): ~6.0 Средний — см. анализ ниже


Предисловие

Этот разбор не о новом эксплойте или рабочем PoC. Суть здесь в том, чтобы исправить ошибки публичного раскрытия CVE-2025-59059, а именно две вещи: в качестве уязвимого компонента назван не тот класс, и оценка CVSS не отражает реальные ограничения эксплуатируемости. Всё здесь основано на статическом анализе исходного кода Apache Ranger 2.7.0 и диффа патча, вошедшего в 2.8.0.


Что говорится в advisory

Официальный advisory гласит:

«Уязвимость удалённого выполнения кода в NashornScriptEngineCreator обнаружена в Apache Ranger версиях <= 2.7.0».

Это неверно или как минимум вводит в заблуждение. NashornScriptEngineCreator — не уязвимый класс. Если на то пошло, это более защищённый из двух связанных с Nashorn компонентов в кодовой базе — к этому мы ещё вернёмся.


Предыстория: Nashorn в Apache Ranger

Apache Ranger использует JavaScript-выражения для оценки политик фильтрации строк. Это правила, определяющие, получает ли конкретный пользователь доступ к конкретной записи в наборе данных. Чтобы выполнять эти выражения на JVM, Ranger встраивает JavaScript-движок. В версиях <= 2.7.0 этим движком является Nashorn — встроенный JS-движок Oracle, поставлявшийся с JDK 8 по 14.

Одно обстоятельство, которое advisory полностью упускает — и это очень важно для оценки масштаба воздействия, — состоит в том, что jdk.nashorn.api.scripting.NashornScriptEngineFactory вообще не является частью исходного кода Ranger. Это встроенный компонент JDK. Он был включён в JDK 8, объявлен устаревшим в JDK 11 и полностью удалён в JDK 15. Так что эта уязвимость достижима, только если вы запускаете Ranger на JDK 8–14. Всё, что работает на JDK 15+, не затронуто, потому что Nashorn там просто не существует, а ScriptEngineUtil просто молча переключается на GraalJS или JavaScriptEngineCreator.

Два класса в Ranger используют Nashorn. Они обращаются с ним совершенно по-разному.


Два класса, связанных с Nashorn

1. NashornScriptEngineCreator — названный, но более безопасный

Расположен в:

agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
public class NashornScriptEngineCreator implements ScriptEngineCreator {

    private static final String[] SCRIPT_ENGINE_ARGS = new String[] {
        "--no-java", "--no-syntax-extensions"
    };

    @Override
    public ScriptEngine getScriptEngine(ClassLoader clsLoader) {
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        ret = factory.getScriptEngine(SCRIPT_ENGINE_ARGS, clsLoader, RangerClassFilter.INSTANCE);
        ...
    }

    private static class RangerClassFilter implements ClassFilter {
        @Override
        public boolean exposeToScripts(String className) {
            LOG.warn("script blocked: attempt to use Java class {}", className);
            return false;
        }
    }
}

Этот класс на самом деле делает три вещи для усиления безопасности движка:

  • --no-java — перекрывает прямой доступ к пространству имён java.* из скриптов
  • --no-syntax-extensions — отключает нестандартный синтаксис Nashorn
  • RangerClassFilter — блокирует весь доступ к Java-классам на уровне ClassFilter, возвращая false для всего

Пуленепробиваемо ли это? Нет. Обходы Nashorn ClassFilter существуют через цепочки рефлексии и трюки с java.lang.invoke. Но он значительно сильнее ограничен по сравнению с тем, что мы видим в другом классе.


2. RecordFilterJavaScript — фактически уязвимый класс

Расположен в:

plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
public class RecordFilterJavaScript {

    static class SecurityFilter implements ClassFilter {
        @Override
        public boolean exposeToScripts(String s) {
            return false;
        }

        boolean containsMalware(String filterExpr) {
            // only checks for this one specific string
            return filterExpr.contains("this.engine");
        }
    }

    public static boolean filterRow(String user, String filterExpr, String jsonString) {
        SecurityFilter securityFilter = new SecurityFilter();

        if (securityFilter.containsMalware(filterExpr)) {
            throw new MaskingException("cannot process filter expression due to security concern...");
        }

        // instantiates Nashorn directly — no --no-java, no --no-syntax-extensions
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        ScriptEngine engine = factory.getScriptEngine(securityFilter);

        String script = " jsonAttr = JSON.parse(jsonString); " + filterExpr;

        Bindings bindings = engine.createBindings();
        bindings.put("jsonString", jsonString);
        bindings.put("user", user);

        boolean hasAccess = (boolean) engine.eval(script, bindings);
        ...
    }
}

Сравните это с NashornScriptEngineCreator — разница очевидна:

  • нет флага --no-java — пространство имён java.* полностью открыто для скриптов
  • нет --no-syntax-extensions
  • единственная «защита» — одна строковая проверка: filterExpr.contains("this.engine")
  • filterExpr конкатенируется напрямую в скрипт, который выполняет Nashorn

Поскольку --no-java не передан, пространство имён java.* полностью доступно. Техники обхода вообще не нужны:

var runtime = java.lang.Runtime.getRuntime();
runtime.exec("id");

Никакого this.engine здесь нет. Чёрный список полностью нерелевантен для этого вектора атаки.

Что интересно: разработчики явно знали как минимум об одном паттерне обхода. В тестовом файле TestRecordFilterJavaScript.java есть вот это:

RecordFilterJavaScript.filterRow("user",
    "this.engine.factory.scriptEngine.eval('java.lang.Runtime.getRuntime().exec(\"/Applications/Spotify.app/Contents/MacOS/Spotify\")')",
    ...);

Этот тест существует, чтобы подтвердить, что this.engine блокируется. А вот прямой путь через java.* заблокирован не был, и он вообще не требует this.engine.


Точка входа

RecordFilterJavaScript.filterRow() вызывается только из одного места:

plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java
private boolean hasAccessToRecord(String schema, String user, ..., String jsonString, ...) {
    RangerAccessResult result = plugin.evalRowFilterPolicies(request, null);

    if (result.isRowFilterEnabled()) {
        String filterExpr = result.getFilterExpr();
        ret = RecordFilterJavaScript.filterRow(user, filterExpr, jsonString);
    }
    return ret;
}

filterExpr берётся из result.getFilterExpr() — это JavaScript-выражение, хранящееся в политике фильтрации строк Ranger. Злоумышленник с правами администратора политик может установить это выражение каким угодно. Когда любой пользователь затем обращается к ресурсу, управляемому этой политикой, срабатывает hasAccessToRecord(), которая извлекает filterExpr из хранилища политик, и filterRow() передаёт его в Nashorn практически без песочницы.

Цепочка атаки:

Доступ администратора политик
       |
       v
Создание/изменение политики фильтрации строк на ресурсе nestedstructure
       |
       v
filterExpr установлен в: java.lang.Runtime.getRuntime().exec("...")
       |
       v
Любой пользователь обращается к ресурсу → срабатывает hasAccessToRecord()
       |
       v
filterExpr попадает в filterRow() → Nashorn выполняет его → RCE

Дифф патча

Скачать инструмент