[12:45:11][] Browser Exploitation Framework (BeEF) 0.5.4.0
[12:45:11] | Twit: @beefproject
[12:45:11] | Site: https://beefproject.com
[12:45:11] |_ Wiki: https://github.com/beefproject/beef/wiki
[12:45:11][] Project Creator: Wade Alcorn (@WadeAlcorn)
[12:45:11][!] Unable to load extension 's2c_dnstunnel':
[12:45:11] | uninitialized constant BeEF::Extension::ServerClientDnsTunnel::RubyDNS::Server
[12:45:11] | Did you mean? TCPServer
[12:45:11][] BeEF is loading. Wait a few seconds...
[12:45:20][] 8 extensions enabled:
[12:45:20] | XSSRays
[12:45:20] | Social Engineering
[12:45:20] | Requester
[12:45:20] | Proxy
[12:45:20] | Network
[12:45:20] | Events
[12:45:20] | Demos
[12:45:20] | Admin UI
[12:45:20][] 303 modules enabled.
[12:45:20][] 3 network interfaces were detected.
[12:45:20][*] running on network interface: 127.0.0.1
[12:45:20] | Hook URL: http://127.0.0.1:3000/hook.js
[12:45:20] | UI URL: http://127.0.0.1:3000/ui/panel
[12:45:20][] running on network interface: x
[12:45:20] | Hook URL: http://x:3000/hook.js
[12:45:20] |_ UI URL: http://x:3000/ui/panel
[12:45:20][] running on network interface: x
[12:45:20] | Hook URL: http://x:3000/hook.js
[12:45:20] |_ UI URL: http://x:3000/ui/panel
[12:45:20][] RESTful API key: x
[12:45:21][] HTTP Proxy: http://127.0.0.1:6789
my main config.yaml
beef:
version: '0.5.4.0'
More verbose messages (server-side)
debug: false
# More verbose messages (client-side)
client_debug: true
# 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: "x"
passwd: "x"
# Interface / IP restrictions
restrictions:
# subnet of IP addresses that can hook to the framework
permitted_hooking_subnet: ["0.0.0.0/0", "::/0"]
# subnet of IP addresses that can connect to the admin UI
#permitted_ui_subnet: ["127.0.0.1/32", "::1/128"]
permitted_ui_subnet: ["0.0.0.0/0", "::/0"]
# subnet of IP addresses that cannot be hooked by the framework
excluded_hooking_subnet: []
# 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
# Public Domain Name / Reverse Proxy / Port Forwarding
#
# In order for the client-side BeEF JavaScript hook to be able to connect to BeEF,
# the hook JavaScript needs to be generated with the correct connect-back details.
#
# If you're using a public domain name, reverse proxy, or port forwarding you must
# configure the public-facing connection details here.
#public:
# host: "beef.local" # public hostname/IP address
# port: "443" # public port (443 if the public server is using HTTPS)
# https: false # true/false
# If using any reverse proxy you should also set allow_reverse_proxy to true below.
# Note that this causes the BeEF server to trust the X-Forwarded-For HTTP header.
# If the BeEF server is directly accessible, clients can spoof their connecting
# IP address using this header to bypass the IP address permissions/exclusions.
allow_reverse_proxy: false
# Hook
hook_file: "/hook.js"
hook_session_name: "BEEFHOOK"
# 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:
enable: false
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: 5000 # poll BeEF every x second, this affects how often the browser can have a command execute on it
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:
file: "beef.db"
# 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 eventually
# 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 timeout.
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
geoip:
enable: true
# GeoLite2 City database created by MaxMind, available from https://www.maxmind.com
database: '/usr/share/GeoIP/GeoLite2-City.mmdb'
# 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
s2c_dns_tunnel:
enable: true
Define which network interface DNS server should listen. IP-address of this interface will be used in DNS answers.
# By default, DNS server will be started on the interface which has a highest IP-address and will listen UDP 53 port only.
#listen: ''
# Zone managed by DNS server. DNS server will not be started if zone is not specified
zone: 'domen.com'
# Starts the S2C DNS Tunnel server at BeEF startup.
# @param http_hook_server [BeEF::Core::Server] HTTP server instance
def self.pre_http_start(_http_hook_server)
configuration = BeEF::Core::Configuration.instance
zone = configuration.get('beef.extension.s2c_dns_tunnel.zone')
raise ArgumentError, 'zone name is undefined' unless zone.to_s != ''
# if listen parameter is not defined in the config.yaml then interface with the highest BeEF's IP-address will be choosen
listen = configuration.get('beef.extension.s2c_dns_tunnel.listen')
Socket.ip_address_list.map { |x| listen = x.ip_address if x.ipv4? } if listen.to_s.empty?
port = 53
protocol = :udp
interfaces = [[protocol, listen, port]]
dns = BeEF::Extension::ServerClientDnsTunnel::Server.instance
dns.run(listen: interfaces, zone: zone)
print_info "Server-to-Client DNS Tunnel Server: #{listen}:#{port} (#{protocol})"
info = ''
info += "Zone: #{zone}\n"
print_more info
end
# Mounts the handler for processing HTTP image requests.
# @param beef_server [BeEF::Core::Server] HTTP server instance
def self.mount_handler(beef_server)
configuration = BeEF::Core::Configuration.instance
zone = configuration.get('beef.extension.s2c_dns_tunnel.zone')
beef_server.mount('/tiles', BeEF::Extension::ServerClientDnsTunnel::Httpd.new(zone))
end
end
end
end
@answer.rcode = if rcode.is_a? Symbol
Resolv::DNS::RCode.const_get(rcode)
else
rcode.to_i
end
return unless rcode == :NXDomain
@answer.aa = 1
soa = Resolv::DNS::Resource::IN::SOA.new(Resolv::DNS::Name.create("ns.#{domain}"),
Resolv::DNS::Name.create("hostmaster.#{domain}"),
Time.now.strftime('%Y%m%d%H').to_i, 86_400, 7200, 3_600_000, 172_800)
@answer.add_authority(name, 3600, soa)
end
end
end
class Server < RubyDNS::Server
include Singleton
attr_accessor :messages
def initialize
super()
@lock = Mutex.new
end
# Starts the custom DNS server.
#
# @param options [Hash] server configuration options
# @option options [Array<Array>] :zone - zone manged by BeEF DNS server for data exfiltration
# @option options [Array<Array>] :listen - local interfaces to listen on
def run(options = {})
@lock.synchronize do
Thread.new do
EventMachine.next_tick do
listen = options[:listen] || nil
super(listen: listen)
@selfip = options[:listen][0][1]
@zone = options[:zone]
@messages = {}
end
end
end
end
# Entry point for processing incoming DNS requests.
#
# @param name [String] name of the resource record being looked up
# @param resource [Resolv::DNS::Resource::IN] query type (e.g. A, CNAME, NS, etc.)
# @param transaction [RubyDNS::Transaction] internal RubyDNS class detailing DNS question/answer
def process(name, resource, transaction)
@lock.synchronize do
print_debug "Received DNS request (name: #{name} type: #{format_resource(resource)})"
if (format_resource(resource) != 'A') || !name.match(/#{@zone}$/)
transaction.fail!(:Refused, @zone)
return
end
# Parce query name in accordance with Active Directory SRV resource records
cid = name.split('.')[2].split('-')[2].to_i
bit = name.split('.')[2].split('-')[3].to_i(16)
if @messages[cid].nil?
transaction.fail!(:NXDomain, @zone)
return
else
message = @messages[cid]
end
if message.length <= bit
transaction.fail!(:NXDomain, @zone)
return
end
# If the bit is equal to 1 we should return one of the BeEF's IP addresses
case message[bit]
when '1'
transaction.respond!(@selfip)
return
# If the bit is equal to 0 we should return NXDomain message
when '0'
transaction.fail!(:NXDomain, @zone)
return
end
end
end
private
# Helper method that formats the given resource class in a human-readable format.
#
# @param resource [Resolv::DNS::Resource::IN] resource class
# @return [String] resource name stripped of any module/class names
def format_resource(resource)
/::(\w+)$/.match(resource.name)[1]
end
end
end
end
end
httpd.rb
module BeEF
module Extension
module ServerClientDnsTunnel
class Httpd < Sinatra::Base
def initialize(domain)
super()
@domain = domain
end
get '/map' do
if request.host.match("^_ldap\._tcp\.[0-9a-z\-]+\.domains\._msdcs\.#{@domain}$")
path = File.dirname(__FILE__)
send_file File.join(path, 'pixel.jpg')
end
end
end
end
#
module BeEF
module Extension
module ServerClientDnsTunnel
extend BeEF::API::Extension
@short_name = 'S2C DNS Tunnel'
@full_name = 'Server-to-Client DNS Tunnel'
@description = 'This extension provides a custom BeEF DNS server and HTTP server ' \
'that implement unidirectional covert timing channel from BeEF communication server to zombie browser.'
end
end
end
[12:45:11][] Browser Exploitation Framework (BeEF) 0.5.4.0 [12:45:11] | Twit: @beefproject [12:45:11] | Site: https://beefproject.com [12:45:11] |_ Wiki: https://github.com/beefproject/beef/wiki [12:45:11][] Project Creator: Wade Alcorn (@WadeAlcorn) [12:45:11][!] Unable to load extension 's2c_dnstunnel': [12:45:11] | uninitialized constant BeEF::Extension::ServerClientDnsTunnel::RubyDNS::Server [12:45:11] | Did you mean? TCPServer [12:45:11][] BeEF is loading. Wait a few seconds... [12:45:20][] 8 extensions enabled: [12:45:20] | XSSRays [12:45:20] | Social Engineering [12:45:20] | Requester [12:45:20] | Proxy [12:45:20] | Network [12:45:20] | Events [12:45:20] | Demos [12:45:20] | Admin UI [12:45:20][] 303 modules enabled. [12:45:20][] 3 network interfaces were detected. [12:45:20][*] running on network interface: 127.0.0.1 [12:45:20] | Hook URL: http://127.0.0.1:3000/hook.js [12:45:20] | UI URL: http://127.0.0.1:3000/ui/panel [12:45:20][] running on network interface: x [12:45:20] | Hook URL: http://x:3000/hook.js [12:45:20] |_ UI URL: http://x:3000/ui/panel [12:45:20][] running on network interface: x [12:45:20] | Hook URL: http://x:3000/hook.js [12:45:20] |_ UI URL: http://x:3000/ui/panel [12:45:20][] RESTful API key: x [12:45:21][] HTTP Proxy: http://127.0.0.1:6789
my main config.yaml
beef: version: '0.5.4.0'
More verbose messages (server-side)
config.yaml for extension s2c_dns_tunnel
beef: extension: s2c_dns_tunnel: enable: false name: 'Server-to-Client DNS Tunnel' authors: ['dnkolegov','afr1ka']
Define which network interface DNS server should listen. IP-address of this interface will be used in DNS answers.
api.rb
module BeEF module Extension module ServerClientDnsTunnel module API module ServerClientDnsTunnelHandler BeEF::API::Registrar.instance.register(BeEF::Extension::ServerClientDnsTunnel::API::ServerClientDnsTunnelHandler, BeEF::API::Server, 'pre_http_start') BeEF::API::Registrar.instance.register(BeEF::Extension::ServerClientDnsTunnel::API::ServerClientDnsTunnelHandler, BeEF::API::Server, 'mount_handler')
end end
dnsd.rb
module BeEF module Extension module ServerClientDnsTunnel module RubyDNS class Transaction def fail!(rcode, domain) append_question!
end end
httpd.rb
module BeEF module Extension module ServerClientDnsTunnel class Httpd < Sinatra::Base def initialize(domain) super() @domain = domain end
end end
require 'sinatra/base'
extension.rb
#
Copyright (c) 2006-2024 Wade Alcorn - wade@bindshell.net
Browser Exploitation Framework (BeEF) - https://beefproject.com
See the file 'doc/COPYING' for copying permission
# module BeEF module Extension module ServerClientDnsTunnel extend BeEF::API::Extension @short_name = 'S2C DNS Tunnel' @full_name = 'Server-to-Client DNS Tunnel' @description = 'This extension provides a custom BeEF DNS server and HTTP server ' \ 'that implement unidirectional covert timing channel from BeEF communication server to zombie browser.' end end end
require 'extensions/s2c_dns_tunnel/dnsd' require 'extensions/s2c_dns_tunnel/api' require 'extensions/s2c_dns_tunnel/httpd'
beef version 0.5.4.0 ruby 3.0.2p107 (2021-07-07 revision 0db68f0233)