Revert "Merge pull request #1845 from beefproject/fix_broken_admin_ui_access"
This reverts commit5de127a0e2, reversing changes made tof5de5eb7c0.
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" +
|
||||
"<html><head>" +
|
||||
"<title>404 Not Found</title>" +
|
||||
"</head><body>" +
|
||||
"<h1>Not Found</h1>" +
|
||||
"<p>The requested URL was not found on this server.</p>" +
|
||||
"<hr>" +
|
||||
"<address>Apache/2.2.3 (CentOS)</address>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</body></html>"
|
||||
IIS_HEADER = {"Server" => "Microsoft-IIS/6.0",
|
||||
"X-Powered-By" => "ASP.NET",
|
||||
"Content-Type" => "text/html; charset=UTF-8"}
|
||||
IIS_BODY = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
||||
"<HTML><HEAD><TITLE>The page cannot be found</TITLE>" +
|
||||
"<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=Windows-1252\">" +
|
||||
"<STYLE type=\"text/css\">" +
|
||||
" BODY { font: 8pt/12pt verdana } " +
|
||||
" H1 { font: 13pt/15pt verdana }" +
|
||||
" H2 { font: 8pt/12pt verdana }" +
|
||||
" A:link { color: red }" +
|
||||
" A:visited { color: maroon }" +
|
||||
"</STYLE>" +
|
||||
"</HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD>" +
|
||||
"<h1>The page cannot be found</h1>" +
|
||||
"The page you are looking for might have been removed, had its name changed, or is temporarily unavailable." +
|
||||
"<hr>" +
|
||||
"<p>Please try the following:</p>" +
|
||||
"<ul>" +
|
||||
"<li>Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.</li>" +
|
||||
"<li>If you reached this page by clicking a link, contact" +
|
||||
" the Web site administrator to alert them that the link is incorrectly formatted." +
|
||||
"</li>" +
|
||||
"<li>Click the <a href=\"javascript:history.back(1)\">Back</a> button to try another link.</li>" +
|
||||
"</ul>" +
|
||||
"<h2>HTTP Error 404 - File or directory not found.<br>Internet Information Services (IIS)</h2>" +
|
||||
"<hr>" +
|
||||
"<p>Technical Information (for support personnel)</p>" +
|
||||
"<ul>" +
|
||||
"<li>Go to <a href=\"http://go.microsoft.com/fwlink/?linkid=8180\">Microsoft Product Support Services</a> and perform a title search for the words <b>HTTP</b> and <b>404</b>.</li>" +
|
||||
"<li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr)," +
|
||||
"and search for topics titled <b>Web Site Setup</b>, <b>Common Administrative Tasks</b>, and <b>About Custom Error Messages</b>.</li>" +
|
||||
"</ul>" +
|
||||
"</TD></TR></TABLE>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</BODY></HTML>"
|
||||
NGINX_HEADER = {"Server" => "nginx",
|
||||
"Content-Type" => "text/html"}
|
||||
NGINX_BODY = "<html>\n"+
|
||||
"<head><title>404 Not Found</title></head>\n" +
|
||||
"<body bgcolor=\"white\">\n" +
|
||||
"<center><h1>404 Not Found</h1></center>\n" +
|
||||
"<hr><center>nginx</center>\n" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</body>\n" +
|
||||
"</html>\n"
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -24,13 +24,61 @@ module BeEF
|
||||
case type
|
||||
when "apache"
|
||||
#response body
|
||||
BeEF::Core::Router::APACHE_BODY
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" +
|
||||
"<html><head>" +
|
||||
"<title>404 Not Found</title>" +
|
||||
"</head><body>" +
|
||||
"<h1>Not Found</h1>" +
|
||||
"<p>The requested URL was not found on this server.</p>" +
|
||||
"<hr>" +
|
||||
"<address>Apache/2.2.3 (CentOS)</address>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</body></html>"
|
||||
when "iis"
|
||||
#response body
|
||||
BeEF::Core::Router::IIS_BODY
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
||||
"<HTML><HEAD><TITLE>The page cannot be found</TITLE>" +
|
||||
"<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=Windows-1252\">" +
|
||||
"<STYLE type=\"text/css\">" +
|
||||
" BODY { font: 8pt/12pt verdana } " +
|
||||
" H1 { font: 13pt/15pt verdana }" +
|
||||
" H2 { font: 8pt/12pt verdana }" +
|
||||
" A:link { color: red }" +
|
||||
" A:visited { color: maroon }" +
|
||||
"</STYLE>" +
|
||||
"</HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD>" +
|
||||
"<h1>The page cannot be found</h1>" +
|
||||
"The page you are looking for might have been removed, had its name changed, or is temporarily unavailable." +
|
||||
"<hr>" +
|
||||
"<p>Please try the following:</p>" +
|
||||
"<ul>" +
|
||||
"<li>Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.</li>" +
|
||||
"<li>If you reached this page by clicking a link, contact" +
|
||||
" the Web site administrator to alert them that the link is incorrectly formatted." +
|
||||
"</li>" +
|
||||
"<li>Click the <a href=\"javascript:history.back(1)\">Back</a> button to try another link.</li>" +
|
||||
"</ul>" +
|
||||
"<h2>HTTP Error 404 - File or directory not found.<br>Internet Information Services (IIS)</h2>" +
|
||||
"<hr>" +
|
||||
"<p>Technical Information (for support personnel)</p>" +
|
||||
"<ul>" +
|
||||
"<li>Go to <a href=\"http://go.microsoft.com/fwlink/?linkid=8180\">Microsoft Product Support Services</a> and perform a title search for the words <b>HTTP</b> and <b>404</b>.</li>" +
|
||||
"<li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr)," +
|
||||
"and search for topics titled <b>Web Site Setup</b>, <b>Common Administrative Tasks</b>, and <b>About Custom Error Messages</b>.</li>" +
|
||||
"</ul>" +
|
||||
"</TD></TR></TABLE>" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</BODY></HTML>"
|
||||
when "nginx"
|
||||
#response body
|
||||
BeEF::Core::Router::NGINX_BODY
|
||||
"<html>\n"+
|
||||
"<head><title>404 Not Found</title></head>\n" +
|
||||
"<body bgcolor=\"white\">\n" +
|
||||
"<center><h1>404 Not Found</h1></center>\n" +
|
||||
"<hr><center>nginx</center>\n" +
|
||||
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_imitation.hook_404")).to_s +
|
||||
"</body>\n" +
|
||||
"</html>\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"
|
||||
|
||||
@@ -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/<bp>/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 = ''
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user