Як хакери шукають вразливості у сайтах — і як цьому запобігти

Іноді власники сайтів дивуються: звідки в логах беруться дивні запити до неіснуючих файлів — таких як c4.php, l.php, up.php чи навіть .well-known/setup. Якщо придивитися уважніше, то можна побачити десятки, сотні і навіть тисячі подібних запитів від одного IP-адреса, які виглядають приблизно так:

172.200.79.69 - - [04/Nov/2025:11:05:30 +0200] "GET /667.php HTTP/1.0" 404 919 "-" "-"
172.200.79.69 - - [04/Nov/2025:11:05:31 +0200] "GET /c4.php HTTP/1.0" 404 919 "-" "-"
172.200.79.69 - - [04/Nov/2025:11:05:32 +0200] "GET /racs3.php HTTP/1.0" 404 919 "-" "-"

Це типовий приклад автоматизованої атаки на сайт. Боти хакерів сканують тисячі сайтів у пошуках вразливих файлів — так званих шеллів, тестових скриптів (phpinfo.php), старих бекапів (bak.php), або дірок у плагінах WordPress. Їхня мета — знайти файл, через який можна отримати віддалений доступ до вашого хостингу, або ж отримати якусь конфіденційну інформацію. Такі атаки зазвичай не спрямовані особисто на ваш сайт — бот просто обходить інтернет-адреси у пошуках випадкових вразливостей.

Навіть якщо ваш сайт дуже гарно захищений, такі атаки створюють незручність у вигляді завантаження процессору (особливо, коли ваша сторінка 404 генерується в CMS) – це в кращому випадку! У найгіршому – якщо бот знаходить вразливість, то негайно сповіщає свого власника.

Як виявити спроби атак

Про те, що на вашому сервері спостерігається підвищена хакерська активність, зазвичай сигналізує сам хостинг — ви можете отримати сповіщення про перевищення лімітів навантаження або підозрілу кількість запитів до сайтів, що свідчить про масове сканування чи спроби зламу.

Перевірте access-логи на своєму сервері — зазвичай вони зберігаються у /logs або доступні через панель керування (наприклад, cPanel чи ISPmanager). Фільтруйте записи за підозрілими розширеннями .php, які не належать вашому сайту.

Зверніть увагу на повторювані IP-адреси — якщо один і той самий бот за кілька секунд перевіряє десятки неіснуючих файлів, це однозначно сканування.

Усі такі запити будуть вести на неіснуючу 404 сторінку (статус у запитів 404).

Такі атаки будуть суттєво відрізнятися в логах від звичайних запитів, їх дуже легко знайти за наявними абракадабрами в URL-запитах:

403

Як з цим боротися?

Таких “відвідувачів” можна і потрібно блокувати автоматично. Щоб не перевіряти логи вручну, можна застосувати невеликий PHP-скрипт, який:

  • перевіряє, чи звертається користувач до підозрілого URL;
  • автоматично додає IP-адресу до .htaccess;
  • блокує подальші запити з цієї адреси.

Базу підозрілих шляхів зручно тримати у JSON-файлі в хмарі, щоб не оновлювати її вручну для кожного сайту і зробити процес оновлення сигнатур атак автоматичним! В нашому випадку ми скористаємося масивом: https://shell.seotools.workers.dev

Далі наш PHP скрипт раз на добу автоматично завантажує свіжу версію масиву і працює вже з ним локально на вашому сайті на 404 сторінці (адже всі підозрілі запити перенаправляються саме туди).

У сайтах на WordPress такий файл зазвичай розміщений:

/wp-content/themes/ваша_тема/404.php

Відкриваємо файл 404.php, з першого рядка додаємо код:

<?php
// Налаштування
$json_url = 'https://shell.seotools.workers.dev'; // URL до бази JSON-файлу
$local_file = __DIR__ . '/suspicious-paths.json'; // Шлях до локального файлу
$cache_lifetime = 24 * 60 * 60; // 1 день в секундах

// Шлях до кореневого .htaccess
$htaccess_file = rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/.htaccess';
// Перевірка, чи потрібно оновити локальний файл
$need_update = !file_exists($local_file) || (time() - filemtime($local_file) > $cache_lifetime);

if ($need_update) {
// Скачуємо
    $json_data = @file_get_contents($json_url);

    if ($json_data !== false && !empty($json_data)) {
        file_put_contents($local_file, $json_data);
    } else {
        if (file_exists($local_file)) {
            $json_data = file_get_contents($local_file);
        } else {
            die('Error');
        }
    }
} else {
    $json_data = file_get_contents($local_file);
}

// Перетворюємо JSON в PHP-масив
$suspicious_paths = json_decode($json_data, true);

if (!is_array($suspicious_paths)) {
die('Помилка декодування JSON.');
}

// Отримуємо URI
$request_uri = $_SERVER['REQUEST_URI'];

// Проверіємо, чи наявний він в масиві
if (in_array($request_uri, $suspicious_paths)) {
    // отримуємо IP хакера
    $ban = htmlspecialchars(trim($_SERVER['REMOTE_ADDR']), ENT_QUOTES);
    $ban_string = "deny from " . $ban;

    // Якщо .htaccess немає — створюємо
    if (!file_exists($htaccess_file)) {
        file_put_contents($htaccess_file, "order allow,deny\nallow from all\n");
    }

    // Перевірка на дублі IP
    $current_htaccess_content = file_get_contents($htaccess_file);

    if (strpos($current_htaccess_content, $ban_string) === false) {
        file_put_contents($htaccess_file, $ban_string . PHP_EOL, FILE_APPEND);
    }

    // Повертаємо 403
    header("HTTP/1.1 403 Forbidden");
    echo "Access forbidden. Your IP has been blocked.";
    exit;
} ?>

В код я додав коментарі, тож не важко зрозуміти, як саме працює цей захист: ваш файл .htaccess поповнюватиметься IP адресами зловмисників, зупиняючи їх машини від тотального сканування вашого сайту, а отже, і від зайвого навантаження!

Автор: Ярослав SOCHKA
Якщо стаття виявилася для Вас корисною, можете сказати "дякую", перерахувавши кілька гривень на власний розсуд (натисніть на кнопку): Подякувати

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *