class Pentest::Endpoint
Attributes
app_path[R]
route[R]
Public Class Methods
new(route, app_path, hooks)
click to toggle source
# File lib/pentest/endpoint.rb, line 7 def initialize(route, app_path, hooks) @route = route @app_path = app_path @hooks = hooks @controller = route.defaults[:controller] @action = route.defaults[:action] return if @controller.nil? || @action.nil? @controller_name = ::ActiveSupport::Inflector.camelize(@controller) + "Controller" @controller_class = ::ActiveSupport::Inflector.constantize(@controller_name) @error_patterns = Set.new end
Public Instance Methods
dispatch(payload)
click to toggle source
# File lib/pentest/endpoint.rb, line 60 def dispatch(payload) request = ActionDispatch::TestRequest.create request.request_method = @route.verb request.path = path(payload.params_hash) @hooks[:before_attacks].each do |before_attack_proc| before_attack_proc.call(request) end request.path_parameters = { controller: @controller, action: @action, } payload.params_hash.each do |param_parts, value| if param_parts.size == 1 param, = param_parts if @route.required_parts.include? param request.path_parameters[param] = value else request.query_parameters[param] = value end elsif param_parts.size == 2 request.query_parameters[param_parts[0]] ||= {} request.query_parameters[param_parts[0]][param_parts[1]] = value end end request.path_parameters.each do |param, value| request.update_param(param, value) end request.query_parameters.each do |param, value| request.update_param(param, value) end response = ActionDispatch::TestResponse.create err = nil begin @controller_class.new.dispatch(@action.to_sym, request, response) rescue => e err = e end [request, response, err] end
scan!(ingredients)
click to toggle source
# File lib/pentest/endpoint.rb, line 27 def scan!(ingredients) params = get_params Logger.info "#{@route.verb} #{path}" Logger.debug "Attacking #{@controller_class.inspect}##{@action}...", timestamp: false Logger.debug "Detected Parameters: #{params.to_a.inspect}", timestamp: false error_patterns = Set.new penetrated_payloads = [] Logger.start_progress Checkers.run_checkers(self, params) do |checker| params.each_with_index do |param, injection_point| penetrated_payload, errors = checker.attack(param, injection_point, ingredients) accumulate_errors(errors) unless penetrated_payload.nil? penetrated_payloads << penetrated_payload end end end Logger.end_progress @error_patterns.each do |error_pattern| Logger.warn("Error: #{error_pattern}", timestamp: false) end penetrated_payloads end
valid?()
click to toggle source
# File lib/pentest/endpoint.rb, line 23 def valid? !@controller.nil? && !@action.nil? && @controller_class.method_defined?(@action.to_sym) end
Private Instance Methods
accumulate_errors(errors)
click to toggle source
# File lib/pentest/endpoint.rb, line 141 def accumulate_errors(errors) errors.each do |error| unless error.nil? @error_patterns << error end end end
get_params()
click to toggle source
# File lib/pentest/endpoint.rb, line 122 def get_params exp = RubyParser.get_sexp(method) param_usages = AstUtils.search_for_params(exp) deep_parameters = Set.new non_deep_parameters = Set.new param_usages.each do |param, type, method, arg| if type == :callee && method == :[] deep_parameters << [ param, arg[1] ] else non_deep_parameters << param end end non_deep_parameters += @route.required_parts.map(&:to_sym) non_deep_parameters -= deep_parameters.map {|a| a[0]} deep_parameters.to_a + non_deep_parameters.map {|param| [param]} end
method()
click to toggle source
# File lib/pentest/endpoint.rb, line 110 def method @controller_class.instance_method(@action.to_sym) end
path(options = {})
click to toggle source
# File lib/pentest/endpoint.rb, line 114 def path(options = {}) @route.required_parts.each do |part| options[part] ||= ":#{part}" end @route.format(options) end