Vulnerabilidade de Execução Remota de Comandos no GitLab Explorada via Notebooks Jupyter

Vulnerabilidade de Execução Remota de Comandos no GitLab Explorada via Notebooks Jupyter

Uma falha crítica no parser JSON Oj permite que usuários autenticados executem código arbitrário como usuário git em instâncias self-managed não corrigidas, exigindo apenas a criação de arquivos específicos.

ComponenteGitLab CE e EE (versões 15.2.0 a 19.0.1) e biblioteca Oj (parser JSON para Ruby)
VetorCommit de dois notebooks Jupyter (.ipynb) com JSON forjado e solicitação de diff, explorando buffer overflow e vazamento de ponteiro no parser Oj
ImpactoExecução remota de comandos (RCE) como usuário git, potencial acesso a código-fonte, segredos Rails, credenciais de serviço e dados de CI/CD
PrioridadeAtualização imediata para versões 18.10.8, 18.11.5 ou 19.0.2 e verificação da versão no container Webservice
Resumo técnico

Foi publicada uma prova de conceito (PoC) funcional que demonstra a execução de comandos remotos emservidores GitLab self-managed não atualizados. A exploração ocorre através de vulnerabilidades na biblioteca Oj, um parser JSON de alta performance para Ruby utilizado pelo GitLab para renderizar notebooks Jupyter. O ataque não exige privilégios de administrador, acesso ao runner de CI/CD, interação com outras vítimas ou acesso a projetos de terceiros, sendo necessário apenas um usuário autenticado na plataforma.

A cadeia de exploração publicada tem como alvo específico a versão 18.11.3 do GitLab em arquitetura x86-64, mas as falhas subjacentes no Oj afetam um amplo conjunto de versões. O problema deriva de como o processador de notebooks do GitLab manipula dados JSON controlados pelo repositório, passando-os diretamente para o estado nativo do parser Oj dentro do processo de aplicação do servidor web Puma. Como o processo é executado com os privilégios do usuário git, a exploração bem-sucedida compromete o isolamento da aplicação, expondo ativos sensíveis e permitindo movimentação lateral em ambientes mal configurados.

Fluxo técnico

A exploração combina duas falhas distintas no parser Oj para obter execução de código. A primeira é um estouro de buffer (buffer overflow) na pilha de estado de aninhamento. O Oj armazena o estado de aninhamento em uma pilha fixa de 1.024 bytes e não verifica se a profundidade estrutural do JSON excede esse limite. Arrays profundamente aninhados podem, portanto, escrever bytes 0x01 no estado adjacente do parser. A exploração corrompe o campo buf.head, fazendo com que o Oj passe um ponteiro forjado para a função realloc(). Uma alocação subsequente de um Array em Ruby reutiliza a mesma região de memória e sobrescreve p->start.

A segunda falha envolve um vazamento de endereço de heap necessário para evitar a aleatorização de layout de espaço de endereço (ASLR). O Oj aloca uma chave de objeto de 65.565 bytes, mas trunca seu comprimento para 29 em um campo assinado de 16 bits. Ao retornar 29 bytes contendo o ponteiro de alocação da chave ativa, o defeito permite que o exploit obtenha o endereço de memória real. Esse vazamento é exposto pelo GitLab no diff renderizado do notebook. Para contornar o ASLR, o exploit realiza uma busca de endereço que, testada em instalações com dois workers, leva entre cinco e dez minutos, podendo chegar a horas em cenários de Workers maduros.

A cadeia é acionada enviando dois arquivos de notebook ordenados lexicograficamente em uma única requisição diffs_stream. Isso garante que ambos os estágios ocorram dentro do mesmo worker Puma, que reutiliza o estado global do parser Oj. O primeiro arquivo corrompe o ponteiro de retorno e levanta um erro que o GitLab captura antes de continuar o diff. A próxima análise invoca o ponteiro sobrescrito e alcança a função system() através de uma sequência específica de gadgets (ROP) dependente da compilação (build-specific). O usuário git é usado para a conexão reversa na demonstração.

Superfície afetada

As vulnerabilidades afetam as edições Community (CE) e Enterprise (EE) do GitLab, englobando os planos Free, Premium e Ultimate. A faixa de versões vulneráveis inclui desde a 15.2.0 até a 18.10.7, da 18.11.0 até a 18.11.4, e da 19.0.0 até a 19.0.1. As primeiras versões corrigidas são a 18.10.8, 18.11.5 e 19.0.2. Clientes do GitLab.com (SaaS) já foram corrigidos até 10 de junho, restando o risco para operadores de instâncias self-managed que não atualizaram.

No nível da dependência, as gems publicadas do Oj nas versões 3.13.0 a 3.17.1 são vulneráveis. A correção está presente a partir da versão 3.17.3 do Oj. O impacto da execução como usuário git é significativo em ambientes onde o container ou host não possui isolamento rígido. O atacante potencialmente acessa o código-fonte de todos os repositórios, segredos do Rails, credenciais de serviços integrados, dados de pipelines de CI/CD e serviços internos alcançáveis a partir da aplicação.

  • GitLab CE/EE versões 15.2.0 a 18.10.7
  • GitLab CE/EE versões 18.11.0 a 18.11.4
  • GitLab CE/EE versões 19.0.0 a 19.0.1
  • Biblioteca Oj (Ruby gem) versões 3.13.0 a 3.17.1
  • Ambientes self-managed (on-premise ou cloud não gerenciada)
Hunting e telemetria

Equipes de segurança devem priorizar a verificação de versão, mas a telemetria pode indicar tentativas de exploração. Como o ataque requer o envio de notebooks com estruturas JSON aninhadas e anômalas, logs de aplicação que mostram erros de parsing ou falhas de segmentação (segfaults) em workers Puma ao lidar com arquivos .ipynb são fortes indicadores. Além disso, a atividade de rede de saída inesperada originada do usuário git ou do processo do servidor web pode sinalizar execução bem-sucedida de comandos.

Recomenda-se auditar repositórios quanto à criação recente de arquivos .ipynb que contenham metadados JSON excessivamente grandes ou estruturas profundas, especialmente se feitos por usuários que normalmente não operam com notebooks Jupyter. A revisão de logs de acesso por requisições diff_stream que envolvem esses arquivos também pode revelar o vetor de disparo.

  • Falhas ou crashes no processo Puma durante renderização de diffs
  • Criação de arquivos .ipynb com JSON grande ou profundamente aninhado
  • Tráfego de saída não usual originado da conta de serviço git
  • Requisições diffs_stream consecutivas para arquivos de notebook
Mitigação

A única mitigação confirmada e eficaz é a atualização para uma versão corrigida do GitLab que inclua a dependência Oj 3.17.3. Operadores de instâncias self-managed devem planejar imediatamente a atualização para as versões 18.10.8, 18.11.5 ou 19.0.2. É crucial notar que, para implantações via Helm ou Operator, a versão do GitLab dentro da imagem Webservice deve ser verificada, não apenas a versão do chart ou operador, para garantir que o binário corrigido esteja em execução.

Não há solução temporária oficial documentada pela disclosures ou nas notas de lançamento da GitLab além da atualização. A aplicação de correções deve seguir o ciclo de manutenção padrão, mas deve ser tratada com prioridade crítica devido à baixa barreira de exploração (apenas necessidade de autenticação) e ao alto impacto potencial. A verificação de pós-atualização deve incluir a confirmação da versão da gem Oj carregada pelo ambiente Ruby.

  • Atualizar para GitLab 18.10.8, 18.11.5 ou 19.0.2
  • Verificar a versão do GitLab dentro da imagem Webservice em implantações Kubernetes
  • Auditar logs de acesso e erros de aplicação por anomalias em arquivos .ipynb
  • Restringir o upload de arquivos .ipynb se o uso de notebooks não for uma necessidade de negócios

Postar um comentário

0 Comentários