Module: Msf::WebServices::LootServlet

Defined in:
lib/msf/core/web_services/servlet/loot_servlet.rb

Class Method Summary collapse

Class Method Details

.api_path ⇒ Object



3
4
5
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 3

def self.api_path
  '/api/v1/loots'
end

.api_path_with_id ⇒ Object



7
8
9
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 7

def self.api_path_with_id
  "#{self.api_path}/?:id?"
end

.delete_loot ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 83

def self.delete_loot
  lambda {
    warden.authenticate!
    begin
      opts = parse_json_request(request, false)
      data = get_db.delete_loot(opts)
      # The rails delete operation returns a frozen object. We need to Base64 encode the data
      # before converting to JSON. So we'll work with a duplicate of the original if it is frozen.
      data.map! { |loot| loot.dup if loot.frozen? }
      data = encode_loot_data(data)
      set_json_data_response(response: data)
    rescue StandardError => e
      print_error_and_create_response(error: e, message: 'There was an error deleting the loot:', code: 500)
    end
  }
end

.get_loot ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 23

def self.get_loot
  lambda {
    warden.authenticate!
    begin
      sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
      data = get_db.loots(sanitized_params)
      includes = [:host]
      data = encode_loot_data(data)
      data = data.first if is_single_object?(data, sanitized_params)
      set_json_data_response(response: data, includes: includes)
    rescue ActiveRecord::RecordNotFound => e
      create_error_response(error: e, message: 'Loot record was not found', code: 404)
    rescue StandardError => e
      print_error_and_create_response(error: e, message: 'There was an error retrieving the loot:', code: 500)
    end
  }
end

.registered(app) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 11

def self.registered(app)
  app.get self.api_path, &get_loot
  app.get self.api_path_with_id, &get_loot
  app.post self.api_path, &report_loot
  app.put self.api_path_with_id, &update_loot
  app.delete self.api_path, &delete_loot
end

.report_loot ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 41

def self.report_loot
  lambda {
    warden.authenticate!
    job = lambda { |opts|
      if opts[:data]
        filename = File.basename(opts[:path])
        local_path = File.join(Msf::Config.loot_directory, "#{SecureRandom.hex(10)}-#{filename}")
        opts[:path] = process_file(opts[:data], local_path)
        opts[:data] = Base64.urlsafe_decode64(opts[:data])
      end

      data = get_db.report_loot(opts)
      encode_loot_data(data)
    }
    exec_report_job(request, &job)
  }
end

.update_loot ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/msf/core/web_services/servlet/loot_servlet.rb', line 59

def self.update_loot
  lambda {
    warden.authenticate!
    begin
      opts = parse_json_request(request, false)
      tmp_params = sanitize_params(params)
      opts[:id] = tmp_params[:id] if tmp_params[:id]
      db_record = get_db.loots(opts).first
      # Give the file a unique name to prevent accidental overwrites. Only do this if there is actually a file
      # on disk. If there is not a file on disk we assume that this DB record is for tracking a file outside
      # of metasploit, so we don't want to assign them a unique file name and overwrite that.
      if opts[:path] && File.exist?(db_record.path)
        filename = File.basename(opts[:path])
        opts[:path] = File.join(Msf::Config.loot_directory, "#{SecureRandom.hex(10)}-#{filename}")
      end
      data = get_db.update_loot(opts)
      data = encode_loot_data(data)
      set_json_data_response(response: data)
    rescue StandardError => e
      print_error_and_create_response(error: e, message: 'There was an error updating the loot:', code: 500)
    end
  }
end