Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/core/main/server.rb
1154 views
1
#
2
# Copyright (c) 2006-2025 Wade Alcorn - [email protected]
3
# Browser Exploitation Framework (BeEF) - https://beefproject.com
4
# See the file 'doc/COPYING' for copying permission
5
#
6
7
# Remove Thin 'Server' response header
8
Thin.send :remove_const, :SERVER
9
Thin::SERVER = nil
10
11
module BeEF
12
module Core
13
class Server
14
include Singleton
15
attr_reader :root_dir, :url, :configuration, :command_urls, :mounts, :semaphore
16
17
def initialize
18
@configuration = BeEF::Core::Configuration.instance
19
@url = @configuration.beef_url_str
20
@root_dir = File.expand_path('../../../', __dir__)
21
@command_urls = {}
22
@mounts = {}
23
@rack_app
24
@semaphore = Mutex.new
25
end
26
27
def to_h
28
{
29
'beef_version' => @configuration.get('beef_version'),
30
'beef_url' => @url,
31
'beef_root_dir' => @root_dir,
32
'beef_host' => @configuration.beef_host,
33
'beef_port' => @configuration.beef_port,
34
'beef_public' => @configuration.public_host,
35
'beef_public_port' => @configuration.public_port,
36
'beef_hook' => @configuration.get('beef.http.hook_file'),
37
'beef_proto' => @configuration.beef_proto,
38
'client_debug' => @configuration.get('beef.client_debug')
39
}
40
end
41
42
#
43
# Mounts a handler, can either be a hard or soft mount
44
#
45
# @param [String] url The url to mount
46
# @param [Class] http_handler_class Class to call once mount is triggered
47
# @param args Arguments to pass to the http handler class
48
#
49
def mount(url, http_handler_class, args = nil)
50
# argument type checking
51
raise TypeError, '"url" needs to be a string' unless url.is_a?(String)
52
53
@mounts[url] = if args.nil?
54
http_handler_class
55
else
56
[http_handler_class, *args]
57
end
58
print_debug "Server: mounted handler '#{url}'"
59
end
60
61
#
62
# Unmounts handler
63
#
64
# @param [String] url URL to unmount.
65
#
66
def unmount(url)
67
raise TypeError, '"url" needs to be a string' unless url.is_a?(String)
68
69
@mounts.delete url
70
end
71
72
#
73
# Reload the URL map (used by the NetworkStack AssetHandler to mount new URLs at runtime)
74
#
75
def remap
76
@rack_app.remap @mounts
77
end
78
79
#
80
# Prepares the BeEF http server.
81
#
82
def prepare
83
# Create http handler for the javascript hook file
84
mount(@configuration.get('beef.http.hook_file').to_s, BeEF::Core::Handlers::HookedBrowsers.new)
85
86
# Create handler for the initialization checks (Browser Details)
87
mount('/init', BeEF::Core::Handlers::BrowserDetails)
88
89
# Dynamically get the list of all the http handlers using the API and register them
90
BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'mount_handler', self)
91
92
# Rack mount points
93
@rack_app = Rack::URLMap.new(@mounts)
94
95
return if @http_server
96
97
# Set the logging level of Thin to match the config
98
Thin::Logging.silent = true
99
if @configuration.get('beef.http.debug') == true
100
Thin::Logging.silent = false
101
Thin::Logging.debug = true
102
end
103
104
# Create the BeEF http server
105
@http_server = Thin::Server.new(
106
@configuration.get('beef.http.host'),
107
@configuration.get('beef.http.port'),
108
@rack_app
109
)
110
111
# Configure SSL/TLS
112
return unless @configuration.get('beef.http.https.enable') == true
113
114
openssl_version = OpenSSL::OPENSSL_VERSION
115
if openssl_version =~ / 1\.0\.1([a-f])? /
116
print_warning "Warning: #{openssl_version} is vulnerable to Heartbleed (CVE-2014-0160)."
117
print_more 'Upgrade OpenSSL to version 1.0.1g or newer.'
118
end
119
120
cert_key = @configuration.get 'beef.http.https.key'
121
cert_key = File.expand_path cert_key, $root_dir unless cert_key.start_with? '/'
122
unless File.exist? cert_key
123
print_error "Error: #{cert_key} does not exist"
124
exit 1
125
end
126
127
cert = @configuration.get 'beef.http.https.cert'
128
cert = File.expand_path cert, $root_dir unless cert.start_with? '/'
129
unless File.exist? cert
130
print_error "Error: #{cert} does not exist"
131
exit 1
132
end
133
134
@http_server.ssl = true
135
@http_server.ssl_options = {
136
private_key_file: cert_key,
137
cert_chain_file: cert,
138
verify_peer: false
139
}
140
141
if Digest::SHA256.hexdigest(File.read(cert)).eql?('978f761fc30cbd174eab0c6ffd2d235849260c0589a99262f136669224c8d82a') ||
142
Digest::SHA256.hexdigest(File.read(cert_key)).eql?('446214bb608caf9e21dd105ce3d4ea65a3f32949906f3eb25a2c622a68623122')
143
print_warning 'Warning: Default SSL cert/key in use.'
144
print_more 'Use the generate-certificate utility to generate a new certificate.'
145
end
146
rescue StandardError => e
147
print_error "Failed to prepare HTTP server: #{e.message}"
148
print_error e.backtrace
149
exit 1
150
end
151
152
#
153
# Starts the BeEF http server
154
#
155
def start
156
@http_server.start do
157
use OTR::ActiveRecord::ConnectionManagement
158
end
159
rescue RuntimeError => e
160
# port is in use
161
raise unless e.message.include? 'no acceptor'
162
163
print_error "Another process is already listening on port #{@configuration.get('beef.http.port')}, or you're trying to bind BeEF to an invalid IP."
164
print_error 'Is BeEF already running? Exiting...'
165
exit 127
166
end
167
end
168
end
169
end
170
171