From 6a8c8d708146273d6af23d311adb3d127a943d5f Mon Sep 17 00:00:00 2001 From: root Date: Mon, 30 Dec 2019 06:05:09 +0000 Subject: [PATCH] Revert "Merge pull request #1845 from beefproject/fix_broken_admin_ui_access" This reverts commit 5de127a0e2c976ad6ef2fc1e57d343bd50dab2c0, reversing changes made to f5de5eb7c090023df39256a9983f75fc87403194. --- config.yaml | 3 - core/bootstrap.rb | 1 - core/main/router/error_responses.rb | 68 ------------------- core/main/router/router.rb | 65 ++++++++++++++++-- extensions/admin_ui/classes/httpcontroller.rb | 67 ++---------------- .../authentication/authentication.rb | 7 +- spec/beef/extensions/adminui_spec.rb | 46 ------------- 7 files changed, 65 insertions(+), 192 deletions(-) delete mode 100644 core/main/router/error_responses.rb delete mode 100644 spec/beef/extensions/adminui_spec.rb diff --git a/config.yaml b/config.yaml index ce6449269..528a8f751 100644 --- a/config.yaml +++ b/config.yaml @@ -51,9 +51,6 @@ beef: # Reverse Proxy / NAT # If you want BeEF to be accessible behind a reverse proxy or NAT, # set both the publicly accessible hostname/IP address and port below: - # NOTE: Allowing the reverse proxy will enable a vulnerability where the ui/panel can be spoofed - # by altering the X-FORWARDED-FOR ip address in the request header. - allow_reverse_proxy: false #public: "" # public hostname/IP address #public_port: "" # public port (experimental) diff --git a/core/bootstrap.rb b/core/bootstrap.rb index 46bc79ab0..094213a7b 100644 --- a/core/bootstrap.rb +++ b/core/bootstrap.rb @@ -12,7 +12,6 @@ end ## @note Include the BeEF router require 'core/main/router/router' require 'core/main/router/api' -require 'core/main/router/error_responses' ## @note Include http server functions for beef diff --git a/core/main/router/error_responses.rb b/core/main/router/error_responses.rb deleted file mode 100644 index 584e5ef80..000000000 --- a/core/main/router/error_responses.rb +++ /dev/null @@ -1,68 +0,0 @@ -module BeEF - module Core - module Router - - config = BeEF::Core::Configuration.instance - - APACHE_HEADER = { "Server" => "Apache/2.2.3 (CentOS)", - "Content-Type" => "text/html; charset=UTF-8" } - APACHE_BODY = "" + - "" + - "404 Not Found" + - "" + - "

Not Found

" + - "

The requested URL was not found on this server.

" + - "
" + - "
Apache/2.2.3 (CentOS)
" + - ("" if config.get("beef.http.web_server_imitation.hook_404")).to_s + - "" - IIS_HEADER = {"Server" => "Microsoft-IIS/6.0", - "X-Powered-By" => "ASP.NET", - "Content-Type" => "text/html; charset=UTF-8"} - IIS_BODY = "" + - "The page cannot be found" + - "" + - "" + - "
" + - "

The page cannot be found

" + - "The page you are looking for might have been removed, had its name changed, or is temporarily unavailable." + - "
" + - "

Please try the following:

" + - "
    " + - "
  • Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.
  • " + - "
  • If you reached this page by clicking a link, contact" + - " the Web site administrator to alert them that the link is incorrectly formatted." + - "
  • " + - "
  • Click the Back button to try another link.
  • " + - "
" + - "

HTTP Error 404 - File or directory not found.
Internet Information Services (IIS)

" + - "
" + - "

Technical Information (for support personnel)

" + - "
    " + - "
  • Go to Microsoft Product Support Services and perform a title search for the words HTTP and 404.
  • " + - "
  • Open IIS Help, which is accessible in IIS Manager (inetmgr)," + - "and search for topics titled Web Site Setup, Common Administrative Tasks, and About Custom Error Messages.
  • " + - "
" + - "
" + - ("" if config.get("beef.http.web_server_imitation.hook_404")).to_s + - "" - NGINX_HEADER = {"Server" => "nginx", - "Content-Type" => "text/html"} - NGINX_BODY = "\n"+ - "404 Not Found\n" + - "\n" + - "

404 Not Found

\n" + - "
nginx
\n" + - ("" if config.get("beef.http.web_server_imitation.hook_404")).to_s + - "\n" + - "\n" - - end - end -end diff --git a/core/main/router/router.rb b/core/main/router/router.rb index b092a5f48..7ea91f611 100644 --- a/core/main/router/router.rb +++ b/core/main/router/router.rb @@ -24,13 +24,61 @@ module BeEF case type when "apache" #response body - BeEF::Core::Router::APACHE_BODY + "" + + "" + + "404 Not Found" + + "" + + "

Not Found

" + + "

The requested URL was not found on this server.

" + + "
" + + "
Apache/2.2.3 (CentOS)
" + + ("" if config.get("beef.http.web_server_imitation.hook_404")).to_s + + "" when "iis" #response body - BeEF::Core::Router::IIS_BODY + "" + + "The page cannot be found" + + "" + + "" + + "
" + + "

The page cannot be found

" + + "The page you are looking for might have been removed, had its name changed, or is temporarily unavailable." + + "
" + + "

Please try the following:

" + + "
    " + + "
  • Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.
  • " + + "
  • If you reached this page by clicking a link, contact" + + " the Web site administrator to alert them that the link is incorrectly formatted." + + "
  • " + + "
  • Click the Back button to try another link.
  • " + + "
" + + "

HTTP Error 404 - File or directory not found.
Internet Information Services (IIS)

" + + "
" + + "

Technical Information (for support personnel)

" + + "
    " + + "
  • Go to Microsoft Product Support Services and perform a title search for the words HTTP and 404.
  • " + + "
  • Open IIS Help, which is accessible in IIS Manager (inetmgr)," + + "and search for topics titled Web Site Setup, Common Administrative Tasks, and About Custom Error Messages.
  • " + + "
" + + "
" + + ("" if config.get("beef.http.web_server_imitation.hook_404")).to_s + + "" when "nginx" #response body - BeEF::Core::Router::NGINX_BODY + "\n"+ + "404 Not Found\n" + + "\n" + + "

404 Not Found

\n" + + "
nginx
\n" + + ("" if config.get("beef.http.web_server_imitation.hook_404")).to_s + + "\n" + + "\n" else "Not Found." end @@ -45,11 +93,16 @@ module BeEF type = config.get("beef.http.web_server_imitation.type") case type when "apache" - headers BeEF::Core::Router::APACHE_HEADER + headers "Server" => "Apache/2.2.3 (CentOS)", + "Content-Type" => "text/html; charset=UTF-8" + when "iis" - headers BeEF::Core::Router::IIS_HEADER + headers "Server" => "Microsoft-IIS/6.0", + "X-Powered-By" => "ASP.NET", + "Content-Type" => "text/html; charset=UTF-8" when "nginx" - headers BeEF::Core::Router::NGINX_HEADER + headers "Server" => "nginx", + "Content-Type" => "text/html" else headers "Server" => '', "Content-Type" => "text/html" diff --git a/extensions/admin_ui/classes/httpcontroller.rb b/extensions/admin_ui/classes/httpcontroller.rb index 09b41db6c..d826b9d37 100644 --- a/extensions/admin_ui/classes/httpcontroller.rb +++ b/extensions/admin_ui/classes/httpcontroller.rb @@ -10,7 +10,7 @@ module AdminUI # # Handle HTTP requests and call the relevant functions in the derived classes # - class HttpController + class HttpController attr_accessor :headers, :status, :body, :paths, :currentuser, :params @@ -26,8 +26,8 @@ module AdminUI @status = 200 if data['status'].nil? @session = BeEF::Extension::AdminUI::Session.instance - @config = BeEF::Core::Configuration.instance - @bp = @config.get "beef.extension.admin_ui.base_path" + config = BeEF::Core::Configuration.instance + @bp = config.get "beef.extension.admin_ui.base_path" @headers = {'Content-Type' => 'text/html; charset=UTF-8'} if data['headers'].nil? @@ -37,60 +37,6 @@ module AdminUI @paths = data['paths'] end end - - # - # Authentication check. Confirm the request to access the UI comes from a permitted IP address - # - def authenticate_request(ip) - auth = BeEF::Extension::AdminUI::Controllers::Authentication.new - if !auth.permitted_source?(ip) - if @config.get("beef.http.web_server_imitation.enable") - type = @config.get("beef.http.web_server_imitation.type") - case type - when "apache" - @body = BeEF::Core::Router::APACHE_BODY - @status = 404 - @headers = BeEF::Core::Router::APACHE_HEADER - return false - when "iis" - @body = BeEF::Core::Router::IIS_BODY - @status = 404 - @headers = BeEF::Core::Router::IIS_HEADER - return false - when "nginx" - @body = BeEF::Core::Router::APACHE_BODY - @status = 404 - @headers = BeEF::Core::Router::APACHE_HEADER - return false - else - @body = "Not Found." - @status = 404 - @headers = {"Content-Type" => "text/html"} - return false - end - else - @body = "Not Found." - @status = 404 - @headers = {"Content-Type" => "text/html"} - return false - end - else - return true - end - end - - # - # Check if reverse proxy has been enabled and return the correct client IP address - # - def get_ip(request) - if !@config.get("beef.http.allow_reverse_proxy") - ua_ip = request.get_header('REMOTE_ADDR') # Get client remote ip address - else - ua_ip = request.ip # Get client x-forwarded-for ip address - end - ua_ip - end - # # Handle HTTP requests and call the relevant functions in the derived classes @@ -101,12 +47,7 @@ module AdminUI # Web UI base path, like http://beef_domain//panel auth_url = "#{@bp}/authentication" - - # If access to the UI is not permitted for the request IP address return a 404 - if !authenticate_request(get_ip(@request)) - return - end - + # test if session is unauth'd and whether the auth functionality is requested if not @session.valid_session?(@request) and not self.class.eql?(BeEF::Extension::AdminUI::Controllers::Authentication) @body = '' diff --git a/extensions/admin_ui/controllers/authentication/authentication.rb b/extensions/admin_ui/controllers/authentication/authentication.rb index 66c9065e5..6fde20ed5 100644 --- a/extensions/admin_ui/controllers/authentication/authentication.rb +++ b/extensions/admin_ui/controllers/authentication/authentication.rb @@ -44,12 +44,9 @@ class Authentication < BeEF::Extension::AdminUI::HttpController config = BeEF::Core::Configuration.instance @headers['Content-Type']='application/json; charset=UTF-8' @headers['X-Frame-Options']='sameorigin' - if !config.get("beef.http.allow_reverse_proxy") - ua_ip = @request.get_header('REMOTE_ADDR') - else - ua_ip = @request.ip # get client ip address - end + ua_ip = @request.ip # get client ip address @body = '{ success : false }' # attempt to fail closed + # check if source IP address is permitted to authenticate if not permitted_source?(ua_ip) BeEF::Core::Logger.instance.register('Authentication', "IP source address (#{@request.ip}) attempted to authenticate but is not within permitted subnet.") diff --git a/spec/beef/extensions/adminui_spec.rb b/spec/beef/extensions/adminui_spec.rb deleted file mode 100644 index 72ec66057..000000000 --- a/spec/beef/extensions/adminui_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# -# Tests for handling access to the Admin UI -# - -require 'extensions/admin_ui/classes/httpcontroller' -require 'extensions/admin_ui/controllers/authentication/authentication' - -RSpec.describe 'BeEF Extension AdminUI' do - before(:all) do - @config = BeEF::Core::Configuration.instance - end - - it 'loads configuration' do - expect(@config.get('beef.restrictions')).to have_key('permitted_ui_subnet') - end - - it 'confirms that any ip address is permitted to view the admin ui' do - ui = BeEF::Extension::AdminUI::HttpController.new - expect(@config.set('beef.restrictions.permitted_ui_subnet',["0.0.0.0/0", "::/0"])).to eq true - expect(ui.authenticate_request("8.8.8.8")).to eq true - end - - it 'confirms that an ip address is permitted to view the admin ui' do - ui = BeEF::Extension::AdminUI::HttpController.new - expect(@config.set('beef.restrictions.permitted_ui_subnet',["192.168.10.1"])).to eq true - expect(ui.authenticate_request("192.168.10.1")).to eq true - end - - it 'confirms that an ip address is not permitted to view the admin ui' do - ui = BeEF::Extension::AdminUI::HttpController.new - expect(@config.set('beef.restrictions.permitted_ui_subnet',["10.10.10.1"])).to eq true - expect(ui.authenticate_request("8.8.8.8")).to eq false - end - - it 'confirms that X-Forwarded-For cant be spoofed when reverse proxy is disabled' do - ui = BeEF::Extension::AdminUI::HttpController.new - expect(@config.set('beef.restrictions.permitted_ui_subnet',["192.168.0.10"])).to eq true - expect(@config.set('beef.http.allow_reverse_proxy',false)).to eq true - env = { "REQUEST_METHOD" => "GET", "PATH_INFO" => "/ui/authentication" } - request = Rack::Request.new(env) - request.add_header("HTTP_X_FORWARDED_FOR","192.168.0.10") - request.add_header("REMOTE_ADDR","192.168.0.20") - expect(ui.get_ip(request)).to eq "192.168.0.20" - end - -end \ No newline at end of file