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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
spark-rpc-stream-unauth — Apache Spark 4.2.0 - 높음 - 원격 - 파일 읽기 - 인증되지 않은 RPC StreamRequest 파일 조인 | Kitploit
도구/GitHubGitHub/abraxas/spark-rpc-stream-unauth
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringNetwork SecurityPenetration TestingPapers & ResearchLabs & Practice
GitHubabraxas/spark-rpc-stream-unauth

spark-rpc-stream-unauth

Apache Spark 4.2.0 - 높음 - 원격 - 파일 읽기 - 인증되지 않은 RPC StreamRequest 파일 조인

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Abraxas Labs - spark-rpc-stream-unauth

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-rpc-stream-unauth

spark-rpc-stream-unauth

분류: 권한 잔여물 / 파일 읽기 도달 범위: 원격

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

CVE-2020-9480은 RPC 제어 평면에서 인증되지 않은 RequestSubmitDriver / RegisterApplication을 차단했습니다. AbstractAuthRpcHandler는 receive()와 receiveStream()을 게이트합니다. 하지만 getStreamManager()는 게이트하지 않습니다. TransportRequestHandler는 여전히 SASL 이전에 StreamRequest를 해당 매니저로 디스패치합니다. NettyStreamManager.openStream은 루트 내부 유지 검사 없이 new File(dir, fname)을 수행합니다.

인증되지 않은 StreamRequest classes/../../path가 Spark-UID 파일을 읽습니다. Unix 절대 경로 자식은 등록된 디렉터리 내부에 머무릅니다(랩 404). files/는 맵 조회입니다(404). receive() / receiveStream()은 401로 유지됩니다. 이는 9480 RCE가 아닙니다.

ID아직 CVE 없음
분류권한 잔여물 / 파일 읽기 (CVE-2020-9480의 게이트되지 않은 RPC 데이터 평면 잔여물)
도달 범위원격 (spark.authenticate=true인 드라이버 RpcEnv / ESS / BlockManager에 대한 인증되지 않은 TCP)
CWECWE-862, CWE-22
CVSS높음: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
제품Apache Spark
영향받는 버전4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8). 운영자가 활성화한 spark.authenticate=true. 호스트 파일 읽기에는 등록된 디렉터리(spark.repl.class.outputDir /classes 및/또는 Connect artifacts)가 필요합니다.
인증StreamRequest / getStreamManager()에 없음
라이선스GNU Affero GPL v3.0
랩127.0.0.1 전용

공격자가 할 수 있는 일

spark.authenticate=true와 등록된 디렉터리가 있는 Spark RPC 포트로 TCP 연결합니다. 공유 비밀이 필요 없습니다. spark.network.crypto.enabled도 필요 없습니다. streamId가 classes/../../<path>인 전송 StreamRequest(메시지 유형 6)를 보냅니다. TransportRequestHandler.processStreamRequest는 RpcHandler.receive를 호출하지 않습니다. 대신 getStreamManager().openStream을 호출합니다. 9480 래퍼는 실제 매니저를 반환합니다. new File(dir, "../../oracle/secret")은 REPL/아티팩트 루트 외부로 정규화되어 FileSegmentManagedBuffer로 반환됩니다.

이는 Spark UID 권한으로의 호스트 파일 읽기입니다. 작업 제출이 아닙니다. RequestSubmitDriver가 아닙니다. 셸도 아닙니다.

기밀성 (랩 입증)

방법싱크권한
인증되지 않은 StreamRequest classes/../../<path>NettyStreamManager.openStream new File(dir, fname) 후 FileSegmentManagedBuffer드라이버가 열 수 있는 Spark-UID 파일을 읽습니다. 랩 입증: opened /opt/repl-classes/../../oracle/secret, 정규화된 경로 /oracle/secret, 본문 SPARK-RPC-STREAM-UNAUTH-WITNESS, x-auth-gated=false, x-authenticated=false.
인증되지 않은 StreamRequest classes/hello.txt (디렉터리 내 제어)동일한 조인, 등록된 디렉터리 내부에 머무름실제로 /classes 아래에 있는 파일을 읽습니다. 랩 입증 200 IN-DIR-OK, 증인 없음. 포함된 이름에 대해서도 SASL 없이 파일 서버가 작동함을 확인합니다.

기밀성 (추론)

방법싱크권한
라이브 ESS streamId에 대한 인증되지 않은 ChunkFetchRequest / StreamRequestOneForOneStreamManager.getChunk / openStream. checkAuthorization은 client.getClientId() == null일 때 건너뜁니다다른 앱의 진행 중인 셔플 / 디스크-RDD 바이트를 읽습니다. 가용성: 드레인이 curChunk를 진행시킵니다. 라이브 streamId가 필요합니다(무작위 시작, 이후 +1). 가젯은 라이브 ESS와 통신하지 않았습니다.
인증되지 않은 MergedBlockMetaRequestAbstractAuthRpcHandler.getMergedBlockMetaReqHandler()도 게이트되지 않음ESS에 병합 셔플이 있을 때 선택한 appId의 병합 셔플 청크 비트맵을 읽습니다. 동일한 null-clientId 건너뛰기. 실행되지 않았습니다.

이 잔여물에서 차단됨 (랩 입증)

방법싱크차단 유지
인증되지 않은 StreamRequest classes//oracle/secret (Unix 절대 경로 자식)new File(dir, "/oracle/secret")404. 열린 경로는 /opt/repl-classes/oracle/secret입니다. Unix File은 연결하며, 부모를 무시하지 않습니다. 절대 경로 자식이 루트를 버린다는 헌트 주장은 Unix에서 틀렸습니다.
인증되지 않은 StreamRequest files//oracle/secretfiles 맵 조회404. files/와 jars/는 조인이 아닌 basename 조회입니다.
인증되지 않은 receive() / OneWayMessageAbstractAuthRpcHandler.receive401 Unauthenticated call to receive(). x-auth-gated=true.
인증되지 않은 receiveStream() / UploadStreamAbstractAuthRpcHandler.receiveStream401 Unauthenticated call to receiveStream().
랩 비밀로 인증된 receiveStream()doAuthChallenge 이후 동일한 게이트200 receiveStream-ok. 비밀이 여전히 9480 경로를 여는지에 대한 제어.

랩 입증 vs 추론: 인증되지 않은 .. 파일 읽기, Unix 절대 경로 404, files/ 404, 게이트된 receive / receiveStream은 랩입니다. ESS 셔플 드레인은 추론입니다.

인접 차단 (과장하지 말 것):

  • CVE-2020-9480 RCE 경로: OneWayMessage / UploadStream / RpcRequest를 통한 인증되지 않은 RequestSubmitDriver / RegisterApplication. 여전히 공유 비밀이 필요합니다.
  • 기본 spark.authenticate=false의 인증되지 않은 셔플 및 작업 제출(SECURITY.md FAQ, 문서화된 신뢰 네트워크 기본값). 이 잔여물이 아닙니다.
  • 인증된 앱 A가 앱 B를 가져오기(AppIsolationSuite / SPARK-57889 non-null clientId).
  • CVE-2021-38296 핸드셰이크 키 복구.
  • CVE-2025-55039 Moderate CTR 기본값.
  • 독립 실행형 master RpcEnv는 일반적으로 /classes나 artifacts가 등록되어 있지 않으므로, 이 호스트 파일 경로 탐색은 드라이버 / REPL / Connect이며 master:7077이 아닙니다.
  • 파일을 실행하지 않습니다. 쓰지 않습니다. spark.authenticate.secret을 덤프하지 않습니다.

발견 방법

저는 apache/spark v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)을 고정했으며, master나 4.3 RC가 아닙니다. 28번의 소스 헌트. 열린 클러스터에서의 작업 제출은 설계상입니다. ML 모델 로드는 실행 가능한 코드입니다. 공개된 Jackson History RCE, UI id -Gn 셸, PySpark 로컬 임퍼소네이션, 9480 수신 경로는 이번 껍질에서 차단됩니다.

RPC 인증 헌트는 9480의 재신고 확인이 될 예정이었습니다. AuthServerBootstrap은 여전히 핸들러를 래핑합니다. 인증되지 않은 receive는 여전히 예외를 던집니다. 그런 다음 getStreamManager()를 읽었습니다. 세 줄. 델리게이트를 반환합니다. TransportRequestHandler.handle은 StreamRequest를 receive를 우회하여 라우팅합니다. 기본 StreamManager.checkAuthorization은 no-op입니다. SPARK-57889는 StreamRequest에 문자열 ID 검사를 추가했고, ESS가 "인증 꺼짐"에 사용하는 null-clientId 건너뛰기를 유지했는데, 이는 "이 연결이 인증된 적 없음"이기도 합니다.

SparkContext는 spark.repl.class.outputDir이 설정되면 /classes를 등록합니다. Connect ArtifactManager는 artifacts를 등록합니다. NettyStreamManager.openStream은 ftype/fname을 분할합니다. files/jars가 아닌 유형은 정규 접두사 검사 없이 new File(dir, fname)을 수행합니다.

헌트 신뢰도를 하루 낭비했기에 기록하는 잘못된 방향: JavaDoc은 절대 경로 자식이 부모를 무시한다고 말합니다. Unix에서 UnixFileSystem.resolve는 연결합니다. new File("/opt/repl-classes", "/oracle/secret")은 /opt/repl-classes/oracle/secret입니다. 랩 404. High 경로는 classes/../../oracle/secret입니다.

연극: 이것이 9480 RCE라고 주장하는 것. 제어 평면은 여전히 게이트됩니다. 오라클은 Spark UID가 이미 읽을 수 있는 파일 안의 증인 문자열입니다.

랩

핀 소스의 가젯(AbstractAuthRpcHandler.java:52-87, NettyStreamManager.scala:54-70). HTTP는 TransportRequestHandler의 대역입니다: /stream?id=는 StreamRequest; POST /rpc/receive는 OneWayMessage; POST /rpc/receive-stream은 UploadStream. 공식 spark:4.2.0은 필요하지 않습니다. 루프백 전용.

python3 spark-rpc-stream-unauth-Abraxas-Labs.py

또는:

cd lab
./run.sh

루프백 127.0.0.1:18910. Compose 프로젝트 spark-rpc-stream-unauth. 증인 SPARK-RPC-STREAM-UNAUTH-WITNESS는 /oracle/secret에 있습니다. 등록된 디렉터리 /opt/repl-classes에 hello.txt = IN-DIR-OK. 마지막 줄:

SUCCESS SPARK-RPC-STREAM-UNAUTH SPARK-RPC-STREAM-UNAUTH-WITNESS

수정

isAuthenticated까지 getStreamManager()(및 getMergedBlockMetaReqHandler())를 게이트하거나, 거부하는 매니저를 반환하십시오. NettyStreamManager.openStream에서 getCanonicalFile 이후 등록된 디렉터리를 벗어나는 fname을 거부하십시오. ESS에서는 spark.authenticate가 켜져 있을 때 null clientId를 인증되지 않은 것으로 취급하십시오. SPARK-57889는 이미 StreamRequest에서 checkAuthorization을 호출합니다; 건너뛰기가 잔여물입니다.

그때까지는 Spark UID의 파일을 이미 신뢰하지 않는 누구에게나 TCP 포트가 도달 가능한 RpcEnv에 /classes나 artifacts를 등록하지 마십시오. spark.authenticate=true는 이 데이터 평면을 차단하지 않습니다.

참고

도구 다운로드