Adds a monkey-patch for the WEBrick directory traversal flaw
git-svn-id: file:///home/svn/framework3/trunk@5434 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
52a64d4d9f
commit
032edb7e39
|
@ -33,6 +33,13 @@ end
|
|||
msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
||||
$:.unshift(File.join(File.dirname(msfbase), '..', '..', '..', 'lib'))
|
||||
|
||||
|
||||
|
||||
# Monkey patch the webrick vulnerability
|
||||
if(Object.const_defined?(:WEBrick))
|
||||
load(File.join(File.dirname(msfbase), "..", "patches", "filehandler.rb"))
|
||||
end
|
||||
|
||||
require 'rex'
|
||||
require 'msf/ui'
|
||||
require 'msf/base'
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#
|
||||
# Monkey patch the webrick vulnerability
|
||||
#
|
||||
|
||||
$stderr.puts "[*] WEBrick directory traversal patch loaded"
|
||||
|
||||
module WEBrick
|
||||
module HTTPServlet
|
||||
|
||||
class FileHandler < AbstractServlet
|
||||
|
||||
def service(req, res)
|
||||
# if this class is mounted on "/" and /~username is requested.
|
||||
# we're going to override path informations before invoking service.
|
||||
if defined?(Etc) && @options[:UserDir] && req.script_name.empty?
|
||||
if %r|^(/~([^/]+))| =~ req.path_info
|
||||
script_name, user = $1, $2
|
||||
path_info = $'
|
||||
begin
|
||||
passwd = Etc::getpwnam(user)
|
||||
@root = File::join(passwd.dir, @options[:UserDir])
|
||||
req.script_name = script_name
|
||||
req.path_info = path_info
|
||||
rescue
|
||||
@logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed"
|
||||
end
|
||||
end
|
||||
end
|
||||
prevent_directory_traversal(req, res)
|
||||
super(req, res)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prevent_directory_traversal(req, res)
|
||||
# Preventing directory traversal on DOSISH platforms;
|
||||
# Backslashes (0x5c) in path_info are not interpreted as special
|
||||
# character in URI notation. So the value of path_info should be
|
||||
# normalize before accessing to the filesystem.
|
||||
if File::ALT_SEPARATOR
|
||||
# File.expand_path removes the trailing path separator.
|
||||
# Adding a character is a workaround to save it.
|
||||
# File.expand_path("/aaa/") #=> "/aaa"
|
||||
# File.expand_path("/aaa/" + "x") #=> "/aaa/x"
|
||||
expanded = File.expand_path(req.path_info + "x")
|
||||
expanded[-1, 1] = "" # remove trailing "x"
|
||||
req.path_info = expanded
|
||||
end
|
||||
end
|
||||
|
||||
def check_filename(req, res, name)
|
||||
@options[:NondisclosureName].each{|pattern|
|
||||
if File.fnmatch("/#{pattern}", name, File::FNM_CASEFOLD)
|
||||
@logger.warn("the request refers nondisclosure name `#{name}'.")
|
||||
raise HTTPStatus::NotFound, "`#{req.path}' not found."
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def nondisclosure_name?(name)
|
||||
@options[:NondisclosureName].each{|pattern|
|
||||
if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
|
||||
return true
|
||||
end
|
||||
}
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue