Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2024-27198 — Análisis detallado de CVE-2024-27198: omisión de autenticación en JetBrains TeamCity que conduce a la ejecución remota de código, con explicación a nivel de código y demostración del exploit. | Kitploit
Herramientas/GitHubGitHub/hpt-intern-task-submission/cve-2024-27198
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAutenticaciónAprendizaje y Educación
GitHubhpt-intern-task-submission/cve-2024-27198

CVE-2024-27198

Análisis detallado de CVE-2024-27198: omisión de autenticación en JetBrains TeamCity que conduce a la ejecución remota de código, con explicación a nivel de código y demostración del exploit.

Ver Repositorio
6hace 2 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2024-27198: La omisión de autenticación en Jetbrain Teamcity conduce a ejecución remota de código

Overview

TeamCity es un servidor de integración continua y despliegue que proporciona, de serie, pruebas unitarias continuas, análisis de calidad de código e informes tempranos sobre problemas de compilación.

La vulnerabilidad aparece en una librería que permite a los atacantes acceder a endpoints arbitrarios sin autenticación.

Code Analysis

El código vulnerable se encuentra en la librería web-openapi.jar en directory to the lib

La clase jetbrains.buildServer.controllers.BaseController se encarga de manejar las peticiones y respuestas, aunque está implementada de forma incorrecta. Veamos cómo es el código:

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);  
            }  
        }

El propósito principal del método ModelAndView es representar la página solicitada en la interfaz de usuario. Aquí es donde comienza el bug. Observa que updateViewIfRequestHasJspParameter se llamará si nuestra petición no está siendo redirigida. Para encontrar la causa raíz de la vulnerabilidad, necesitamos investigar más a fondo para entenderlo.

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 se utiliza para actualizar el nombre de la vista del objeto ModelAndView cuando se cumplen ciertas condiciones. isControllerRequestWithViewName será True si el objeto modelAndView tiene un nombre y la path en la URL no termina en .jsp. Por ejemplo, una URL que cumple esas condiciones es http://localhost:8111/random_string y una inválida será http://localhost:8111/admin/admin.html o http://localhost:8111/admin.jsp. Como se discutió anteriormente, no debemos acceder a algo que provoque una redirección; normalmente serán páginas que requieren autorización. El programa asignará entonces una variable llamada jspFromRequest que llamará al método getJspFromRequest(). Pasemos ahora a ese método; explicaré el resto del código después. Hay una sentencia if que comprobará si isControllerRequestWithViewName es verdadero, si el resultado de la llamada al método getJspFromRequest() no está vacío y si el nombre del objeto modelAndView no debe ser igual a la página que queremos solicitar mediante

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

Esta función primero recupera el valor de un parámetro de petición llamado jsp. La comprobación asegura que jsp debe terminar en .jsp y no debe contener /admin. Combinando con la sentencia if anterior:

if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  

Tendremos una visión general de cómo se ve la URL:

  1. La ruta no debe provocar redirección ni contener .jsp
  2. El parámetro de petición jsp no debe ser igual a la path. Por ejemplo, /random?jsp=/random será inválido
  3. Lo más importante, jsp debe terminar en .jsp

TeamCity proporciona una API REST para integrar aplicaciones externas y crear interacciones mediante scripts con el servidor TeamCity. Permite acceder a los recursos a través de rutas URL. Puedes empezar a trabajar con la API REST abriendo la URL http://<TeamCity Server host>:<port>/app/rest/server en tu navegador: esta página ofrece varios enlaces para explorar la API.

Teamcity ofrece una API REST que nos permite acceder a recursos sensibles si podemos evadir la autenticación. En este caso, por ejemplo, intentaremos acceder a /app/rest/server.

unauthenticated_request

Como es habitual, el servidor nos redirigirá a /login.html cuando solicitemos /app/rest/server. Construyamos una URL perfecta para evadir esta restricción. Primero, nuestra ruta puede ser cualquier cosa siempre que devuelva un código de estado 404 o incluso 200, como login.html. A continuación, usaremos jsp para solicitar /app/rest/server, pero debe terminar en .jsp. En esta situación, incluso hay 2 trucos que podemos usar para evadir esta comprobación. Podemos usar el punto y coma ; como delimitador de parámetros: /app/rest/server;.jsp; esta vez, .jsp se tratará como un segundo parámetro. La segunda evasión es usar el fragmento de URI #: /app/rest/server%23.jsp. Lo que va después del fragmento de URI no se usará para el enrutamiento, solo se usa para la navegación dentro de una página. Ten en cuenta que el carácter debe estar codificado en URL; de lo contrario, el navegador lo ignorará primero.

unauthenticated_request_bypass.png

Con esta técnica, incluso podemos crear un nuevo usuario con privilegios de administrador. La documentación de Teamcity dice que podemos crear un nuevo usuario mediante este endpoint /app/rest/users.

create_new_user

Vayamos al panel de administración y comprobemos si se ha creado algún usuario nuevo.

confirmed

Como era de esperar, se crea un nuevo usuario con privilegios de administrador. Con los privilegios de administrador, podemos controlar completamente el servidor. Sin embargo, podemos ir aún más lejos obteniendo ejecución remota de código. Este CVE afecta a todas las versiones anteriores a 2023.11.4, pero este RCE solo es posible en versiones anteriores a 2023.11. Hay un endpoint no documentado /app/rest/debug/processes que permite a un usuario con privilegios de administrador ejecutar comandos arbitrarios. Enviaremos una petición POST con 2 parámetros de petición en la URL de la solicitud. Para Windows, será ?exePath=cmd.exe&params=/c%20[our command here] y con Linux será ?exePath=/bin/sh&params=-c%20[our command here]. Estoy ejecutando Teamcity en Windows, por lo que la ruta completa será /app/rest/debug/processes?exePath=cmd.exe&params=/c%20whoami

failed_attempt

El servidor devuelve un error 403 indicando que la petición carece de csrf token. La documentación de Teamcity también nos proporciona el endpoint para recuperar el token, que es /authenticationTest.html?csrf.

Después de recuperar el token, lo añadiremos a la cabecera de la petición X-TC-CSRF-Token o al parámetro HTTP tc-csrf-token; aquí elijo X-TC-CSRF-Token.

Descargar herramienta