Authenticated Local File Inclusion (LFI) Vulnerability in PluginOps Page Builder
As we discussed in a previous post, while reviewing the changes in a recent version of the plugin PluginOps Page Builder we found that a local file inclusion version vulnerability had recently been fixed in the plugin. In looking over the changes that fixed that, we found that there was still a limited authenticated local file inclusion (LFI) vulnerability in the plugin.
In the file /admin/admin.php the plugin registered a shortcode:
71 72 | add_shortcode( 'pb_samlple_nav', array($this,'pb_shortcode_sample_nav' ) ); |
The beginning of the function called by that looked like this as of the original version of 1.4.3:
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | function pb_shortcode_sample_nav($atts, $content){ if( current_user_can('editor') || current_user_can('administrator') ) { ob_start(); extract( shortcode_atts( array( 'pb_menu' => '', 'pb_logo_url' => '', 'menucolor' => '', 'menu_class' => '', 'menu_font' => '', ), $atts ) ); $menuName = $pb_menu; $pageLogoUrl = $pb_logo_url; $menuColor = $menucolor; $menufont = $menu_font; include(ULPB_PLUGIN_PATH.'admin/views/menus/'.$menu_class.'.php'); |
The first thing the function does is to check to make sure the user to access the function is and Editor or Administrator.
At the bottom of the code you can see that a file is included. The value of the variable $menu_class, which is part of the file to be included comes from an attribute from the shortcode. There was no restriction on directory traversal being included in that, so that files outside of the directory that files are intended to be included from can be accessed.
IT would have also been possible to exploit this through cross-site request forgery (CSRF) through WordPress’ ability to access shortcodes through AJAX.
In a later version of 1.4.3 the file /admin/admin.php was moved to /admin/classes/admin.php and the code in the function pb_shortcode_sample_nav() to restrict what can be included to the intended files:
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | function pb_shortcode_sample_nav($atts, $content){ if( current_user_can('editor') || current_user_can('administrator') ) { ob_start(); extract( shortcode_atts( array( 'pb_menu' => '', 'pb_logo_url' => '', 'menucolor' => '', 'menu_class' => '', 'menu_font' => '', ), $atts ) ); $menuName = $pb_menu; $pageLogoUrl = $pb_logo_url; $menuColor = $menucolor; $menufont = $menu_font; switch ($menu_class) { case 'menu-style-1': include(ULPB_PLUGIN_PATH.'admin/views/menus/menu-style-1.php'); break; case 'menu-style-2': include(ULPB_PLUGIN_PATH.'admin/views/menus/menu-style-2.php'); break; case 'menu-style-3': include(ULPB_PLUGIN_PATH.'admin/views/menus/menu-style-3.php'); break; case 'menu-style-4': include(ULPB_PLUGIN_PATH.'admin/views/menus/menu-style-4.php'); break; default: include(ULPB_PLUGIN_PATH.'admin/views/menus/menu-style-1.php'); break; } |
Proof of Concept
The following proof of concept will cause a file named test.php in the root directory of the WordPress installation to be included, when logged in as an Editor. Place the following short code on to a post or page:
[pb_samlple_nav menu_class='../../../../../../test']
Timeline
- October 20, 2017 – Developer notified.
- October 20, 2017 – Developer responds.
- October 29, 2017 – Version 1.4.4 released, which includes fix and new version number.