
Apache Spark 4.2.0 - Alta - Remoto - Privilegio residuo - proxy-user defaultExtraClassPath
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-proxyuser-classpath
Write-up: https://abraxaslabs.tech/research/spark-proxyuser-classpath
Classe: Residuo di privilegio (residuo di CVE-2023-22946 / SPARK-41958) Portata: Remota
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
CVE-2023-22946 / SPARK-41958 mantiene ancora spark.submit.proxyUser.allowCustomClasspathInClusterMode impostato a false per impostazione predefinita ed esegue ancora childClasspath.clear() al submit in cluster con --proxy-user. Questo è il percorso pubblico YARN --jars. Spark 4.0 ha poi aggiunto spark.driver.defaultExtraClassPath. Il launcher antepone sempre quella chiave alla -cp della JVM di spark-submit, anche in modalità cluster. SPARK-41958 non la vede mai.
Un tenant in stile Livy può comunque caricare un jar preparato all'interno della JVM spark-submit del gateway. UserGroupInformation.doAs di Hadoop non cambia quell'UID Unix.
| ID | nessuna CVE al momento |
| Classe | Residuo di privilegio (residuo di CVE-2023-22946 / SPARK-41958) |
| Portata | Remota (submit di job --proxy-user in stile Livy attraverso il gateway) |
| CWE | CWE-269, CWE-427 |
| CVSS | Alto: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Prodotto | Apache Spark |
| Affetto | Apache Spark 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) |
| Auth | tenant autenticato di un gateway in stile Livy / Kyuubi / Oozie che inoltra --conf e --jars preparati in spark-submit --proxy-user ... --deploy-mode cluster |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1:18950. File di prova. Gadget dei percorsi launcher / submit citati. |
Possedere un account tenant su un gateway Spark multi-tenant (Livy, Kyuubi, Oozie e simili) che esegue spark-submit --proxy-user <tenant> --deploy-mode cluster con un UID superuser. Preparare un jar che la JVM del gateway può aprire. Inviare --conf spark.driver.defaultExtraClassPath=<staged jar>. Il controllo di SPARK-41958 può restare false. La spark-submit -cp costruita inizia comunque con quel jar. Le classi al suo interno vengono caricate con l'UID Unix del gateway.
--conf spark.submit.proxyUser.allowCustomClasspathInClusterMode=true è un secondo percorso: .internal() è solo documentazione, --conf scrive comunque la chiave, e la modalità cluster YARN mantiene poi --jars su childClasspath. La CVE-2023-22946 pubblica resta il percorso predefinito YARN --jars che clear() già copre. Questo residuo è defaultExtraClassPath senza controllo.
L'impersonificazione Hadoop dopo un submit pulito resta comunque l'utente proxy per l'AM YARN / il driver k8s. Questo residuo riguarda solo la JVM del gateway.
| Metodo | Sink | Recon | Integrità | Disponibilità | Provenienza |
|---|---|---|---|---|---|
Invio in stile Livy --proxy-user + cluster yarn/k8s/standalone + --conf spark.driver.defaultExtraClassPath=<staged local jar>, flag SPARK-41958 lasciato a false | SparkSubmitCommandBuilder.buildSparkSubmitCommand SparkSubmitCommandBuilder.java:317-327 primo elemento di -cp | Elenca/legge i file che l'UID del gateway può leggere (directory keytab, spark-defaults, staging locale). L'identità Hadoop delle RPC successive è comunque l'utente proxy. | Carica classi del tenant all'interno della JVM spark-submit. L'UID Unix resta il gateway (superutente proxy Hadoop). Lab: defaultExtraClassPath-on-cp=yes childClasspath-cleared=yes lab.WitnessMain ha scritto SPARK-PROXYUSER-CLASSPATH-WITNESS. Dedotto dalla classe CVE pubblica: overlay delle risorse Configuration di Hadoop / lookup dell'implementazione FileSystem come quell'UID. | Crash della JVM di submit se l'overlay genera un'eccezione. Non la classe. | Caricamento e scrittura witness dimostrati in lab come -cp costruito. Overlay Hadoop dedotto. Passthrough --conf di Livy/Kyuubi dedotto (quei tree non corrispondono a questo pin). |
Stesso submit con --conf spark.submit.proxyUser.allowCustomClasspathInClusterMode=true più --jars / risorsa primaria | SparkSubmit.prepareSubmitEnvironment SparkSubmit.scala:333-336,738-743,917-924 poi runMain :980-987 | Stessa recon del percorso A, sul child URLClassLoader anziché sul system loader. | Mantiene --jars su childClasspath così addJarToClasspath viene eseguito. Lab: conf-flag-keeps-jars=yes. | Idem. | Mantenimento di childClasspath dimostrato in lab. Non è una ri-segnalazione del percorso pubblico YARN --jars che clear() copre quando il flag resta false. |
Dimostrato in lab vs dedotto: il -cp costruito contiene defaultExtraClassPath in modalità cluster; childClasspath.clear() viene comunque eseguito con il flag predefinito; spark.driver.extraClassPath è omesso in cluster; --jars con flag false viene cancellato; una classe witness su quel -cp scrive l'oracle. L'esecuzione della classe di configurazione Hadoop è il meccanismo pubblico di CVE-2023-22946, non rieseguito qui. L'inoltro di --conf da parte di Livy/Kyuubi è l'architettura documentata da quei progetti.