FlawOpen

flawopen.com/Incidents/citrix-bleed-session-token-leak-october-2023

● Citrix · CVE-2023-4966 · October 2023 · CVSS 9.4 · Crítica
Pesquisa · FlawOpen

Citrix Bleed: vazamento de tokens e bypass de MFA

A CVE-2023-4966 expôs memória do NetScaler com tokens de sessão; o sequestro contornou MFA. A exploração começou no fim de ago. de 2023.[1], [2]

💡 Explicação em Linguagem Simples (ELI5)

Você pede a um assistente que copie uma mensagem num cartão pequeno e diga o tamanho dela. O cartão só comporta 50 caracteres, então ele escreve 50, mas quando você pergunta o tamanho da mensagem, responde com sinceridade "800 caracteres", porque esse era o tamanho do original. Aí você entrega o cartão a alguém e manda ler 800 caracteres dele. A pessoa lê os seus 50 e continua lendo o que estiver escrito no resto da folha.[2]

Conceitos Centrais e Termos

snprintf
Função de C que formata texto num buffer de tamanho fixo. Quando o texto não cabe, ela o trunca, mas retorna o tamanho que o texto completo teria.[3]
NetScaler ADC / Gateway
Appliances da Citrix que oferecem acesso remoto e balanceamento de carga na borda da rede. Só os configurados como Gateway ou servidor virtual AAA eram afetados.[1]
Leitura além do buffer (CWE-125)
Ler depois do fim de um buffer. Nada é sobrescrito, mas o que estiver na memória vizinha é revelado. Isso descreve o mecanismo específico de leitura fora dos limites (CWE-125); a Citrix classifica a CVE-2023-4966 de forma ampla como CWE-119.[1], [3]
Token de sessão
O valor que prova que um usuário já fez login. Quem o apresenta é tratado como aquele usuário, sem pedido de senha nem de MFA.[2]

Mapeamentos de frameworks

Linha do Tempo do Incidente

2023-08

Começa a exploração da falha como zero-day, segundo relatórios posteriores de resposta a incidentes.[2]

2023-10-10

A Citrix publica o boletim CTX579459 com as versões corrigidas 14.1-8.50, 13.1-49.15 e 13.0-92.19.[1]

2023-10-18

A CISA inclui a CVE-2023-4966 no catálogo Known Exploited Vulnerabilities.[4]

Fluxo de Ataque Passo a Paso

Passo 1

Um cabeçalho grande demais

Uma requisição sem autenticação, com um cabeçalho Host muito longo, chega ao código que monta uma resposta de descoberta OpenID Connect no appliance.[2], [3]

Passo 2

O tamanho é mal interpretado

O snprintf trunca o texto para caber no buffer, mas retorna o tamanho completo que teria, e o código trata esse valor como número de bytes escritos.[3], [2]

Passo 3

A memória além do buffer é enviada

A resposta é enviada com esse tamanho maior, e o appliance devolve memória vizinha junto com o JSON truncado.[2]

Passo 4

As sessões são sequestradas

A memória vazada pode conter tokens de sessão válidos. Reutilizar um deles dá ao atacante a sessão do usuário, sem senha nem MFA.[2], [1]

Código-Fonte: Vulnerável vs. Seguro

C ilustrativo, não é código-fonte do NetScaler. A correção verifica o valor retornado por snprintf, que informa o tamanho que a saída completa teria. Se for negativo ou igual ou maior que o tamanho do buffer, a formatação falhou ou foi truncada, então a função não envia nada. Assim, send_response só recebe o tamanho quando a resposta completa cabe em buf.[3], [2]

IMPLEMENTAÇÃO VULNERÁVEL
#include <stdio.h>

int send_response(const char *data, int len);

int send_oidc_config(const char *host)
{
    char buf[256];
    /* n é o número de bytes que seriam gravados e pode exceder sizeof(buf) */
    int n = snprintf(buf, sizeof(buf), "{\"issuer\":\"https://%s\"}", host);
    return send_response(buf, n);   /* envia n bytes, lendo além de buf */
}
PATCH SEGURO E ROBUSTO
#include <stdio.h>

int send_response(const char *data, int len);

int send_oidc_config(const char *host)
{
    char buf[256];
    int n = snprintf(buf, sizeof(buf), "{\"issuer\":\"https://%s\"}", host);
    if (n < 0 || (size_t)n >= sizeof(buf))
        return -1;                  /* rejeite saída truncada; nunca envie além do buffer */
    return send_response(buf, n);
}

Lista de Verificação de Segurança para Engenharia

Fontes