Skip to content

Commit 35b217b

Browse files
committed
Merge branch 'goliath' into http_client_change
2 parents 9647f8d + 8c51222 commit 35b217b

File tree

5 files changed

+40
-49
lines changed

5 files changed

+40
-49
lines changed

lib/metasploit/framework/data_service/remote/http/remote_loot_data_service.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ module RemoteLootDataService
66
LOOT_PATH = '/api/1/msf/loot'
77

88
def loot(opts = {})
9-
json_to_open_struct_object(self.get_data(LOOT_PATH, opts), [])
9+
# TODO: Add an option to toggle whether the file data is returned or not
10+
loots = json_to_open_struct_object(self.get_data(LOOT_PATH, opts), [])
11+
# Save a local copy of the file
12+
loots.each do |loot|
13+
if loot.data
14+
local_path = File.join(Msf::Config.loot_directory, File.basename(loot.path))
15+
loot.path = process_file(loot.data, local_path)
16+
end
17+
end
18+
loots
1019
end
1120

1221
def report_loot(opts)

lib/metasploit/framework/data_service/remote/http/remote_nmap_data_service.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ def import_nmap_xml_file(opts)
1414

1515
opts[:data] = Base64.urlsafe_encode64(data)
1616

17-
self.post_data_async(NMAP_PATH, opts)
17+
self.post_data(NMAP_PATH, opts)
1818
end
1919
end

lib/metasploit/framework/data_service/remote/http/response_data_helper.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'ostruct'
2+
require 'digest'
23

34
#
45
# HTTP response helper class
@@ -23,6 +24,27 @@ def json_to_open_struct_object(response_wrapper, returns_on_error = nil)
2324
return returns_on_error
2425
end
2526

27+
# Processes a Base64 encoded file included in a JSON request.
28+
# Saves the file in the location specified in the parameter.
29+
#
30+
# @param base64_file [String] The Base64 encoded file.
31+
# @param save_path [String] The location to store the file. This should include the file's name.
32+
# @return [String] The location where the file was successfully stored.
33+
def process_file(base64_file, save_path)
34+
decoded_file = Base64.urlsafe_decode64(base64_file)
35+
begin
36+
# If we are running the data service on the same box this will ensure we only write
37+
# the file if it is somehow not there already.
38+
unless File.exists?(save_path) && File.read(save_path) == decoded_file
39+
File.open(save_path, 'w+') { |file| file.write(decoded_file) }
40+
end
41+
rescue Exception => e
42+
puts "There was an error writing the file: #{e}"
43+
e.backtrace.each { |line| puts "#{line}\n"}
44+
end
45+
save_path
46+
end
47+
2648
#
2749
# Converts a hash to an open struct
2850
#

lib/msf/core/db_manager/http/servlet/loot_servlet.rb

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,48 +27,11 @@ def self.get_loot
2727

2828
def self.report_loot
2929
lambda {
30-
3130
job = lambda { |opts|
32-
# This regex does a best attempt to determine if opts[:data] is valid Base64
33-
# See https://stackoverflow.com/questions/8571501/how-to-check-whether-the-string-is-base64-encoded-or-not
34-
if opts[:data] =~ /^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/
35-
opts[:data] = Base64.urlsafe_decode64(opts[:data]) if opts[:data]
36-
end
37-
38-
# This code is all for writing out the file locally.
39-
# It is copied from lib/msf/core/auxiliary/report.rb
40-
# We shouldn't duplicate it so a better method should be used
41-
if ! ::File.directory?(Msf::Config.loot_directory)
42-
FileUtils.mkdir_p(Msf::Config.loot_directory)
43-
end
44-
45-
ext = 'bin'
46-
if opts[:name]
47-
parts = opts[:name].to_s.split('.')
48-
if parts.length > 1 and parts[-1].length < 4
49-
ext = parts[-1]
50-
end
51-
end
52-
53-
case opts[:content_type]
54-
when /^text\/[\w\.]+$/
55-
ext = "txt"
56-
end
57-
# This method is available even if there is no database, don't bother checking
58-
host = Msf::Util::Host.normalize_host(opts[:host])
59-
60-
ws = (opts[:workspace] ? opts[:workspace] : 'default')
61-
name =
62-
Time.now.strftime("%Y%m%d%H%M%S") + "_" + ws + "_" +
63-
(host || 'unknown') + '_' + opts[:type][0,16] + '_' +
64-
Rex::Text.rand_text_numeric(6) + '.' + ext
65-
66-
name.gsub!(/[^a-z0-9\.\_]+/i, '')
67-
68-
path = File.join(Msf::Config.loot_directory, name)
69-
full_path = ::File.expand_path(path)
70-
File.open(full_path, "wb") do |fd|
71-
fd.write(opts[:data])
31+
if opts[:data]
32+
filename = File.basename(opts[:path])
33+
local_path = File.join(Msf::Config.loot_directory, filename)
34+
opts[:path] = process_file(opts[:data], local_path)
7235
end
7336

7437
get_db().report_loot(opts)

lib/msf/core/db_manager/http/servlet/nmap_servlet.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@ def self.import_nmap_xml_file
1616
lambda {
1717

1818
job = lambda { |opts|
19-
20-
nmap_file = opts[:filename].split('/').last
21-
local_file = File.open(File.join(Msf::Config.local_directory, nmap_file), 'w')
22-
local_file.write(Base64.urlsafe_decode64(opts[:data]))
23-
local_file.close
24-
opts[:filename] = File.expand_path(local_file)
19+
nmap_file = File.basename(opts[:filename])
20+
nmap_file_path = File.join(Msf::Config.local_directory, nmap_file)
21+
opts[:filename] = process_file(opts[:data], nmap_file_path)
2522
get_db().import_nmap_xml_file(opts)
2623
}
2724
exec_report_job(request, &job)

0 commit comments

Comments
 (0)