Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
spark-history-zip-symlink — Apache Spark 4.2.0 - 높음 - 원격 - 파일 읽기 - History zip이 심어진 심볼릭 링크를 따라감 | Kitploit
도구/GitHubGitHub/abraxas/spark-history-zip-symlink
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringPenetration TestingPapers & Research
GitHubabraxas/spark-history-zip-symlink

spark-history-zip-symlink

Apache Spark 4.2.0 - 높음 - 원격 - 파일 읽기 - History zip이 심어진 심볼릭 링크를 따라감

저장소 보기
33일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Abraxas Labs - spark-history-zip-symlink

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-history-zip-symlink

spark-history-zip-symlink

분류: 파일 읽기 도달 범위: 원격

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

CVE-2025-54920으로 History Server의 Jackson이 잠겨 sparkEventFromJson은 SparkListenerEvent 하위 클래스만 생성합니다. 하지만 롤링 zipEventLogFiles는 여전히 모든 listStatus 자식을 FileSystem.open을 통해 덤프합니다. LocalFileSystem은 POSIX 심볼릭 링크를 따라갑니다. eventlog_v2_*에 심어둔 자식이 인증 없는 GET /api/v1/applications/{id}/logs에 압축되어 포함됩니다. zip 멤버 본문은 SHS-UID 대상입니다. 엔트리 이름은 심볼릭 링크의 basename입니다.

이것은 Jackson RCE의 재신고가 아닙니다. Jackson은 닫혀 있습니다. 이것은 호스트 RCE가 아닙니다. 무결성과 가용성은 없습니다.

ID아직 CVE 없음
분류파일 읽기 (CVE-2025-54920 피해자 모델의 롤링 zip 잔여물)
도달 범위원격 (History 로그 디렉터리 작성자 + zip의 인증 없는 GET)
CWECWE-59, CWE-22
CVSSHigh: 7.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
제품Apache Spark
영향받는 버전4.2.0 태그 v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
인증PR:L = spark.history.fs.logDirectory에 쓰기 (54920과 동일한 피해자). History UI ACL은 기본적으로 꺼져 있음.
라이선스GNU Affero GPL v3.0
랩127.0.0.1:18980 전용

공격자가 할 수 있는 일

spark.history.fs.logDirectory(기본값 file:/tmp/spark-events)에 쓸 수 있는 사람은 History Server가 압축할 롤링 디렉터리를 심을 수 있습니다. 롤링 작성자는 기본적으로 켜져 있습니다. History UI ACL은 기본적으로 꺼져 있습니다. SHS 프로세스 UID가 혼동된 대리인입니다.

권한메서드 / 싱크랩 검증 또는 추론
기밀성: SHS UID가 열 수 있는 호스트 파일 읽기유효한 appstatus_*와 events_* JSON(SparkListenerLogStart / SparkListenerApplicationStart)에 더해 로그 디렉터리 밖을 가리키는 심볼릭 링크 자식을 가진 eventlog_v2_<id>/를 심음. 스캔을 기다림. 인증 없는 GET /api/v1/applications/{id}/logs (OneApplicationResource.getEventLogs -> FsHistoryProvider.writeEventLogs -> RollingEventLogFilesFileReader.zipEventLogFiles -> FileSystem.open)랩 검증됨. zip 멤버 eventlog_v2_app-2026-0001/planted-secret 본문은 SPARK-HISTORY-ZIP-SYMLINK-WITNESS. events 멤버에는 witness가 없음. 엔트리 이름은 대상 경로가 아니라 심볼릭 링크 basename으로 유지됨.
기밀성: 공격자가 open할 수 없는(660) 동일 테넌트의 이벤트 로그동일한 zip, 심볼릭 링크 대상은 다른 앱의 로그추론됨. 동일한 FileSystem.open. 검증되지 않음.
기밀성: SHS가 읽을 수 있다면 keytab, spark-env.sh, /etc/passwd동일한 zip추론됨. 오라클은 해당 파일들이 아니라 전용 /secret/host-secret임.
SHS 또는 호스트 파일의 무결성zip은 HTTP 본문으로 읽힘닫힘. 랩 검증 결과 없음.
SHS 또는 호스트 파일의 가용성zip은 대상을 삭제하거나 잘라내지 않음닫힘. 랩 검증 결과 없음.
호스트 RCE / Jackson gadget constructJsonProtocol.sparkEventFromJson닫힘. SparkListenerEvent가 필요함. 이 랩은 무해한 Event JSON만 심음.
엔트리 이름의 ../ zip slipPath.getName()닫힘. POSIX 파일명은 /를 포함할 수 없음. 엔트리는 eventlog_v2_<id>/<basename>.
resolveLogPath의 경로 문자열 이탈new Path(logDir, attempt.logPath)닫힘. Path 객체는 구성된 로그 디렉터리 아래에 머무름. 이탈은 inode임.
대상의 compaction 재작성 / cleaner 삭제spark.history.fs.eventLog.rolling.maxFilesToRetain 기본값 Integer.MAX_VALUE; cleaner 기본값 꺼짐닫힘. 심볼릭 링크에 대한 로컬 fs.delete는 대상이 아니라 링크를 unlink함.
인증 없는 job 제출 / ML 모델 로드SECURITY.md FAQ / docs/ml-security.md닫힘. 설계상 그렇고, 이 잔여물이 아님.

발견 방법

master나 4.3 RC가 아니라 apache/spark v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)을 고정했습니다. 스물여덟 번의 추적. Jackson History RCE는 이 버전에서 닫혀 있습니다(JsonProtocol.scala:965-972). History Server는 여전히 공격자가 쓸 수 있는 로그 디렉터리를 가리키고 있었고, 이는 CVE-2025-54920과 동일한 피해자 모델입니다.

zipEventLogFiles는 이벤트 파일만이 아니라 모든 files를 압축합니다:

override def zipEventLogFiles(zipStream: ZipOutputStream): Unit = {
  val dirEntryName = rootPath.getName + "/"
  zipStream.putNextEntry(new ZipEntry(dirEntryName))
  files.foreach { file =>
    addFileAsZipEntry(zipStream, file.getPath, dirEntryName + file.getPath.getName)
  }
}

addFileAsZipEntry는 fileSystem.open 후 transferTo입니다. LocalFileSystem은 POSIX 심볼릭 링크를 따라갑니다. getLogDirInfo는 "심볼릭 링크를 적절히 처리한다"고 주석을 달고는 표시 이름을 위해 해석되지 않은 Path 부모를 순회합니다.

이미 기록된 잘못된 방향들: SPARK-52381을 History 전체 이야기로 취급한 것; witness를 events_*에 심은 것(랩이 이를 실패시킴); zip 엔트리가 대상 경로를 담을 것이라 기대한 것; resolveLogPath 접두사 결합을 이탈로 취급한 것; 이 버전에서 HiveConnection Event 클래스를 시도한 것.

랩

python3 spark-history-zip-symlink-Abraxas-Labs.py

또는

cd lab
./run.sh

EventLogFileReaders.scala의 롤링 zip 덤프 gadget이며, 완전한 History Server도 아니고 공식 spark:4.2.0 이미지도 아닙니다. Jackson을 통해 Event JSON을 파싱하지 않습니다. 루프백 127.0.0.1:18980. Compose 프로젝트 spark-history-zip-symlink. 롤링 디렉터리는 유효한 appstatus_* + events_*(witness 없음)와 planted-secret -> /secret/host-secret을 담고 있습니다.

SUCCESS SPARK-HISTORY-ZIP-SYMLINK SPARK-HISTORY-ZIP-SYMLINK-WITNESS

수정 방법

모든 listStatus 이름이 아니라 events_* / appstatus_* 자식만 압축하십시오. no-follow(O_NOFOLLOW / Hadoop no-symlink 옵션)로 열고, realpath가 spark.history.fs.logDirectory 밖에 있는 자식은 거부하십시오. 표시 이름 헬퍼는 realpath 검사가 아닙니다.

참고 자료

  • github.com/apache/spark 태그 v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
  • EventLogFileReaders.scala (addFileAsZipEntry ~48-56, zipEventLogFiles ~267-272)
  • FsHistoryProvider.scala (writeEventLogs ~831-856, resolveLogPath ~866-896)
  • OneApplicationResource.scala (GET .../logs ~128-165)
  • JsonProtocol.scala (sparkEventFromJson ~965-972, Jackson 잠금)
  • 인접 패치됨(Jackson construct, 이 inode 순회가 아님): CVE-2025-54920 / SPARK-52381
  • CWE-59 · CWE-22

라이선스

GNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.

도구 다운로드