rewrote the server core and adjusted the API/classes to use Thin and Rack instead of WebRick.

This commit is contained in:
antisnatchor
2011-11-19 15:49:19 +01:00
parent 1e32734565
commit 2997540918
25 changed files with 356 additions and 395 deletions

View File

@@ -23,7 +23,7 @@ module NetworkStack
# @param [Object] server HTTP server instance
def self.mount_handler(server)
# @note this mounts the dynamic handler
server.mount('/dh', true, BeEF::Core::NetworkStack::Handlers::DynamicReconstruction)
server.mount('/dh', BeEF::Core::NetworkStack::Handlers::DynamicReconstruction.new)
end
end

View File

@@ -41,18 +41,21 @@ module Handlers
# @return [String] URL Path of mounted asset
# @todo This function should accept a hooked browser session to limit the mounted file to a certain session
def bind(file, path=nil, extension=nil, count=-1)
url = buildURL(path, extension)
url = build_url(path, extension)
@allocations[url] = {'file' => "#{root_dir}"+file, 'path' => path, 'extension' => extension, 'count' => count}
@http_server.mount(url, true, WEBrick::HTTPServlet::FileHandler, @allocations[url]['file'])
@http_server.mount(url, Rack::File.new(@allocations[url]['file']))
@http_server.remap
print_info "File [" + "#{root_dir}"+file + "] bound to url [" + url + "]"
return url
url
end
# Unbinds a file from a mount point
# @param [String] url URL path of asset to be unbinded
#TODO: check why is throwing exception
def unbind(url)
@allocations.delete(url)
@http_server.unmount(url, true)
@http_server.unmount(url)
@http_server.remap
end
# Builds a URL based on the path and extension, if neither are passed a random URL will be generated
@@ -60,10 +63,10 @@ module Handlers
# @param [String] extension Extension defined by bind()
# @param [Integer] length The amount of characters to be used when generating a random URL
# @return [String] Generated URL
def buildURL(path, extension, length=20)
url = (path == nil) ? '/'+rand(36**length).to_s(36) : path;
url += (extension == nil) ? '' : '.'+extension;
return url
def build_url(path, extension, length=20)
url = (path == nil) ? '/'+rand(36**length).to_s(36) : path
url += (extension == nil) ? '' : '.'+extension
url
end
# Checks if the file is allocated, if the file isn't return true to pass onto FileHandler.
@@ -84,7 +87,7 @@ module Handlers
return true
end
end
return false
false
end
private

View File

@@ -18,10 +18,8 @@ module Core
module NetworkStack
module Handlers
# @note DynamicHanlder is used reconstruct segmented traffic from the hooked browser
class DynamicReconstruction < WEBrick::HTTPServlet::AbstractServlet
attr_reader :guard
# @note DynamicHandler is used reconstruct segmented traffic from the hooked browser
class DynamicReconstruction
# @note holds packet queue
PQ = Array.new()
@@ -29,28 +27,32 @@ module Handlers
# @note obtain dynamic mount points from HttpHookServer
MOUNTS = BeEF::Core::Server.instance.mounts
# Combines packet information and pushes to PQ, then checks packets
# @param [Object] request Request object
# @param [Object] response Response object
def do_POST(request, response)
@request = request
response.set_no_cache
response.header['Content-Type'] = 'text/javascript'
response.header['Access-Control-Allow-Origin'] = '*'
response.header['Access-Control-Allow-Methods'] = 'POST'
response.body = ''
# Combines packet information and pushes to PQ (packet queue), then checks packets
def call(env)
@request = Rack::Request.new(env)
response = Rack::Response.new(
body = [],
status = 200,
header = {
'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0',
'Content-Type' => 'text/javascript',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST'
}
)
PQ << {
:beefhook => get_param(@request.query, 'bh'),
:stream_id => Integer(get_param(@request.query, 'sid')),
:packet_id => Integer(get_param(@request.query, 'pid')),
:packet_count => Integer(get_param(@request.query, 'pc')),
:data => get_param(@request.query, 'd')
:beefhook => @request['bh'],
:stream_id => Integer(@request['sid']),
:packet_id => Integer(@request['pid']),
:packet_count => Integer(@request['pc']),
:data => @request['d']
}
check_packets()
response
end
# @note Alias do_GET function to do_POST
alias do_GET do_POST
# Check packets goes through the PQ array and attempts to reconstruct the stream from multiple packets
def check_packets()
@@ -79,7 +81,7 @@ module Handlers
res = JSON.parse(b64).first
res['beefhook'] = packet[:beefhook]
res['request'] = @request
res['beefsession'] = @request.get_hook_session_id()
res['beefsession'] = @request[BeEF::Core::Configuration.instance.get('beef.http.hook_session_name')]
execute(res)
rescue JSON::ParserError => e
print_debug 'Network stack could not decode packet stream.'
@@ -96,7 +98,7 @@ module Handlers
def expunge(beefhook, stream_id)
packets = PQ.select{ |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
PQ.delete_if { |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
return packets.sort_by { |p| p[:packet_id] }
packets.sort_by { |p| p[:packet_id] }
end
# Execute is called once a stream has been rebuilt. it searches the mounts and passes the data to the correct handler