
चरण-दर-चरण तकनीकी विश्लेषण CVE-2019-1698 का, जो एक WordPress प्लगइन SQL इंजेक्शन भेद्यता है, जिसमें कोड डिफ़ समीक्षा, संवेदनशील फ़ंक्शन की पहचान, और curl का उपयोग करके शोषण प्रदर्शन शामिल है।
कोड संदर्भ 1: https://plugins.trac.wordpress.org/changeset/3040809/notificationx/trunk/includes/Core/Rest/Analytics.php

कोड संदर्भ 2: https://plugins.trac.wordpress.org/changeset/3040809/notificationx/trunk/includes/Core/Database.php

इसलिए, निम्न फ़ाइल इस CVE से संबंधित है:
wp-content/plugins/notificationx/includes/Core/Rest/Analytics.php
अब, हम जाँचेंगे कि फ़ाइल में भेद्य कोड हो सकता है:
insert_analytics() फ़ंक्शन पर ध्यान दें:
यह (उपयोगकर्ता से आने वाला) प्राप्त करता है और पैरामीटर निकालता है।
$requesttypeफिर, यह मान CoreAnalytics::get_instance()->insert_analytics() फ़ंक्शन को पास कर दिया जाता है:

इस कोड को ट्रिगर करने के लिए, हम मैप किए गए रूट को देख सकते हैं (Analytics क्लास से, register_routes() फ़ंक्शन के अंदर):
$this->namespace . '/' . $this->rest_base
और Analytics क्लास का कंस्ट्रक्टर namespace और rest_base वेरिएबल्स के मान दिखाता है:
public function __construct() {
$this->namespace = 'notificationx/v1';
$this->rest_base = 'analytics';
add_action('rest_api_init', [$this, 'register_routes']);
}
इसलिए, प्रासंगिक (भेद्य) कोड जो उपयोगकर्ता द्वारा आपूर्ति किए गए type पैरामीटर को स्वीकार करता है, निम्न रूट के माध्यम से पहुँचा जा सकता है:
notificationx/v1/analytics
लेकिन शोषण करने का तरीका क्या है और इंजेक्शन के लिए SQL क्वेरी कहाँ है?
चूँकि उपयोगकर्ता द्वारा आपूर्ति किया गया type पैरामीटर निम्न को पास किया जाता है:
CoreAnalytics::get_instance()->insert_analytics( absint( $params['nx_id'] ), $type );
इस फ़ंक्शन का पता लगाना:
आइए हाइलाइट की गई फ़ाइल में इस फ़ंक्शन कोड की जाँच करें:
wp-content/plugins/notificationx/includes/Core/Analytics.php::

यदि आप सोच रहे हैं कि भेद्यता increment_count() फ़ंक्शन में है, तो आप बिल्कुल सही रास्ते पर हैं!
यह रहा increment_count फ़ंक्शन (और इसमें उपयोगकर्ता से आने वाला $type पैरामीटर है):

यह फ़ंक्शन आगे update_analytics() फ़ंक्शन को कॉल करता है। आइए इसे देखें:


update_analytics फ़ंक्शन SQL क्वेरी को गतिशील रूप से बनाता है और बिना सैनिटाइज़ किया गया उपयोगकर्ता इनपुट इसका हिस्सा होता है। संदिग्ध लगता है? ऐसा ही होना चाहिए, क्योंकि यही भेद्यता का कारण है।
$col पैरामीटर HTTP अनुरोध में उपयोगकर्ता द्वारा भेजे गए type पैरामीटर के अनुरूप है।
$table_name इस पर सेट है: nx_stats:
public function __construct() {
global $wpdb;
$this->wpdb = $wpdb;
self::$table_entries = $wpdb->prefix . 'nx_entries';
self::$table_posts = $wpdb->prefix . 'nx_posts';
self::$table_stats = $wpdb->prefix . 'nx_stats';
}
सही verb की पहचान करने के लिए, मैंने WordPress REST API का उपयोग किया:
http://localhost/wp-json/

/notificationx/v1/analytics API रूट को POST अनुरोध द्वारा ट्रिगर किया जा सकता है और हमें nx_id (एक पूर्णांक) और (वैकल्पिक रूप से) type (एक स्ट्रिंग) पास करना होता है।
याद रखें, कि analytics जानकारी nx_stats नामक तालिका में अपडेट की गई थी, जिसे हमने पहले wp-content/plugins/notificationx/includes/Core/Database.php के इन कोड स्निपेट्स का उपयोग करके निकाला था:
public function __construct() {
global $wpdb;
$this->wpdb = $wpdb;
self::$table_entries = $wpdb->prefix . 'nx_entries';
self::$table_posts = $wpdb->prefix . 'nx_posts';
self::$table_stats = $wpdb->prefix . 'nx_stats';
}
$table_name = self::$table_stats;

हमारी योजना यह देखने की है कि जब हम अनुरोध में अपना payload पास करते हैं तो निर्मित SQL क्वेरी क्या होती है।
और अब, हम अपना curl (SQLi payload के साथ) अनुरोध फिर से भेजेंगे:
time curl http://localhost:8080/wp-json/notificationx/v1/analytics -d 'nx_id=1337&type=clicks`=IF(SUBSTRING(version(),1,1)=5,SLEEP(10),null)-- -'
