#970 started working on client-to-server DNS channel.
This commit is contained in:
@@ -21,6 +21,7 @@ module BeEF
|
||||
super()
|
||||
@lock = Mutex.new
|
||||
@database = BeEF::Core::Models::Dns::Rule
|
||||
@data_chunks = Hash.new
|
||||
end
|
||||
|
||||
# Adds a new DNS rule. If the rule already exists, its current ID is returned.
|
||||
@@ -139,6 +140,11 @@ module BeEF
|
||||
@lock.synchronize do
|
||||
print_debug "Received DNS request (name: #{name} type: #{format_resource(resource)})"
|
||||
|
||||
# no need to parse AAAA resources when data is extruded from client
|
||||
if format_resource(resource) == 'A'
|
||||
reconstruct(name)
|
||||
end
|
||||
|
||||
catch (:done) do
|
||||
# Find rules matching the requested resource class
|
||||
resources = @database.all(:resource => resource)
|
||||
@@ -166,6 +172,43 @@ module BeEF
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Collects and reconstructs data extruded by the client and found in subdomain, with structure like:
|
||||
#0.1.5.4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7.browserhacker.com
|
||||
#[...]
|
||||
#0.5.5.7565207175616d206469676e697373696d2065752e.browserhacker.com
|
||||
def reconstruct(data)
|
||||
split_data = data.split('.')
|
||||
pack_id = split_data[0]
|
||||
seq_num = split_data[1]
|
||||
seq_tot = split_data[2]
|
||||
data_chunk = split_data[3] # this might change if we store more than 63 bytes in a chunk (63 is the limitation from RFC)
|
||||
|
||||
if pack_id.match(/^(\d)+$/) and seq_num.match(/^(\d)+$/) and seq_tot.match(/^(\d)+$/)
|
||||
print_debug "[DNS] Received chunk (#{seq_num} / #{seq_tot}) of packet (#{pack_id}): #{data_chunk}"
|
||||
|
||||
if @data_chunks[pack_id] == nil
|
||||
# no previous chunks received, create new Array to store chunks
|
||||
@data_chunks[pack_id] = Array.new(seq_tot.to_i)
|
||||
@data_chunks[pack_id][seq_num.to_i - 1] = data_chunk
|
||||
else
|
||||
# previous chunks received, update Array
|
||||
@data_chunks[pack_id][seq_num.to_i - 1] = data_chunk
|
||||
if @data_chunks[pack_id].all? and @data_chunks[pack_id] != 'DONE'
|
||||
# means that no position in the array is false/nil, so we received all the packet chunks
|
||||
packet_data = @data_chunks[pack_id].join('')
|
||||
decoded_packet_data = packet_data.scan(/../).map{ |n| n.to_i(16)}.pack('U*')
|
||||
print_debug "[DNS] Packet data fully received: #{packet_data}. \n Converted from HEX: #{decoded_packet_data}"
|
||||
|
||||
# we might get more DNS requests for the same chunks sometimes, once every chunk of a packet is received, mark it
|
||||
@data_chunks[pack_id] = 'DONE'
|
||||
end
|
||||
end
|
||||
else
|
||||
print_debug "[DNS] Data (#{data}) is not a valid chunk."
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Helper method that converts a DNS rule to a hash.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user