| Server IP : 146.190.157.162 / Your IP : 216.73.217.6 Web Server : Apache System : Linux ubuntu-s-2vcpu-4gb-amd-sfo3-01-KIT-DIGITAL 6.5.0-44-generic #44-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 7 15:10:09 UTC 2024 x86_64 User : businessweek ( 639) PHP Version : 8.2.10-2ubuntu2.2 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_signal,pcntl_signal_dispatch,pcntl_getpriority,pcntl_setpriority,dl,putenv,parse_ini_file,show_source MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/ |
Upload File : |
#!/usr/bin/env bash
set -euo pipefail
BASE_DIR="${BASE_DIR:-/var/www/html}"
EXCLUDE_DIR="wordpress-manager"
DRY_RUN=0
QUARANTINE=0
QUARANTINE_DIR="${QUARANTINE_DIR:-/root/wp-quarantine-$(date +%Y%m%dT%H%M%S)}"
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=1
fi
if [[ "${2:-}" == "--quarantine" || "${1:-}" == "--quarantine" ]]; then
QUARANTINE=1
fi
run() {
if [[ "$DRY_RUN" -eq 1 ]]; then
printf '[DRY] %q' "$1"
shift
for a in "$@"; do
printf ' %q' "$a"
done
printf '\n'
else
"$@"
fi
}
WP_INDEX_CONTENT='<?php
/**
* Front to the WordPress application. This file doesn'\''t do anything, but loads
* wp-blog-header.php which does and tells WordPress to load the theme.
*
* @package WordPress
*/
/**
* Tells WordPress to load the WordPress theme and output it.
*
* @var bool
*/
define( '\''WP_USE_THEMES'\'', true );
/** Loads the WordPress Environment and Template */
require __DIR__ . '\''/wp-blog-header.php'\'';
?>'
WP_CRON_CONTENT='<?php
/**
* A pseudo-cron daemon for scheduling WordPress tasks.
*
* WP-Cron is triggered when the site receives a visit. In the scenario
* where a site may not receive enough visits to execute scheduled tasks
* in a timely manner, this file can be called directly or via a server
* cron daemon for X number of times.
*
* Defining DISABLE_WP_CRON as true and calling this file directly are
* mutually exclusive and the latter does not rely on the former to work.
*
* The HTTP request to this file will not slow down the visitor who happens to
* visit when a scheduled cron event runs.
*
* @package WordPress
*/
ignore_user_abort( true );
if ( ! headers_sent() ) {
header( '\''Expires: Wed, 11 Jan 1984 05:00:00 GMT'\'' );
header( '\''Cache-Control: no-cache, must-revalidate, max-age=0'\'' );
}
if ( function_exists( '\''fastcgi_finish_request'\'' ) ) {
fastcgi_finish_request();
} elseif ( function_exists( '\''litespeed_finish_request'\'' ) ) {
litespeed_finish_request();
}
if ( ! empty( $_POST ) || defined( '\''DOING_AJAX'\'' ) || defined( '\''DOING_CRON'\'' ) ) {
die();
}
define( '\''DOING_CRON'\'', true );
if ( ! defined( '\''ABSPATH'\'' ) ) {
require_once __DIR__ . '\''/wp-load.php'\'';
}
wp_raise_memory_limit( '\''cron'\'' );
function _get_cron_lock() {
global $wpdb;
$value = 0;
if ( wp_using_ext_object_cache() ) {
$value = wp_cache_get( '\''doing_cron'\'', '\''transient'\'', true );
} else {
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '\''_transient_doing_cron'\'' ) );
if ( is_object( $row ) ) {
$value = $row->option_value;
}
}
return $value;
}
$crons = wp_get_ready_cron_jobs();
if ( empty( $crons ) ) {
die();
}
$gmt_time = microtime( true );
$doing_cron_transient = get_transient( '\''doing_cron'\'' );
if ( empty( $doing_wp_cron ) ) {
if ( empty( $_GET['\''doing_wp_cron'\''] ) ) {
if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) {
return;
}
$doing_wp_cron = sprintf( '\''%.22F'\'', microtime( true ) );
$doing_cron_transient = $doing_wp_cron;
set_transient( '\''doing_cron'\'', $doing_wp_cron );
} else {
$doing_wp_cron = $_GET['\''doing_wp_cron'\''];
}
}
if ( $doing_cron_transient !== $doing_wp_cron ) {
return;
}
foreach ( $crons as $timestamp => $cronhooks ) {
if ( $timestamp > $gmt_time ) {
break;
}
foreach ( $cronhooks as $hook => $keys ) {
foreach ( $keys as $k => $v ) {
$schedule = $v['\''schedule'\''];
if ( $schedule ) {
$result = wp_reschedule_event( $timestamp, $schedule, $hook, $v['\''args'\''], true );
if ( is_wp_error( $result ) ) {
error_log(
sprintf(
__( '\''Cron reschedule event error for hook: %1$s, Error code: %2$s, Error message: %3$s, Data: %4$s'\'' ),
$hook,
$result->get_error_code(),
$result->get_error_message(),
wp_json_encode( $v )
)
);
do_action( '\''cron_reschedule_event_error'\'', $result, $hook, $v );
}
}
$result = wp_unschedule_event( $timestamp, $hook, $v['\''args'\''], true );
if ( is_wp_error( $result ) ) {
error_log(
sprintf(
__( '\''Cron unschedule event error for hook: %1$s, Error code: %2$s, Error message: %3$s, Data: %4$s'\'' ),
$hook,
$result->get_error_code(),
$result->get_error_message(),
wp_json_encode( $v )
)
);
do_action( '\''cron_unschedule_event_error'\'', $result, $hook, $v );
}
do_action_ref_array( $hook, $v['\''args'\''] );
if ( _get_cron_lock() !== $doing_wp_cron ) {
return;
}
}
}
}
if ( _get_cron_lock() === $doing_wp_cron ) {
delete_transient( '\''doing_cron'\'' );
}
die();
?>'
is_wp_root() {
[[ -f "$1/wp-config.php" && -d "$1/wp-includes" && -d "$1/wp-admin" ]]
}
write_file() {
local path="$1"
local content="$2"
if [[ "$DRY_RUN" -eq 1 ]]; then
echo "[DRY] overwrite $path"
else
printf "%s\n" "$content" > "$path"
chmod 644 "$path"
fi
}
quarantine_move() {
local site="$1"
local file="$2"
local rel="${file#"$site"/}"
local dest="$QUARANTINE_DIR/$(basename "$site")/$rel"
if [[ "$DRY_RUN" -eq 1 ]]; then
echo "[DRY] quarantine $file -> $dest"
else
mkdir -p "$(dirname "$dest")"
mv -f "$file" "$dest"
fi
}
suspicious_name() {
local base="$1"
local lower="${base,,}"
case "$lower" in
222.php|tool*.php|ca*.php|tmp*.php|test*.php|shell*.php|ws*.php|wso*.php|r57*.php|c99*.php|mini*.php|adminer*.php|phpinfo*.php|cmd*.php|upload*.php|uploader*.php|bypass*.php|backdoor*.php|wp-vcd.php|wp-tmp.php|wp-conf.php|wp-crong.php|wp-corn.php|wp-ron.php|x*.php|a*.php|b*.php|k*.php) return 0 ;;
esac
if [[ "$lower" =~ ^[a-z0-9]{1,4}\.php$ ]]; then
return 0
fi
if [[ "$lower" =~ ^[a-z0-9]{1,5}\.(txt|dat|log|bak)$ ]]; then
return 0
fi
return 1
}
allowed_root_file() {
local base="$1"
case "$base" in
index.php|wp-activate.php|wp-blog-header.php|wp-comments-post.php|wp-config.php|wp-config-sample.php|wp-cron.php|wp-links-opml.php|wp-load.php|wp-login.php|wp-mail.php|wp-settings.php|wp-signup.php|wp-trackback.php|xmlrpc.php|license.txt|readme.html|robots.txt|.htaccess|google*.html|.well-known) return 0 ;;
esac
return 1
}
if [[ "$QUARANTINE" -eq 1 && "$DRY_RUN" -eq 0 ]]; then
mkdir -p "$QUARANTINE_DIR"
fi
for site_path in "$BASE_DIR"/*; do
[[ -d "$site_path" ]] || continue
site_name="$(basename "$site_path")"
[[ "$site_name" == "$EXCLUDE_DIR" ]] && continue
is_wp_root "$site_path" || continue
echo "Fix: $site_name"
run rm -f "$site_path/222.php"
run rm -f "$site_path/wp-content/222.php"
run rm -f "$site_path/wp-content/wp-blog-header.php"
run rm -f "$site_path/wp-content/wp-cron.php"
if [[ -d "$site_path/wp-content/ai1wm-backups" ]]; then
run rm -rf "$site_path/wp-content/ai1wm-backups"
fi
write_file "$site_path/index.php" "$WP_INDEX_CONTENT"
write_file "$site_path/wp-cron.php" "$WP_CRON_CONTENT"
echo "Suspicious (name-based): $site_name"
while IFS= read -r -d '' f; do
b="$(basename "$f")"
if suspicious_name "$b"; then
if allowed_root_file "$b"; then
continue
fi
if [[ "$QUARANTINE" -eq 1 ]]; then
quarantine_move "$site_path" "$f"
else
echo "$f"
fi
fi
done < <(find "$site_path" -maxdepth 2 -type f \( -name "*.php" -o -name "*.txt" -o -name "*.dat" -o -name "*.log" -o -name "*.bak" \) -print0 2>/dev/null)
echo
done
if [[ "$QUARANTINE" -eq 1 ]]; then
echo "Quarantine: $QUARANTINE_DIR"
fi
echo "Done."