FIXED #1333 Rate limit calls.

Clean-up duplicate functionality.
EOL whitespace removed

Changes to be committed:
	modified:   extensions/admin_ui/controllers/authentication/authentication.rb
This commit is contained in:
Bucky Wilson
2017-11-24 17:05:22 +10:00
parent 0eb6010898
commit a94c6f36df

View File

@@ -12,85 +12,83 @@ module Controllers
# The authentication web page for BeEF. # The authentication web page for BeEF.
# #
class Authentication < BeEF::Extension::AdminUI::HttpController class Authentication < BeEF::Extension::AdminUI::HttpController
# #
# Constructor # Constructor
# #
def initialize def initialize
super({ super({
'paths' => { 'paths' => {
'/' => method(:index), '/' => method(:index),
'/login' => method(:login), '/login' => method(:login),
'/logout' => method(:logout) '/logout' => method(:logout)
} }
}) })
@session = BeEF::Extension::AdminUI::Session.instance @session = BeEF::Extension::AdminUI::Session.instance
end end
# Function managing the index web page # Function managing the index web page
def index def index
@headers['Content-Type']='text/html; charset=UTF-8' @headers['Content-Type']='text/html; charset=UTF-8'
end end
# #
# Function managing the login # Function managing the login
# #
def login def login
username = @params['username-cfrm'] || '' username = @params['username-cfrm'] || ''
password = @params['password-cfrm'] || '' password = @params['password-cfrm'] || ''
config = BeEF::Core::Configuration.instance config = BeEF::Core::Configuration.instance
@headers['Content-Type']='application/json; charset=UTF-8' @headers['Content-Type']='application/json; charset=UTF-8'
ua_ip = @request.ip # get client ip address ua_ip = @request.ip # get client ip address
@body = '{ success : false }' # attempt to fail closed @body = '{ success : false }' # attempt to fail closed
# check if source IP address is permited to authenticate # check if source IP address is permited to authenticate
if not permited_source?(ua_ip) if not permited_source?(ua_ip)
BeEF::Core::Logger.instance.register('Authentication', "IP source address (#{@request.ip}) attempted to authenticate but is not within permitted subnet.") BeEF::Core::Logger.instance.register('Authentication', "IP source address (#{@request.ip}) attempted to authenticate but is not within permitted subnet.")
return return
end end
# check if under brute force attack # check if under brute force attack
time = Time.new return if not BeEF::Core::Rest.timeout?('beef.extension.admin_ui.login_fail_delay',
if not timeout?(time) @session.get_auth_timestamp(),
@session.set_auth_timestamp(time) lambda { |time| @session.set_auth_timestamp(time)})
return
end
# check username and password # check username and password
if not (username.eql? config.get('beef.credentials.user') and password.eql? config.get('beef.credentials.passwd') ) if not (username.eql? config.get('beef.credentials.user') and password.eql? config.get('beef.credentials.passwd') )
BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has failed to authenticate in the application.") BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has failed to authenticate in the application.")
return return
end end
# establish an authenticated session # establish an authenticated session
# set up session and set it logged in # set up session and set it logged in
@session.set_logged_in(ua_ip) @session.set_logged_in(ua_ip)
# create session cookie # create session cookie
session_cookie_name = config.get('beef.http.session_cookie_name') # get session cookie name session_cookie_name = config.get('beef.http.session_cookie_name') # get session cookie name
Rack::Utils.set_cookie_header!(@headers, session_cookie_name, {:value => @session.get_id, :path => "/", :httponly => true}) Rack::Utils.set_cookie_header!(@headers, session_cookie_name, {:value => @session.get_id, :path => "/", :httponly => true})
BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has successfully authenticated in the application.") BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has successfully authenticated in the application.")
@body = "{ success : true }" @body = "{ success : true }"
end end
# #
# Function managing the logout # Function managing the logout
# #
def logout def logout
# test if session is unauth'd # test if session is unauth'd
(print_error "invalid nonce";return @body = "{ success : true }") if not @session.valid_nonce?(@request) (print_error "invalid nonce";return @body = "{ success : true }") if not @session.valid_nonce?(@request)
(print_error "invalid session";return @body = "{ success : true }") if not @session.valid_session?(@request) (print_error "invalid session";return @body = "{ success : true }") if not @session.valid_session?(@request)
@headers['Content-Type']='application/json; charset=UTF-8' @headers['Content-Type']='application/json; charset=UTF-8'
# set the session to be log out # set the session to be log out
@session.set_logged_out @session.set_logged_out
# clean up UA and expire the session cookie # clean up UA and expire the session cookie
config = BeEF::Core::Configuration.instance config = BeEF::Core::Configuration.instance
session_cookie_name = config.get('beef.http.session_cookie_name') # get session cookie name session_cookie_name = config.get('beef.http.session_cookie_name') # get session cookie name
@@ -98,14 +96,14 @@ class Authentication < BeEF::Extension::AdminUI::HttpController
BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has successfully logged out.") BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has successfully logged out.")
@body = "{ success : true }" @body = "{ success : true }"
end end
# #
# Check the UI browser source IP is within the permitted subnet # Check the UI browser source IP is within the permitted subnet
# #
def permited_source?(ip) def permited_source?(ip)
# get permitted subnet # get permitted subnet
config = BeEF::Core::Configuration.instance config = BeEF::Core::Configuration.instance
permitted_ui_subnet = config.get('beef.restrictions.permitted_ui_subnet') permitted_ui_subnet = config.get('beef.restrictions.permitted_ui_subnet')
target_network = IPAddr.new(permitted_ui_subnet) target_network = IPAddr.new(permitted_ui_subnet)
@@ -114,18 +112,7 @@ class Authentication < BeEF::Extension::AdminUI::HttpController
# test if ip within subnet # test if ip within subnet
return target_network.include?(ip) return target_network.include?(ip)
end end
#
# Brute Force Mitigation
# Only one login request per login_fail_delay seconds
#
def timeout?(time)
config = BeEF::Core::Configuration.instance
login_fail_delay = config.get('beef.extension.admin_ui.login_fail_delay') # get fail delay
# test if the last login attempt was less then login_fail_delay seconds
time - @session.get_auth_timestamp > login_fail_delay.to_i
end
end end