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
Ferramentas/GitHubGitHub/hpt-intern-task-submission
/cve-2024-27198
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoAutenticaçãoAprendizado e Educação
GitHubhpt-intern-task-submission/cve-2024-27198

CVE-2024-27198

Análise detalhada de CVE-2024-27198: bypass de autenticação no JetBrains TeamCity levando a execução remota de código, com explicação em nível de código e demonstração de exploit.

Ver Repositório
1há 2 anosAinda 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

CVE-2024-27198: Bypass de autenticação no Jetbrain Teamcity leva à execução remota de código

======================

Visão Geral

TeamCity é um servidor de Integração Contínua e Implantação que fornece testes unitários contínuos prontos para uso, análise de qualidade de código e relatórios antecipados de problemas de build.

A vulnerabilidade aparece em uma biblioteca que permite que atacantes acessem endpoints arbitrários não autenticados.

Análise de Código

O código vulnerável está na biblioteca web-openapi.jar em directory to the lib.

A classe jetbrains.buildServer.controllers.BaseController é responsável por lidar com requisições e respostas, mas foi implementada de forma inadequada. Vejamos como o código se parece:

root@kitploit:~
public abstract class BaseController extends AbstractController {
//////
public final ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    try {  
        ModelAndView modelAndView = this.doHandle(request, response);  
        if (modelAndView != null) {  
            if (modelAndView.getView() instanceof RedirectView) {  
                modelAndView.getModel().clear();  
            } else {  
                this.updateViewIfRequestHasJspParameter(request, modelAndView);  
            }  
        }

O objetivo principal do método ModelAndView é renderizar a página solicitada na interface do usuário. É aqui que o bug começa. Observe que updateViewIfRequestHasJspParameter será chamado se nossa requisição não estiver sendo redirecionada. Para encontrar a causa raiz da vulnerabilidade, precisamos investigar mais a fundo para entender.

root@kitploit:~
private void updateViewIfRequestHasJspParameter(@NotNull HttpServletRequest request, @NotNull ModelAndView modelAndView) {  
    boolean isControllerRequestWithViewName = modelAndView.getViewName() != null && !request.getServletPath().endsWith(".jsp");  
    String jspFromRequest = this.getJspFromRequest(request);  
    if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  
  
}

Este método é usado para atualizar o nome da visão do objeto ModelAndView quando ele atende a condições específicas. O isControllerRequestWithViewName será True se o objeto modelAndView tiver um nome e o path na URL não terminar com .jsp. Por exemplo, uma URL que satisfaz essas condições é http://localhost:8111/random_string e uma inválida será http://localhost:8111/admin/admin.html ou http://localhost:8111/admin.jsp. Como discutido acima, não devemos acessar algo que acione redirecionamento; normalmente, serão páginas que exigem autorização. O programa então atribuirá uma variável chamada jspFromRequest que chamará o método getJspFromRequest(). Vamos agora mudar para esse método; explicarei o restante do código depois. Há uma instrução if que verifica se é verdadeiro, o resultado da chamada ao método não está vazio e o nome do objeto não deve ser igual à página que queremos solicitar via

root@kitploit:~
protected String getJspFromRequest(@NotNull HttpServletRequest request) { String  jspFromRequest  = request.getParameter("jsp"); return  jspFromRequest  == null || jspFromRequest.endsWith(".jsp") && !jspFromRequest.contains("admin/") ? jspFromRequest : null; }

Esta função primeiro recuperará o valor de um parâmetro de requisição chamado jsp. A verificação garante que jsp deve terminar com .jsp e não deve conter /admin. Combinando com a instrução if acima:

root@kitploit:~
if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  

Teremos uma visão geral de como a URL se parece:

  1. O caminho não deve acionar redirecionamento nem conter .jsp
  2. O parâmetro de requisição jsp não deve ser igual ao path. Por exemplo, /random?jsp=/random será inválido
  3. Mais importante ainda, jsp deve terminar com .jsp

O TeamCity fornece uma API REST para integrar aplicações externas e criar interações de script com o servidor TeamCity. Ela permite acessar recursos por meio de caminhos de URL. Você pode começar a trabalhar com a API REST abrindo a URL http://<TeamCity Server host>:<port>/app/rest/server no seu navegador: esta página fornece várias referências para explorar a API.

O TeamCity oferece uma API REST que nos permite acessar recursos sensíveis se pudermos contornar a autenticação. Neste caso, por exemplo, tentaremos acessar /app/rest/server.

unauthenticated_request

Como de costume, o servidor nos redirecionará para /login.html quando solicitarmos /app/rest/server. Vamos construir uma URL perfeita para contornar essa restrição. Primeiro, nosso caminho pode ser qualquer coisa, desde que retorne o código de status 404 ou até mesmo 200, como login.html. Em seguida, usaremos jsp para solicitar /app/rest/server, mas ele deve terminar com .jsp. Nesta situação, ainda existem 2 truques que podemos usar para contornar essa verificação. Podemos usar ponto e vírgula ; como delimitador de parâmetro: /app/rest/server;.jsp; desta vez, o .jsp será tratado como um segundo parâmetro. A segunda forma de contornar é usar o fragmento de URI #: /app/rest/server%23.jsp. O que vem depois do fragmento de URI não será usado para roteamento, apenas para navegação em uma página. Observe que o caractere precisa ser codificado em URL; caso contrário, o navegador o ignorará primeiro.

unauthenticated_request_bypass.png

Com essa técnica, podemos até criar um novo usuário com Privilégio de Administrador. A documentação do TeamCity disse que podemos criar um novo usuário por meio deste endpoint /app/rest/users.

create_new_user

Vamos ao painel de administração e verificar se algum novo usuário foi criado.

confirmed

Como esperado, um novo usuário com Privilégio de Administrador é criado. Com privilégio de administrador, podemos controlar totalmente o servidor. No entanto, podemos ir ainda mais longe obtendo execução remota de código. Este CVE é aplicável a todas as versões anteriores à 2023.11.4, mas esse RCE só é possível em versões anteriores à 2023.11. Existe um endpoint não documentado /app/rest/debug/processes que permite que um usuário com privilégio de administrador execute comandos arbitrários. Enviaremos uma requisição POST com 2 parâmetros de requisição na URL. Para Windows, será ?exePath=cmd.exe&params=/c%20[our command here] e com Linux será ?exePath=/bin/sh&params=-c%20[our command here]. Estou executando o TeamCity no Windows, então o caminho completo será /app/rest/debug/processes?exePath=cmd.exe&params=/c%20whoami.

failed_attempt

O servidor retornou um erro 403 dizendo que a requisição não possui csrf token. A documentação do TeamCity também nos fornece o endpoint para recuperar o token, que é /authenticationTest.html?csrf.

Após recuperar o token, vamos adicioná-lo ao cabeçalho da requisição X-TC-CSRF-Token ou ao parâmetro HTTP tc-csrf-token; aqui escolho X-TC-CSRF-Token.

done

Após fornecer o csrf token, conseguimos executar comandos remotamente, dando-nos controle total sobre o servidor.

Neste CVE, a falha de segurança não estava na validação de entrada, mas na lógica do código. Esta aplicação é realmente complicada; de alguma forma, os desenvolvedores acabam cometendo erros. Também aprendemos uma nova técnica para contornar a autenticação. Espero que você tenha aprendido algo útil com esta análise. Feliz hacking!!!

Baixar ferramenta
isControllerRequestWithViewName
getJspFromRequest()
modelAndView