
CVE-2026-46394 के लिए PoC और लेख: HAXcms Git.php में OS कमांड इंजेक्शन (CWE-78)। केवल अधिकृत सुरक्षा अनुसंधान के लिए।
Git.php OS कमांड इंजेक्शन (CWE-78)केवल अधिकृत सुरक्षा परीक्षण और शोध के लिए प्रूफ-ऑफ-कॉन्सेप्ट। यहाँ वर्णित भेद्यता HAXcms के नवीनतम रिलीज़ में ठीक कर दी गई है। यह PoC इसलिए प्रकाशित किया गया है ताकि रक्षक और शोधकर्ता उन अप्रचलित इंस्टेंस पर समस्या की पुष्टि कर सकें जिनके वे मालिक हैं या जिनका परीक्षण करने के लिए उन्हें स्पष्ट रूप से अधिकृत किया गया है।
| CVE | CVE-2026-46394 |
| घटक | HAXcms PHP बैकएंड - system/backend/php/lib/Git.php |
| भेद्यता | OS कमांड इंजेक्शन (CWE-78) |
| गंभीरता | उच्च - CVSS 3.1 7.2 अकेले / 8.1 पथ ट्रैवर्सल के साथ श्रृंखलित |
| स्थिति | ऊपर की ओर ठीक किया गया। पैच से पहले के रिलीज़ को प्रभावित करता है। |
| प्रोजेक्ट | elmsln/HAXcms |
| रिपोर्टर | श्रेयस चल्ला ([email protected]) |
HAXcms PHP बैकएंड में Git.php लाइब्रेरी असंग्रहित पैरामीटर को जोड़कर शेल कमांड स्ट्रिंग बनाती है और उन्हें सीधे proc_open() को भेजती है। शेल कमांड को निष्पादित करने वाले 17 फ़ंक्शनों में से केवल एक (commit()) escapeshellarg() का उपयोग करता है। शेष 15 कॉलर इनपुट को सीधे कमांड स्ट्रिंग में इंटरपोलेट करते हैं।
कोई भी मान जिसमें शेल मेटाकैरेक्टर (&, ;, |, $(), बैकटिक्स) हो और जो इनमें से किसी फ़ंक्शन तक पहुँचता है, वेब-सर्वर उपयोगकर्ता के रूप में मनमाना OS कमांड निष्पादन का परिणाम देता है।
एकमात्र सही ढंग से एस्केप किया गया फ़ंक्शन सबसे स्पष्ट सबूत है कि एस्केपिंग को समझा गया था और बाकी सभी जगहों पर बस छोड़ दिया गया।
प्रत्येक संवेदनशील फ़ंक्शन run() → run_command() → proc_open() के माध्यम से प्रवाहित होता है:
// Git.php:408-411 - एक रॉ कमांड स्ट्रिंग बनाता है
public function run($command) {
return $this->run_command(Git::get_bin() . " " . $command);
}
// Git.php:383 - इसे सिस्टम शेल के माध्यम से निष्पादित करता है
$resource = proc_open($command, $descriptors, $pipes, $this->repo_path, $env);
संवेदनशील उदाहरण बनाम एक सुरक्षित फ़ंक्शन:
// Git.php:574 - संवेदनशील (कोई एस्केपिंग नहीं)
public function create_branch($branch) {
return $this->run("branch $branch");
}
// Git.php:496 - सुरक्षित (साबित करता है कि लेखक पैटर्न जानता था)
public function commit($message = "") {
return $this->run("commit -av -m " . escapeshellarg($message));
}
| फ़ंक्शन | पंक्ति | शेल कमांड | एस्केप किया गया? |
|---|---|---|---|
create_branch($branch) | 574 | branch $branch | नहीं |
delete_branch($branch) | 588 | branch -d $branch | नहीं |
checkout($branch) | 663 | checkout $branch | नहीं |
merge($branch) | 677 | merge $branch --no-ff | नहीं |
push($remote, $branch) | 785 | push $remote $branch $flags | नहीं |
pull($remote, $branch) | 799 | pull $remote $branch | नहीं |
log($format) | 813 | log --pretty=format:"$format" | नहीं |
show($commit, $format) | 830 | show --pretty=format:"$format" $commit | नहीं |
list_tags($pattern) | 763 | tag -l $pattern | नहीं |
clone_to($target) | 512 | clone --local $repo $target | नहीं |
clone_from($source) | 527 | clone --local $source $repo | नहीं |
clone_remote($source) | 543 | clone $source $repo | नहीं |
set_remote($dest, $url) | 460 | remote add $dest $url | नहीं |
rm($files) |
शिप किए गए कोडबेस में ये फ़ंक्शन सर्वर/साइट कॉन्फ़िगरेशन से प्राप्त मानों के साथ आह्वान किए जाते हैं, न कि सीधे अनुरोध निकायों से, इसलिए शोषण श्रृंखला द्वारा महसूस किया जाता है:
site.json को ओवरराइट करने के लिए saveOutline पथ ट्रैवर्सल का उपयोग करें, metadata.site.git.branch में मेटाकैरेक्टर इंजेक्ट करें। अगला gitCommit() HAXCMSSite.php:584 पर push('origin', $branch) को कॉल करता है, पेलोड निष्पादित करता है।create_branch() (Operations.php:2762) या set_remote() (HAXCMSSite.php:625) तक पहुँचता है।PoC वास्तविक Git.php लाइब्रेरी को सीधे चलाता है: यह एक थ्रोअवे git रिपॉजिटरी बनाता है, create_branch() को एक पेलोड के साथ कॉल करता है जो शेल कमांड विभाजक का उपयोग करता है, और डिस्क पर लिखी गई प्रूफ फ़ाइल की जाँच करके निष्पादन की पुष्टि करता है। यह अपने बाद सफाई करता है।
git PATH परgit clone https://github.com/elmsln/HAXcms.git
git clone https://github.com/shreyas-challa/CVE-2026-46394-haxcms-git-command-injection.git
cd CVE-2026-46394-haxcms-git-command-injection
PoC को अपने HAXcms क्लोन से Git.php की ओर इंगित करें (env var या पहला तर्क); यह इसके बगल में रखे गए haxcms-php/ को भी स्वचालित रूप से खोजता है:
# विकल्प A - पर्यावरण चर
HAXCMS_PHP=../HAXcms/haxcms-php/system/backend/php/lib/Git.php php poc_git_cmdi.php
# विकल्प B - CLI तर्क
php poc_git_cmdi.php ../HAXcms/haxcms-php/system/backend/php/lib/Git.php
यूनिक्स (; विभाजक) और विंडोज (& विभाजक) दोनों पर काम करता है; PoC होस्ट OS के लिए सही पेलोड स्वचालित रूप से चुनता है।
================================================================
HAXcms Git.php - OS कमांड इंजेक्शन (CWE-78)
================================================================
STEP 3: create_branch() के माध्यम से OS कमांड इंजेक्ट करें
पेलोड: test & echo COMMAND_INJECTION_PROOF > "...\PWNED.txt"
STEP 4: सत्यापित करें कि इंजेक्टेड कमांड निष्पादित हुआ
FILE FOUND!
Content: COMMAND_INJECTION_PROOF
COMMAND INJECTION CONFIRMED.
सभी 15 फ़ंक्शनों में प्रत्येक पैरामीटर पर escapeshellarg() लागू करें:
// पहले
public function create_branch($branch) {
return $this->run("branch " . $branch);
}
// बाद में
public function create_branch($branch) {
return $this->run("branch " . escapeshellarg($branch));
}
गहराई में रक्षा - मानों को git स्तर तक पहुँचने से पहले मान्य करें:
function validateBranchName($branch) {
return preg_match('/^[a-zA-Z0-9._\/-]+$/', $branch) && strpos($branch, '..') === false;
}
नवीनतम HAXcms रिलीज़ पर अपडेट करें, जिसमें ऊपर की ओर फिक्स शामिल है।
यह मुद्दा HAXcms अनुरक्षकों को सूचित किया गया और प्रकाशन से पहले ठीक कर दिया गया। PoC केवल पैच उपलब्ध होने के बाद जारी किया गया है। इसका उपयोग केवल उन प्रणालियों के खिलाफ करें जिनके आप मालिक हैं या जिनका परीक्षण करने के लिए आपको स्पष्ट रूप से अधिकृत किया गया है।
यह सामग्री रक्षात्मक अनुसंधान, शिक्षा और अधिकृत सुरक्षा परीक्षण के लिए प्रदान की जाती है। स्पष्ट अनुमति के बिना प्रणालियों के खिलाफ इसे चलाना अवैध हो सकता है। सभी लागू कानूनों का पालन करने और परीक्षण करने से पहले प्राधिकरण प्राप्त करने के लिए आप पूरी तरह से जिम्मेदार हैं। बिना किसी वारंटी के "जैसा है" प्रदान किया गया (LICENSE देखें)।
| 479 |
rm $files |
| नहीं |
add_tag($tag, $msg) | 749 | tag -a $tag -m $msg | $tag: नहीं, $msg: हाँ |
commit($message) | 496 | commit -av -m $message | हाँ (केवल सुरक्षित) |