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: Apache Ranger의 잘못된 RCE 속성에 대한 정적 분석 수정 | Kitploit
도구/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
Static AnalysisVulnerability AnalysisCode AnalysisExploitationWeb SecurityLearning & Education
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: Apache Ranger의 잘못된 RCE 속성에 대한 정적 분석 수정

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
저장소 보기
296개월 전아직 검토되지 않음
공유

CVE-2025-59059: Apache Ranger의 잘못 귀속된 RCE에 대한 정정

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에 적용된 패치 diff에 기반합니다.


권고사항의 내용

공식 권고사항은 다음과 같이 읽힙니다:

"Apache Ranger 버전 <= 2.7.0에서 NashornScriptEngineCreator의 원격 코드 실행 취약점이 보고되었습니다."

이것은 틀렸거나 적어도 오해의 소지가 있습니다. NashornScriptEngineCreator는 취약한 클래스가 아닙니다. 오히려 코드베이스에서 Nashorn 관련 두 컴포넌트 중 더 잘 보호된 쪽입니다. 이에 대해서는 나중에 다루겠습니다.


배경: Apache Ranger의 Nashorn

Apache Ranger는 행 수준 필터 정책을 평가하기 위해 JavaScript 표현식을 사용합니다. 이는 특정 사용자가 데이터셋의 특정 레코드에 접근할 수 있는지 여부를 결정하는 규칙입니다. 이러한 표현식을 JVM에서 실제로 실행하기 위해 Ranger는 JavaScript 엔진을 내장합니다. 버전 <= 2.7.0에서 그 엔진은 Nashorn, 즉 JDK 8~14에 포함된 Oracle의 내장 JS 엔진입니다.

권고사항이 완전히 생략한 한 가지(영향 범위를 정하는 데 매우 중요함)는 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 — ClassFilter 수준에서 모든 Java 클래스 접근을 차단하며 모든 것에 대해 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) {
            // 이 특정 문자열 하나만 확인
            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("보안 문제로 필터 표현식을 처리할 수 없습니다...");
        }

        // Nashorn을 직접 인스턴스화 — --no-java, --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이 차단되었는지 확인하기 위해 존재합니다. 차단되지 않은 것은 this.engine이 전혀 필요하지 않은 직접 java.* 경로였습니다.


진입점

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()에서 비롯됩니다. 이는 Ranger 행 필터 정책에 저장된 JavaScript 표현식입니다. 정책 관리자 권한을 가진 공격자는 해당 표현식을 원하는 대로 설정할 수 있습니다. 이후 어떤 사용자가 해당 정책이 적용되는 리소스에 접근하면 hasAccessToRecord()가 실행되고, filterExpr를 정책 저장소에서 가져와 filterRow()가 샌드박싱 없이 Nashorn에 전달합니다.

공격 체인:

정책 관리자 접근
       |
       v
중첩 구조 리소스에 대한 행 필터 정책 생성/수정
       |
       v
filterExpr 설정: java.lang.Runtime.getRuntime().exec("...")
       |
       v
모든 사용자가 리소스 접근 → hasAccessToRecord() 트리거
       |
       v
filterExpr가 filterRow()로 전달 → Nashorn이 평가 → RCE

패치 diff

수정 사항은 RANGER-4076: Nashorn Script Engine 제거로 추적되며, 2025년 12월 8일 Kishor Gollapalliwar에 의해 커밋되었습니다. Apache 메일링 리스트 커밋 아카이브에서 가져왔습니다. 세 개의 파일이 변경되었고, 27개의 삽입, 81개의 삭제가 있었습니다.

commit 923a8473de2985cd389d45062cd4717d5ca13235
Author: Kishor Gollapalliwar
AuthorDate: Mon Dec 8 14:55:56 2025 +0530

    RANGER-4076: Remove Nashorn Script Engine

 .../plugin/util/NashornScriptEngineCreator.java    | 67 ----------------------
 .../ranger/plugin/util/ScriptEngineUtil.java       |  7 +--
 .../authorizer/RecordFilterJavaScript.java         | 34 ++++++++---
 3 files changed, 27 insertions(+), 81 deletions(-)

파일 1: NashornScriptEngineCreator.java 완전 삭제

도구 다운로드