Скрипт для поиска и удаления спам-тем, связанных с даркнет-маркетплейсами и кракен

Скачать Скрипт для поиска и удаления спам-тем, связанных с даркнет-маркетплейсами и кракен
Недавно искали:

Itnull

Команда форума
Администратор
Регистрация
22.05.13
Сообщения
26.645
Реакции
11.160
Веб-сайт
itnull.me
  • Автор темы
  • Администратор
  • Модер.
  • Команда форума
  • #1
Скрипт для поиска и удаления спам-тем, связанных с даркнет-маркетплейсами и кракен
Проверено на версии: 2.3.6
Вдохновился кодом от @West14 из данного поста: XF 2.2 - Борьба со спамом и решил переделать и доработать его полностью под свои нужды. Хочу поделиться с сообществом результатом своей работы! Этот скрипт предназначен для поиска и удаления спам-тем, связанных с даркнет-маркетплейсами, таких как «Кракен», на форумах XenForo. Он учитывает ключевые слова и регулярные выражения, позволяет исключать определенные темы и отображает подробную информацию о найденных темах.

Если вы найдете ошибки, баги или недоработки, пожалуйста, пишите в эту тему. Буду поддерживать скрипт новыми обновлениями и доработками. Также приветствуются любые предложения по улучшению функционала!

Ниже приведена подробная инструкция по использованию скрипта, а сам код прикреплен в спойлере. Надеюсь, он будет полезен для вашего форума!


Инструкция по использованию скрипта

1. Размещение скрипта


Создайте PHP-файл с уникальным и непредсказуемым именем (например, spam_cleaner_7x9z3.php), чтобы снизить вероятность его обнаружения посторонними.
Скопируйте код скрипта (приведен в спойлере ниже) в этот файл или скачайте уже готовый файл, но перед этим переименуйте его как указано в пункте "1."
Поместите файл в корневую папку вашего форума XenForo на хостинге (там, где находятся файлы вроде index.php и папка src).


2. Настройка скрипта Перед запуском необходимо настроить несколько параметров в коде скрипта:

Часовой пояс:
В коде установлен часовой пояс Asia/Tomsk (+7). Если ваш форум работает в другом часовом поясе, замените его на нужный, например, Europe/Moscow или America/New_York. Список поддерживаемых часовых поясов можно найти в документации PHP
[*]Измените строки:

PHP:
date_default_timezone_set('Asia/Tomsk');
в начале скрипта и внутри блока try.

ID Администратора:
Скрипт требует права администратора для удаления тем. Укажите ID администратора вашего форума в строке:
PHP:
$adminUser = \XF::finder('XF:User')->where('user_id', 1)->fetchOne();
Замените 1 на ID вашего администратора. Найти ID можно в админ-панели XenForo в разделе «Пользователи» или в базе данных в таблице xf_user.

Исключение тем:
Чтобы исключить определенные темы из обработки (например, важные темы, которые не должны быть удалены), добавьте их ID в массив $excludeThreadIds:
PHP:
$excludeThreadIds = [1, 2, 3, 10, 20];
Укажите ID тем через запятую. Например, для исключения тем с ID 250, 1353 и 7777:
PHP:
$excludeThreadIds = [250, 1353, 7777];

Ключевые слова и регулярные выражения:
Скрипт ищет темы, содержащие определенные ключевые слова или соответствующие регулярным выражениям. Текущий список ключевых слов:
PHP:
$spamKeywords = [ 'даркнет', 'darknet', 'kra34.cc', 'kra34.at', 'krn28.click', 'kra27.at', 'kraken', 'darkweb', 'KRaKeN?!' ];
Вы можете добавить или удалить слова, связанные со спамом на вашем форуме. []Слово kraken обрабатывается особым образом: оно считается спамом только в сочетании с другими ключевыми словами. Список дополнительных слов:
PHP:
$secondarySpamKeywords = ['kraken', 'KRAKEN', 'Kraken'];

Регулярные выражения для поиска спама:
Код:
$spamPatterns = [ '/kra\d{1,2}.(cc|at)/i', // Домены типа kra34.cc, kra27.at '/.onion/i', // Ссылки на даркнет '/[!?@]{2,}/', // Многократные знаки препинания '/[\p{So}]/u' // Нестандартные символы ];
Вы можете добавить свои регулярные выражения или изменить существующие для более точной фильтрации.

3. Запуск скрипта
Перейдите в браузере по адресу вашего скрипта, например:
Код:
https://yourdomain.com/spam_cleaner_7x9z3.php
Замените yourdomain.com на домен вашего форума и spam_cleaner_7x9z3.php на имя вашего файла.
  1. Скрипт выведет таблицу с найденными темами, которые соответствуют заданным критериям. В таблице отображаются:
  2. ID темы
  3. Название темы
  4. ID пользователя
  5. Имя пользователя
  6. Статус темы (активна, на модерации, удалена)
  7. Первые 50 символов первого сообщения
Проверьте список тем, чтобы убедиться, что в нем нет важных тем. Если такие темы есть, добавьте их ID в $excludeThreadIds и обновите страницу.
4. Удаление тем ВНИМАНИЕ: Темы удаляются физически из базы данных без возможности восстановления и без записи в журналы XenForo. Будьте осторожны!

  1. В таблице отметьте галочками темы, которые хотите удалить, или выберите «Выбрать все» для удаления всех найденных тем.
  2. Нажмите кнопку «Удалить выбранные темы».
  3. После удаления страница обновится, и удаленные темы исчезнут из списка.
  4. Если возникнут ошибки при удалении (например, недостаток прав), они будут отображены на странице.

5. Дополнительная информация
Статистика
:
  • Скрипт показывает общее количество тем и сообщений в базе, а также количество найденных спам-тем.
  • Также отображается текущий часовой пояс и время запуска скрипта.
Пользователи:
  • Внизу страницы выводится список ID пользователей, создавших спам-темы. Это может быть полезно для дальнейшего анализа или блокировки ботов.
Безопасность:
  • Не разглашайте имя файла скрипта и не делитесь ссылкой на него с посторонними.
  • После использования рекомендуется удалить файл с сервера или переместить его в защищенное место.
6. Возможные улучшения
  • Если вы хотите добавить возможность поиска по другим критериям (например, по датам создания тем или по конкретным форумам), напишите в этой теме, и я постараюсь доработать скрипт.
  • Если у вас есть идеи по улучшению интерфейса или функционала, делитесь предложениями!

PHP:
<?php

// Устанавливаем часовой пояс Томск (+7) (Вы можете выбрать свой, если нужно)
date_default_timezone_set('Asia/Tomsk');


$dir = __DIR__;
require($dir . '/src/XF.php');

try {
    XF::start($dir);

    // Повторно устанавливаем часовой пояс (Здесь необходимо повторно установить ваш часовой пояс)
    date_default_timezone_set('Asia/Tomsk');

    // Установите права администратора (Укажите Ваш ID администратора на форуме где user_id', 1)
    $adminUser = \XF::finder('XF:User')->where('user_id', 1)->fetchOne();
    if ($adminUser) {
        \XF::setVisitor($adminUser);
    } else {
        throw new \Exception("Не удалось установить пользователя ID=1");
    }

    $excludeThreadIds = [1, 2, 3, 10, 20]; // Исключайте темы здесь по ID через запятую.

    // Ключевые слова для спама (Рекламные маркеры)
    $spamKeywords = [
        'даркнет', 'darknet', 'kra34.cc', 'kra34.at', 'krn28.click', 'kra27.at', 'kraken', 'darkweb', 'KRaKeN?!'
    ];

    $spamPatterns = [
        '/kra\d{1,2}\.(cc|at)/i',
        '/\.onion/i',
        '/[!?\@]{2,}/',
        '/[\p{So}]/u'
    ];
    // Ключевое слово "kraken" проверяем только с другими маркерами
    $secondarySpamKeywords = ['kraken', 'KRAKEN', 'Kraken'];

    $threadsFinder = \XF::finder('XF:Thread')
        ->with(['User', 'FirstPost'])
        ->where('discussion_state', ['visible', 'moderated'])
        ->where('thread_id', '!=', $excludeThreadIds[0])
        ->order('thread_id', 'DESC');

    $keywordConditions = [];
    foreach ($spamKeywords as $keyword) {
        $keywordConditions[] = ['FirstPost.message', 'LIKE', "%$keyword%"];
        $keywordConditions[] = ['title', 'LIKE', "%$keyword%"];
    }

    foreach ($secondarySpamKeywords as $keyword) {
        foreach ($spamKeywords as $additionalKeyword) {
            $keywordConditions[] = [
                ['FirstPost.message', 'LIKE', "%$keyword%"],
                ['FirstPost.message', 'LIKE', "%$additionalKeyword%"]
            ];
            $keywordConditions[] = [
                ['title', 'LIKE', "%$keyword%"],
                ['title', 'LIKE', "%$additionalKeyword%"]
            ];
        }
    }
    if (!empty($keywordConditions)) {
        $threadsFinder = $threadsFinder->whereOr($keywordConditions);
    }

    $sqlQuery = $threadsFinder->getQuery();

    $threads = $threadsFinder->fetch();

    $filteredThreads = [];
    foreach ($threads as $thread) {
        $textToCheck = ($thread->title ?? '') . ' ' . ($thread->FirstPost->message ?? '');
        $isSpam = false;
        foreach ($spamPatterns as $pattern) {
            if (preg_match($pattern, $textToCheck)) {
                $isSpam = true;
                break;
            }
        }
        if ($isSpam) {
            $filteredThreads[$thread->thread_id] = $thread;
        }
    }

    // Подсчёт тем
    $threadCount = count($filteredThreads);

    // Общее количество тем и сообщений
    $totalThreads = \XF::finder('XF:Thread')->total();
    $totalPosts = \XF::finder('XF:Post')->total();

    // Обработка удаления
    $confirmDeletion = \XF::app()->request()->filter('delete_confirm', 'bool');
    $deleteThreadIds = \XF::app()->request()->filter('delete_threads', 'array-uint');
    $errorMessages = [];

    if ($confirmDeletion && !empty($deleteThreadIds)) {
        foreach ($filteredThreads as $thread) {
            if (in_array($thread->thread_id, $deleteThreadIds)) {
                try {
                    $error = '';
                    if ($thread->canDelete($error)) {
                        $thread->delete();
                    } else {
                        $errorMessages[] = "Невозможно удалить тему #{$thread->thread_id}: " . ($error ?: 'Отсутствуют права на удаление');
                    }
                } catch (\Exception $e) {
                    $errorMessages[] = "Ошибка при удалении темы #{$thread->thread_id}: " . $e->getMessage();
                }
            }
        }
        if (empty($errorMessages)) {
            header('Location: ' . $_SERVER['PHP_SELF']);
            exit;
        }
    }

} catch (\Exception $e) {
    $errorMessage = "Критическая ошибка: " . $e->getMessage() . "\nStack trace: " . $e->getTraceAsString();
    $errorMessages[] = $errorMessage;
    http_response_code(500);
}

?>

<!DOCTYPE html>
<html>
<head>
    <title>Управление спам-темами</title>
    <meta charset="UTF-8">
<style>
    body { font-family: Georgia, serif; }
    table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background-color: #f2f2f2; }
    th:nth-child(1), th:nth-child(2), th:nth-child(4), th:nth-child(5) {
        white-space: nowrap;
        width: 100px;
    }
    th:nth-child(3) {
        width: 800px;
        white-space: nowrap;
    }
    .delete-btn { background-color: #ff4444; color: white; padding: 5px 10px; border: none; cursor: pointer; }
    .delete-btn:hover { background-color: #cc0000; }
    .error { color: red; margin-top: 10px; margin-bottom: 10px; }
    .info {
        color: #FF0000;
        margin-top: 10px;
        margin-bottom: 10px;
        border: 2px solid #8B0000;
        border-radius: 5px;
        padding: 10px;
        background-color: #FFF3F3;
        text-align: center;
        font-weight: bold;
    }
    .debug { margin-top: 10px; margin-bottom: 10px; }
    .debug p { margin: 0; }
    .label { color: #FF4500; }
    .value { color: #008000; }
    .warning {
        border: 2px solid #FF0000;
        background-color: #FFF3F3;
        padding: 15px;
        margin-bottom: 20px;
        border-radius: 5px;
    }
    .warning h3 {
        color: #FF0000;
        margin-top: 0;
        font-size: 1.2em;
    }
    .warning p {
        margin: 5px 0;
    }
    .warning ul {
        margin-left: 20px;
        list-style-type: disc;
    }
    .description { margin-bottom: 15px; }
    .description .label { font-weight: bold; }
    h2 {
        text-align: center;
        color: #333333;
    }
    hr {
        border: 0;
        border-top: 1px solid #333333;
        margin: 10px 0;
    }
</style>
</head>
<body>
    <h2>Управление спам-темами форума</h2>
    <hr>
    <div class="description">
        <p><span class="label">Описание:</span><br>Этот инструмент позволяет находить и удалять спам-темы, связанные с даркнет-маркетплейсом «Кракен», содержащие ключевые слова (Например: «даркнет», «darknet», «kra34.cc», «kra34.at», «krn28.click», «kra27.at», «kraken», «darkweb», «KRaKeN?!») в заголовке или первом сообщении. Используйте с осторожностью и не разглашайте доступ к скрипту.</p><hr>
        <p><span class="label">Дополнительная информация:</span><br><b>За идею благодарю:</b> <a href="https://xenforo.info/members/west14.22547/" style="color: #008000;">West14</a>.<br><b>Реализовал:</b> <a href="https://xenforo.info/members/shumasick.64948/" style="color: #8B0000;">Shumasick</a></p>
    </div>
    <hr>

    <?php if (!empty($errorMessages)): ?>
        <div class="error">
            <?php foreach ($errorMessages as $error): ?>
                <p><?= htmlspecialchars($error) ?></p>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

    <div class="warning">
        <h3>ВНИМАНИЕ</h3>
        <ul>
            <li>Не разглашайте имя или существование этого файла. Доступ к нему должен быть строго ограничен, чтобы предотвратить несанкционированное использование и потенциальные проблемы с безопасностью форума.</li>
        </ul>
    </div>

    <div class="debug">
        <p><b><span class="label">Скрипт запущен: </span><span class="value"><?php
            $date = new DateTime();
            echo $date->format('d.m.Y H:i:s');
        ?></span></b></p>
        <p><b><span class="label">Текущий часовой пояс: </span><span class="value"><?= date_default_timezone_get() ?></span></b></p>
        <p><b><span class="label">Общее количество тем в базе: </span><span class="value"><?= isset($totalThreads) ? $totalThreads : 'Н/Д' ?></span></b></p>
        <p><b><span class="label">Общее количество сообщений в базе: </span><span class="value"><?= isset($totalPosts) ? $totalPosts : 'Н/Д' ?></span></b></p>
        <p><b><span class="label">Найдено тем по критериям: </span><span class="value"><?= $threadCount ?? 'Н/Д' ?></span></b></p>
    </div>

    <?php if (empty($filteredThreads)): ?>
        <div class="info">
            <p>Подходящие темы не найдены.</p>
        </div>
    <?php else: ?>
        <form method="post">
            <table>
                <tr>
                    <th><input type="checkbox" id="selectAll"> Выбрать все</th>
                    <th>ID Темы:</th>
                    <th>Название Темы:</th>
                    <th>ID Пользователя:</th>
                    <th>Пользователь:</th>
                    <th>Статус Темы:</th>
                    <th>Первые 50 символов сообщения</th>
                </tr>
                <?php foreach ($filteredThreads as $thread): ?>
                    <tr>
                        <td><input type="checkbox" name="delete_threads[]" value="<?= $thread->thread_id ?>"></td>
                        <td><?= $thread->thread_id ?></td>
                        <td><?= htmlspecialchars($thread->title) ?></td>
                        <td><?= $thread->user_id ?? 'N/A' ?></td>
                        <td><?= htmlspecialchars($thread->User->username ?? 'Неизвестный пользователь') ?></td>
                        <td><?= $thread->discussion_state === 'moderated' ? 'На модерации' : ($thread->isDeleted() ? 'Удалена' : 'Активна') ?></td>
                        <td><?= htmlspecialchars(substr($thread->FirstPost->message ?? 'Нет сообщения', 0, 50)) . (strlen($thread->FirstPost->message ?? '') > 50 ? '...' : '') ?></td>
                    </tr>
                <?php endforeach; ?>
            </table>

            <input type="hidden" name="delete_confirm" value="1">
            <button type="submit" class="delete-btn">Удалить выбранные темы</button>
        </form>

        <p>Задействованные ID пользователей: <?= implode(', ', array_unique(array_filter(array_column($filteredThreads, 'user_id')))) ?></p>
    <?php endif; ?>

    <script>
        document.getElementById('selectAll')?.addEventListener('change', function(e) {
            document.querySelectorAll('input[name="delete_threads[]"]').forEach(checkbox => {
                checkbox.checked = e.target.checked;
            });
        });
    </script>
</body>
</html>
 

Вложения

  • DeleteSPAM.rar
    3,9 KB · Просмотры: 0
Назад
Сверху Снизу