Pesquisadores de segurança da depthfirst publicaram, em 24 de julho, um código de exploit funcional para uma falha no GitLab que a própria empresa havia corrigido seis semanas antes, em 10 de junho.
O código executa comandos como o usuário git em qualquer servidor autogerenciado com GitLab 18.11.3 que ainda não tenha recebido a atualização.
Qualquer usuário autenticado com permissão para enviar alterações a um projeto pode acioná-lo.
O atacante faz um commit de um notebook Jupyter especialmente preparado e abre o diff desse commit, o que vaza um ponteiro de heap.
Com informação suficiente desse tipo, uma verificação automatizada consegue localizar as bibliotecas na memória.
Depois, mais dois notebooks disparam o payload.
Não há necessidade de privilégios de administrador, acesso ao CI ou aos runners, interação da vítima ou acesso ao projeto de terceiros.
O GitLab não classificou a correção como uma atualização de segurança.
A atualização do Oj para a versão 3.17.3 apareceu listada em correções de bug no pacote de 10 de junho, e não na tabela de correções de segurança.
Não houve CVE, nem pontuação CVSS, nem menção à cadeia envolvendo o diff do notebook.
Para quem avaliou essa versão apenas com base na tabela de segurança, não havia motivo para tratá-la como urgente.
A cadeia funciona por causa de duas falhas de corrupção de memória no Oj, um analisador JSON em Ruby implementado em grande parte em C nativo.
A depthfirst afirma que seu sistema detectou os problemas de forma autônoma, e os pesquisadores encadearam as falhas manualmente.
O renderizador de notebooks do GitLab, um gem interno chamado ipynbdiff, passa JSON de arquivos .ipynb controlados pelo repositório para Oj::Parser.usual.parse dentro de um worker Puma de longa duração.
Isso faz com que bytes controlados pelo atacante cheguem à memória C gerenciada manualmente pelo Oj dentro do processo da aplicação.
Uma das falhas grava além de uma pilha fixa de 1.024 bytes de aninhamento até assumir o controle do callback de início do analisador.
A outra trunca uma chave de objeto de 65.565 bytes para 29 em um campo inteiro assinado de 16 bits e retorna um ponteiro válido de heap, que o GitLab renderiza no diff.
O vazamento localiza a libc, e a escrita aponta o callback para system().
Componente | Afetado | Primeiro ajuste
GitLab CE/EE | 15.2.0 até 18.10.7 | 18.10.8
GitLab CE/EE | 18.11.0 até 18.11.4 | 18.11.5
GitLab CE/EE | 19.0.0 até 19.0.1 | 19.0.2
Oj gem | 3.13.0 até 3.17.1 | 3.17.3
Todas as edições são afetadas, tanto CE quanto EE, do Free ao Ultimate.
O Ruby em si não é afetado.
O Oj 3.17.2 trouxe outras correções da mesma revisão, mas não essas duas.
A recomendação é atualizar para 18.10.8, 18.11.5 ou 19.0.2.
Nem o GitLab nem a depthfirst oferecem uma alternativa para quem não puder fazer a atualização.
O ponto de atenção está em Helm e Operator: é preciso verificar a versão do GitLab dentro da imagem Webservice que executa o Puma, e não a versão do chart ou do Operator.
Qualquer instalação entre 15.2 e 18.9 não recebe backport, porque essas linhas estão fora dos ciclos de correções mantidos com suporte de segurança do GitLab.
Nesses casos, a instalação precisa migrar para uma versão suportada.
Os comandos são executados como git, a conta por trás do Puma.
Até onde isso pode ir depende de como a instalação está isolada.
O alcance pode incluir código-fonte, segredos do Rails, credenciais de serviços, dados de CI/CD e serviços internos com os quais a aplicação consiga se comunicar.
O exploit público foi desenvolvido para GitLab 18.11.3 em x86-64.
Os offsets dos gadgets, o estado dos registradores e o comportamento do jemalloc vieram dessa imagem, e uma base de biblioteca recuperada só permanece válida até a reinicialização do processo mestre do Puma.
Portanto, não se trata de algo pronto para uso contra qualquer alvo.
As falhas no Oj são genéricas, mas portar o exploit exige trabalho real.
A depthfirst mediu entre cinco e dez minutos para a busca na memória em uma instalação nova com dois workers e estima de uma a duas horas em instalações mais antigas.
A depthfirst reportou as falhas no Oj em 21 de maio, o mantenedor incorporou as correções em 27 de maio e o Oj 3.17.3 foi lançado em 4 de junho.
A cadeia no GitLab foi enviada ao GitLab em 5 de junho, confirmada em 8 de junho e corrigida em 10 de junho.
A depthfirst diz não ter conhecimento de exploração em ambiente real e afirma que o GitLab reproduziu o RCE de forma independente.
A revisão mais ampla do Oj resultou em mais nove avisos de CVE, nenhum deles relacionado a essa cadeia.
O GitLab foi questionado sobre o motivo de a correção não ter sido tratada como um problema de segurança e sobre a eventual atribuição de um CVE, além de a depthfirst ter sido perguntada sobre a portabilidade do exploit.
As respostas ainda não foram enviadas.
Publicidade
Vibecoding cria 10x mais sistemas, 20x mais vulneráveis. E quem ganha com isso é a galera do hacking ético e pentest. Quer ser pago para invadir sistemas? Então você tem que aprender com a Solyd que são os melhores do Brasil. Saiba mais...