beefproject / beef

The Browser Exploitation Framework Project
https://beefproject.com
9.89k stars 2.19k forks source link

Unable to load extension 's2c_dns_tunnel': [12:45:11] | uninitialized constant BeEF::Extension::ServerClientDnsTunnel::RubyDNS::Server #3003

Closed SoT10 closed 11 months ago

SoT10 commented 11 months ago

[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

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.

        # 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'

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')

      # 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

end end

dnsd.rb

module BeEF module Extension module ServerClientDnsTunnel module RubyDNS class Transaction def fail!(rcode, domain) append_question!

        @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

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)

stephenakq commented 11 months ago

Please join the BeEF discord to discuss this issue. Someone there might be able to help https://discord.gg/ugmKmHarKc