WIP remote vuln read, update, delete

GSoC/Meterpreter_Web_Console
Matthew Kienow 2018-02-22 13:53:22 -05:00
parent 7ad7188824
commit 22752518ea
No known key found for this signature in database
GPG Key ID: 40787F8B1EAC6E41
4 changed files with 160 additions and 10 deletions

View File

@ -1,5 +1,14 @@
module VulnDataProxy
def vulns(opts)
begin
data_service = self.get_data_service()
data_service.vulns(opts)
rescue Exception => e
self.log_error(e, "Problem retrieving vulns")
end
end
def report_vuln(opts)
begin
data_service = self.get_data_service()
@ -9,4 +18,24 @@ module VulnDataProxy
end
end
def update_vuln(opts)
begin
data_service = self.get_data_service()
data_service.update_vuln(opts)
rescue Exception => e
self.log_error(e, "Problem updating vuln")
end
end
def delete_vuln(opts)
begin
data_service = self.get_data_service()
data_service.delete_vuln(opts)
rescue Exception => e
self.log_error(e, "Problem deleting vuln")
end
end
end

View File

@ -1,7 +1,29 @@
require 'metasploit/framework/data_service/remote/http/response_data_helper'
module RemoteVulnDataService
include ResponseDataHelper
VULN_API_PATH = '/api/v1/vulns'
VULN_MDM_CLASS = 'Mdm::Vuln'
def vulns(opts)
json_to_mdm_object(self.get_data(VULN_API_PATH, nil, opts), VULN_MDM_CLASS, [])
end
def report_vuln(opts)
self.post_data_async(VULN_API_PATH, opts)
json_to_mdm_object(self.post_data(VULN_API_PATH, opts), VULN_MDM_CLASS, []).first
end
def update_vuln(opts)
path = VULN_API_PATH
if opts && opts[:id]
id = opts.delete(:id)
path = "#{VULN_API_PATH}/#{id}"
end
json_to_mdm_object(self.put_data(path, opts), VULN_MDM_CLASS, [])
end
def delete_vuln(opts)
json_to_mdm_object(self.delete_data(VULN_API_PATH, opts), VULN_MDM_CLASS, [])
end
end

View File

@ -4,20 +4,70 @@ module VulnServlet
'/api/v1/vulns'
end
def self.api_path_with_id
"#{VulnServlet.api_path}/?:id?"
end
def self.registered(app)
app.get VulnServlet.api_path_with_id, &get_vuln
app.post VulnServlet.api_path, &report_vuln
app.put VulnServlet.api_path_with_id, &update_vuln
app.delete VulnServlet.api_path, &delete_vuln
end
#######
private
#######
def self.get_vuln
lambda {
begin
opts = parse_json_request(request, false)
data = get_db().vulns(params.symbolize_keys)
includes = [:host]
set_json_response(data, includes)
rescue Exception => e
set_error_on_response(e)
end
}
end
def self.report_vuln
lambda {
begin
job = lambda { |opts|
get_db().report_vuln(opts)
}
exec_report_job(request, &job)
rescue Exception => e
set_error_on_response(e)
end
}
end
def self.update_vuln
lambda {
begin
opts = parse_json_request(request, false)
tmp_params = params.symbolize_keys
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db().update_vuln(opts)
set_json_response(data)
rescue Exception => e
set_error_on_response(e)
end
}
end
def self.delete_vuln
lambda {
begin
opts = parse_json_request(request, false)
data = get_db().delete_vuln(opts)
set_json_response(data)
rescue Exception => e
set_error_on_response(e)
end
}
end

View File

@ -235,9 +235,58 @@ module Msf::DBManager::Vuln
#
# This methods returns a list of all vulnerabilities in the database
#
def vulns(wspace=workspace)
def vulns(opts)
wspace = opts.delete(:workspace) || opts.delete(:wspace) || workspace
if wspace.kind_of? String
wspace = find_workspace(wspace)
end
::ActiveRecord::Base.connection_pool.with_connection {
wspace.vulns
search_term = opts.delete(:search_term)
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Vuln, search_term)
wspace.vulns.includes(:host).where(opts).where(column_search_conditions)
}
end
# Update the attributes of a Vuln entry with the values in opts.
# The values in opts should match the attributes to update.
#
# @param opts [Hash] Hash containing the updated values. Key should match the attribute to update. Must contain :id of record to update.
# @return [Mdm::Vuln] The updated Mdm::Vuln object.
def update_vuln(opts)
# process workspace string for update if included in opts
wspace = opts.delete(:workspace)
if wspace.kind_of? String
wspace = find_workspace(wspace)
opts[:workspace] = wspace
end
::ActiveRecord::Base.connection_pool.with_connection {
id = opts.delete(:id)
Mdm::Vuln.update(id, opts)
}
end
# Deletes Vuln entries based on the IDs passed in.
#
# @param opts[:ids] [Array] Array containing Integers corresponding to the IDs of the Vuln entries to delete.
# @return [Array] Array containing the Mdm::Vuln objects that were successfully deleted.
def delete_vuln(opts)
raise ArgumentError.new("The following options are required: :ids") if opts[:ids].nil?
::ActiveRecord::Base.connection_pool.with_connection {
deleted = []
opts[:ids].each do |vuln_id|
vuln = Mdm::Vuln.find(vuln_id)
begin
deleted << vuln.destroy
rescue # refs suck
elog("Forcibly deleting #{vuln}")
deleted << vuln.delete
end
end
return deleted
}
end
end