Skip to content

Commit 60e78f0

Browse files
committed
Move file processing to helper method.
Also fixed a bug in processing loot files.
1 parent 82a30ed commit 60e78f0

File tree

3 files changed

+27
-45
lines changed

3 files changed

+27
-45
lines changed

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

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,46 +29,10 @@ def self.report_loot
2929
lambda {
3030

3131
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])
32+
if opts[:data]
33+
filename = File.basename(opts[:path])
34+
local_path = File.join(Msf::Config.loot_directory, filename)
35+
process_file(opts[:data], local_path)
7236
end
7337

7438
get_db().report_loot(opts)

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

Lines changed: 2 additions & 5 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-
2019
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)
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)

lib/msf/core/db_manager/http/servlet_helper.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,27 @@ def get_db()
5757
DBManagerProxy.instance.db
5858
end
5959

60+
# Processes a Base64 encoded file included in a JSON request.
61+
# Saves the file in the location specified in the parameter.
62+
#
63+
# @param base64_file [String] The Base64 encoded file.
64+
# @param save_dir [String] The location to store the file. This should include the file's name.
65+
# @return [String] The location where the file was successfully stored.
66+
def process_file(base64_file, save_dir)
67+
decoded_file = Base64.urlsafe_decode64(base64_file)
68+
begin
69+
# If we are running the data service on the same box this will ensure we only write
70+
# the file if it is somehow not there already.
71+
unless File.exists?(save_dir) && File.read(save_dir) == decoded_file
72+
File.open(save_dir, 'r+') { |file| file.write(decoded_file) }
73+
end
74+
rescue Exception => e
75+
puts "There was an error writing the file: #{e}"
76+
e.backtrace.each { |line| puts "#{line}\n"}
77+
end
78+
save_dir
79+
end
80+
6081
#######
6182
private
6283
#######

0 commit comments

Comments
 (0)