PHP Object Injection Vulnerability in VideoWhisper Live Streaming
Recently we found that the plugin VideoWhisper Live Streaming contained a PHP object injection vulnerability.
The plugin makes the function vwls_calls() available through WordPress’ AJAX functionality whether the requester is logged in to WordPress or not (in the file /videowhisper_streaming.php ):
94 95 | add_action( 'wp_ajax_vwls', array('VWliveStreaming','vwls_calls')); add_action( 'wp_ajax_nopriv_vwls', array('VWliveStreaming','vwls_calls')); |
In that function the value of the GET input “task” is used for a switch statement:
6767 | switch ($_GET['task']) |
As of version 4.67.8, when that is set to “rtmp_status” the value of the POST input “users” is unserialized, which permits PHP object injection to occur:
7962 7963 7964 | case 'rtmp_status': $users = unserialize(stripslashes($_POST['users'])); |
After we notified the developer they made changes that at least limit the ability to exploit this. Here is the relevant code as version 4.67.12:
80111 80112 80113 80114 80115 80116 80117 80118 80119 80120 80121 80122 80123 80124 80125 80126 80127 80128 | case 'rtmp_status': $options = get_option('VWliveStreamingOptions'); //allow such requests only if feature is enabled (by default is not) if ($options['webStatus'] != 'enabled') VWliveStreaming::rexit('denied=webStatusNotEnabled-' . $options['webStatus']); //allow only status updates from configured server IP if ($options['rtmp_restrict_ip']) { if (VWliveStreaming::get_ip_address() != trim($options['rtmp_restrict_ip'])) VWliveStreaming::rexit('denied=NotFromAllowedIP'); } else VWliveStreaming::rexit('denied=StatusServerIPnotConfigured'); $userdata = stripslashes($_POST['users']); if (version_compare(phpversion(), '7.0', '<')) $users = unserialize($userdata); //request is from trusted server else $users = unserialize($userdata, false); |
Before getting to unserialization, a feature needs to be enabled and the request needs to appear to come from an permitted IP address (there is the possibility that the IP address could be spoofed, but you would need to guess or know the IP address when doing that). For those running at least PHP 7.0, the option to not accept any classes when unserializing should also at least limit PHP object injection from occurring if you could get past the two previous restrictions.
Proof of Concept
With our plugin for testing for PHP object injection installed and activated, the following proof of concept will cause the message “PHP object injection has occurred.” to be shown.
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?task=rtmp_status" method="POST"> <input type="hidden" name="action" value="vwls" /> <input type="hidden" name="users" value='O:20:"php_object_injection":0:{}' /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- August 30, 2017 – Developer notified.
- August 30, 2017 – Version 4.67.9-4.67.11 released, which at least limit exploitation of vulnerability.