Merge branch 'conform_to_api_standards' into exploit-query

Prepare for new JSON format.
GSoC/Meterpreter_Web_Console
Erin Bleiweiss 2018-07-31 14:48:37 -05:00
commit 3e8efea57a
63 changed files with 1075 additions and 444 deletions

View File

@ -158,12 +158,21 @@ module CredentialApiDoc
response 200 do
key :description, 'Returns credential data.'
schema do
key :type, :array
items do
key :'$ref', :Credential
property :data do
key :type, :array
items do
key :'$ref', :Credential
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/credentials POST
@ -197,8 +206,16 @@ module CredentialApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Credential
property :data do
key :'$ref', :Credential
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -211,7 +228,7 @@ module CredentialApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted credentials.'
schema do
key :type, :array
items do
@ -219,39 +236,54 @@ module CredentialApiDoc
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
swagger_path '/api/v1/credentials/{id}' do
# Swagger documentation for api/v1/credentials/:id GET
# TODO: Uncomment below when this endpoint is implemented.
# operation :get do
# key :description, 'Return credentials that are stored in the database.'
# key :tags, [ 'credential' ]
#
# parameter :workspace
# parameter :non_dead
# parameter :address
#
# parameter do
# key :name, :id
# key :in, :path
# key :description, 'ID of credential to retrieve.'
# key :required, true
# key :type, :integer
# key :format, :int32
# end
#
# response 200 do
# key :description, 'Returns credential data.'
# schema do
# key :type, :array
# items do
# key :'$ref', :Credential
# end
# end
# end
# end
operation :get do
key :description, 'Return credential that is stored in the database.'
key :tags, [ 'credential' ]
parameter :workspace
parameter :non_dead
parameter :address
parameter do
key :name, :id
key :in, :path
key :description, 'ID of credential to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
response 200 do
key :description, 'Returns credential data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :Credential
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
#Swagger documentation for /api/v1/credentials/:id PUT
operation :put do
@ -273,8 +305,16 @@ module CredentialApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Credential
property :data do
key :'$ref', :Credential
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -28,11 +28,20 @@ module DbExportApiDoc
response 200 do
key :description, 'A JSON object containing the Base64 encoded backup file.'
schema do
property :db_export_file do
key :type, :string
property :data do
property :db_export_file do
key :type, :string
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
end

View File

@ -50,8 +50,16 @@ module EventApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Event
property :data do
key :'$ref', :Event
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -58,8 +58,16 @@ module ExploitApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Exploit
property :data do
key :'$ref', :Exploit
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -104,12 +104,21 @@ module HostApiDoc
response 200 do
key :description, 'Returns host data.'
schema do
key :type, :array
items do
key :'$ref', :Host
property :data do
key :type, :array
items do
key :'$ref', :Host
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/hosts POST
@ -153,8 +162,16 @@ module HostApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Host
property :data do
key :'$ref', :Host
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -167,14 +184,23 @@ module HostApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted hosts.'
schema do
key :type, :array
items do
key :'$ref', :Host
property :data do
key :type, :array
items do
key :'$ref', :Host
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
@ -184,10 +210,6 @@ module HostApiDoc
key :description, 'Return specific host that is stored in the database.'
key :tags, [ 'host' ]
parameter :workspace
parameter :non_dead
parameter :address
parameter do
key :name, :id
key :in, :path
@ -200,12 +222,21 @@ module HostApiDoc
response 200 do
key :description, 'Returns host data.'
schema do
key :type, :array
items do
key :'$ref', :Host
property :data do
key :type, :array
items do
key :'$ref', :Host
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/hosts/:id PUT
@ -226,10 +257,18 @@ module HostApiDoc
end
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns host data.'
schema do
key :type, :object
key :'$ref', :Host
property :data do
key :'$ref', :Host
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -52,12 +52,21 @@ module LoginApiDoc
response 200 do
key :description, 'Returns login data.'
schema do
key :type, :array
items do
key :'$ref', :Login
property :data do
key :type, :array
items do
key :'$ref', :Login
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/logins POST
@ -86,8 +95,16 @@ module LoginApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Login
property :data do
key :'$ref', :Login
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -100,11 +117,13 @@ module LoginApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted logins.'
schema do
key :type, :array
items do
key :'$ref', :Login
property :data do
key :type, :array
items do
key :'$ref', :Login
end
end
end
end
@ -112,6 +131,40 @@ module LoginApiDoc
end
swagger_path '/api/v1/logins/{id}' do
# Swagger documentation for api/v1/logins/:id GET
operation :get do
key :description, 'Return specific login that is stored in the database.'
key :tags, [ 'login' ]
parameter do
key :name, :id
key :in, :path
key :description, 'ID of login to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
response 200 do
key :description, 'Returns login data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :Login
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/logins/:id PUT
operation :put do
key :description, 'Update the attributes an existing login.'
@ -132,8 +185,16 @@ module LoginApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Login
property :data do
key :'$ref', :Login
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -48,12 +48,21 @@ module LootApiDoc
response 200 do
key :description, 'Returns loot data.'
schema do
key :type, :array
items do
key :'$ref', :Loot
property :data do
key :type, :array
items do
key :'$ref', :Loot
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/loots POST
@ -82,8 +91,16 @@ module LootApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Loot
property :data do
key :'$ref', :Loot
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -96,49 +113,62 @@ module LootApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted loot.'
schema do
key :type, :array
items do
key :'$ref', :Loot
property :data do
key :type, :array
items do
key :'$ref', :Loot
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
swagger_path '/api/v1/loot/{id}' do
# Swagger documentation for api/v1/loot/:id GET
swagger_path '/api/v1/loots/{id}' do
# Swagger documentation for api/v1/loots/:id GET
operation :get do
key :description, 'Return specific loot entry that is stored in the database.'
key :tags, [ 'loot' ]
# TODO: Add this back in when this endpoint is implemented, tracked in MS-3233.
#
# operation :get do
# key :description, 'Return specific loot entry that is stored in the database.'
# key :tags, [ 'loot' ]
#
# parameter :workspace
#
# parameter do
# key :name, :id
# key :in, :path
# key :description, 'ID of loot to retrieve.'
# key :required, true
# key :type, :integer
# key :format, :int32
# end
#
# response 200 do
# key :description, 'Returns loot data.'
# schema do
# key :type, :array
# items do
# key :'$ref', :Loot
# end
# end
# end
# end
parameter do
key :name, :id
key :in, :path
key :description, 'ID of loot to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
# Swagger documentation for /api/v1/loot/{id} PUT
response 200 do
key :description, 'Returns loot data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :Loot
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/loots/{id} PUT
operation :put do
key :description, 'Update the attributes an existing loot.'
key :tags, [ 'loot' ]
@ -158,8 +188,16 @@ module LootApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Loot
property :data do
key :'$ref', :Loot
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -12,7 +12,16 @@ module MsfApiDoc
response 200 do
key :description, 'Returns the Metasploit Framework version.'
schema do
property :metasploit_version, type: :string
property :data do
property :metasploit_version, type: :string
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -28,6 +28,13 @@ module NmapApiDoc
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
end

View File

@ -40,12 +40,21 @@ module NoteApiDoc
response 200 do
key :description, 'Returns note data.'
schema do
key :type, :array
items do
key :'$ref', :Note
property :data do
key :type, :array
items do
key :'$ref', :Note
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/notes POST
@ -71,8 +80,16 @@ module NoteApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Note
property :data do
key :'$ref', :Note
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -85,14 +102,23 @@ module NoteApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted notes.'
schema do
key :type, :array
items do
key :'$ref', :Note
property :data do
key :type, :array
items do
key :'$ref', :Note
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
@ -102,8 +128,6 @@ module NoteApiDoc
key :description, 'Return specific note that is stored in the database.'
key :tags, [ 'note' ]
parameter :workspace
parameter do
key :name, :id
key :in, :path
@ -114,14 +138,23 @@ module NoteApiDoc
end
response 200 do
key :description, 'Returns notes data.'
key :description, 'Returns note data.'
schema do
key :type, :array
items do
key :'$ref', :Note
property :data do
key :type, :array
items do
key :'$ref', :Note
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/notes/:id PUT
@ -144,8 +177,16 @@ module NoteApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Note
property :data do
key :'$ref', :Note
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -10,6 +10,10 @@ module RootApiDoc
WORKSPACE_POST_DESC = 'The name of the workspace where this record should be created.'
WORKSPACE_POST_EXAMPLE = 'default'
HOST_EXAMPLE = '127.0.0.1'
CODE_DESC = 'The error code that was generated.'
CODE_EXAMPLE = 500
MESSAGE_DESC = 'A message describing the error that occurred.'
MESSAGE_EXAMPLE = 'Undefined method \'empty?\' for nil:NilClass'
swagger_root do
key :swagger, '2.0'
@ -107,4 +111,20 @@ module RootApiDoc
key :type, :string
end
end
swagger_schema :ErrorModel do
key :required, [:message]
property :error do
property :code do
key :type, :int32
key :description, CODE_DESC
key :example, CODE_EXAMPLE
end
property :message do
key :type, :string
key :description, MESSAGE_DESC
key :example, MESSAGE_EXAMPLE
end
end
end
end

View File

@ -41,12 +41,21 @@ module ServiceApiDoc
response 200 do
key :description, 'Returns service data.'
schema do
key :type, :array
items do
key :'$ref', :Service
property :data do
key :type, :array
items do
key :'$ref', :Service
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/services POST
@ -73,8 +82,16 @@ module ServiceApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Service
property :data do
key :'$ref', :Service
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -87,47 +104,61 @@ module ServiceApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted services.'
schema do
key :type, :array
items do
key :'$ref', :Service
property :data do
key :type, :array
items do
key :'$ref', :Service
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
swagger_path '/api/v1/services/{id}' do
# Swagger documentation for api/v1/services/:id GET
# TODO: Add this back in when this endpoint is implemented, tracked in MS-3233.
#
# operation :get do
# key :description, 'Return specific service that is stored in the database.'
# key :tags, [ 'service' ]
#
# parameter :workspace
#
# parameter do
# key :name, :id
# key :in, :path
# key :description, 'ID of service to retrieve.'
# key :required, true
# key :type, :integer
# key :format, :int32
# end
#
# response 200 do
# key :description, 'Returns service data.'
# schema do
# key :type, :array
# items do
# key :'$ref', :Service
# end
# end
# end
# end
operation :get do
key :description, 'Return specific service that is stored in the database.'
key :tags, [ 'service' ]
parameter do
key :name, :id
key :in, :path
key :description, 'ID of service to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
response 200 do
key :description, 'Returns service data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :Service
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/services/:id PUT
operation :put do
@ -149,8 +180,16 @@ module ServiceApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Service
property :data do
key :'$ref', :Service
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -32,12 +32,21 @@ module SessionApiDoc
response 200 do
key :description, 'Returns session data.'
schema do
key :type, :array
items do
key :'$ref', :Session
property :data do
key :type, :array
items do
key :'$ref', :Session
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/sessions POST
@ -68,4 +77,40 @@ module SessionApiDoc
# end
# end
end
swagger_path '/api/v1/sessions/{id}' do
# Swagger documentation for api/v1/sessions/:id GET
operation :get do
key :description, 'Return a specific session that is stored in the database.'
key :tags, [ 'session' ]
parameter do
key :name, :id
key :in, :path
key :description, 'ID of session to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
response 200 do
key :description, 'Returns session data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :Session
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
end

View File

@ -35,12 +35,21 @@ module SessionEventApiDoc
response 200 do
key :description, 'Returns session event data.'
schema do
key :type, :array
items do
key :'$ref', :SessionEvent
property :data do
key :type, :array
items do
key :'$ref', :SessionEvent
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/session events POST
@ -66,8 +75,52 @@ module SessionEventApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :SessionEvent
property :data do
key :'$ref', :SessionEvent
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
swagger_path '/api/v1/session-events/{id}' do
# Swagger documentation for api/v1/session-events/:id GET
operation :get do
key :description, 'Return a specific session_event that is stored in the database.'
key :tags, [ 'session_event' ]
parameter do
key :name, :id
key :in, :path
key :description, 'ID of session_event to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
response 200 do
key :description, 'Returns session event data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :SessionEvent
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -89,12 +89,21 @@ module VulnApiDoc
response 200 do
key :description, 'Returns vuln data.'
schema do
key :type, :array
items do
key :'$ref', :Vuln
property :data do
key :type, :array
items do
key :'$ref', :Vuln
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/vulns POST
@ -124,10 +133,18 @@ module VulnApiDoc
end
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns vuln data.'
schema do
key :type, :object
key :'$ref', :Vuln
property :data do
key :'$ref', :Vuln
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -140,14 +157,23 @@ module VulnApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted vulns.'
schema do
key :type, :array
items do
key :'$ref', :Vuln
property :data do
key :type, :array
items do
key :'$ref', :Vuln
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
@ -157,8 +183,6 @@ module VulnApiDoc
key :description, 'Return specific vuln that is stored in the database.'
key :tags, [ 'vuln' ]
parameter :workspace
parameter do
key :name, :id
key :in, :path
@ -171,12 +195,21 @@ module VulnApiDoc
response 200 do
key :description, 'Returns vuln data.'
schema do
key :type, :array
items do
key :'$ref', :Vuln
property :data do
key :type, :array
items do
key :'$ref', :Vuln
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/vulns/:id PUT
@ -197,10 +230,18 @@ module VulnApiDoc
end
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns vuln data.'
schema do
key :type, :object
key :'$ref', :Vuln
property :data do
key :'$ref', :Vuln
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -41,12 +41,21 @@ module VulnAttemptApiDoc
response 200 do
key :description, 'Returns vuln attempt data.'
schema do
key :type, :array
items do
key :'$ref', :VulnAttempt
property :data do
key :type, :array
items do
key :'$ref', :VulnAttempt
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/vuln-attempts POST
@ -74,8 +83,52 @@ module VulnAttemptApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :VulnAttempt
property :data do
key :'$ref', :VulnAttempt
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
swagger_path '/api/v1/vuln-attempts/{id}' do
# Swagger documentation for api/v1/vuln-attempts/:id GET
operation :get do
key :description, 'Return a specific vuln attempt that is stored in the database.'
key :tags, [ 'vuln_attempt' ]
parameter do
key :name, :id
key :in, :path
key :description, 'ID of vuln attempt to retrieve.'
key :required, true
key :type, :integer
key :format, :int32
end
response 200 do
key :description, 'Returns vuln attempt data.'
schema do
property :data do
key :type, :array
items do
key :'$ref', :VulnAttempt
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -34,12 +34,21 @@ module WorkspaceApiDoc
response 200 do
key :description, 'Returns workspace data.'
schema do
key :type, :array
items do
key :'$ref', :Workspace
property :data do
key :type, :array
items do
key :'$ref', :Workspace
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/workspaces POST
@ -60,8 +69,16 @@ module WorkspaceApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Workspace
property :data do
key :'$ref', :Workspace
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
@ -74,14 +91,23 @@ module WorkspaceApiDoc
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
key :description, 'Returns an array containing the successfully deleted workspaces.'
schema do
key :type, :array
items do
key :'$ref', :Workspace
property :data do
key :type, :array
items do
key :'$ref', :Workspace
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
end
@ -103,12 +129,21 @@ module WorkspaceApiDoc
response 200 do
key :description, 'Returns workspace data.'
schema do
key :type, :array
items do
key :'$ref', :Workspace
property :data do
key :type, :array
items do
key :'$ref', :Workspace
end
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end
# Swagger documentation for /api/v1/workspaces/:id PUT
@ -131,8 +166,16 @@ module WorkspaceApiDoc
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Workspace
property :data do
key :'$ref', :Workspace
end
end
end
response 500 do
key :description, 'An error occurred during the operation. See the message for more details.'
schema do
key :'$ref', :ErrorModel
end
end
end

View File

@ -151,6 +151,9 @@ class DataProxy
# @param [String] wspace A specific workspace name to add to the opts hash.
# @return [Hash] The opts hash with a valid :workspace value added.
def add_opts_workspace(opts, wspace = nil)
# If :id is present the user only wants a specific record, so workspace isn't needed
return if opts.key?(:id)
# Some methods use the key :wspace. Let's standardize on :workspace and clean it up here.
opts[:workspace] = opts.delete(:wspace) unless opts[:wspace].nil?

View File

@ -15,7 +15,7 @@ module CredentialDataProxy
opts[:workspace_id] = workspace.id
opts[:private_data] = opts.delete(:password)
opts[:private_type] = :password
old_core = data_service.creds(id: opts.delete(:core_id), workspace: workspace.name).first
old_core = data_service.creds(id: opts.delete(:core_id)).first
if old_core
opts[:originating_core_id] = old_core.id
opts[:origin_type] = :cracked_password

View File

@ -29,7 +29,7 @@ module HostDataProxy
def get_host(opts)
begin
data_service = self.get_data_service()
data_service = self.get_data_service
data_service.get_host(opts)
rescue => e
self.log_error(e, "Problem retrieving host")
@ -48,16 +48,6 @@ module HostDataProxy
end
end
def report_hosts(hosts)
begin
data_service = self.get_data_service
add_opts_workspace(hosts)
data_service.report_hosts(hosts)
rescue => e
self.log_error(e, "Problem reporting hosts")
end
end
def update_host(opts)
begin
data_service = self.get_data_service

View File

@ -204,6 +204,22 @@ class RemoteHTTPDataService
return false
end
# Select the correct path for GET request based on the options parameters provided.
# If 'id' is present, the user is requesting a single record and should use
# api/<version>/<resource>/ID path.
#
# @param [Hash] opts The parameters for the request
# @param [String] path The base resource path for the endpoint
#
# @return [String] The correct path for the request.
def get_path_select(opts, path)
if opts.key?(:id)
path = "#{path}/#{opts[:id]}"
opts.delete(:id)
end
path
end
#########
protected
#########

View File

@ -8,17 +8,15 @@ module RemoteCredentialDataService
CREDENTIAL_MDM_CLASS = 'Metasploit::Credential::Core'
def creds(opts = {})
data = self.get_data(CREDENTIAL_API_PATH, nil, opts)
path = get_path_select(opts, CREDENTIAL_API_PATH)
data = self.get_data(path, nil, opts)
rv = json_to_mdm_object(data, CREDENTIAL_MDM_CLASS, [])
parsed_body = JSON.parse(data.response.body)
parsed_body.each do |cred|
if cred['private']
private_object = to_ar(cred['private']['type'].constantize, cred['private'])
rv[parsed_body.index(cred)].private = private_object
end
parsed_body = JSON.parse(data.response.body).symbolize_keys
data = parsed_body[:data]
data.each do |cred|
if cred['origin']
origin_object = to_ar(cred['origin']['type'].constantize, cred['origin'])
rv[parsed_body.index(cred)].origin = origin_object
rv[data.index(cred)].origin = origin_object
end
end
rv

View File

@ -8,7 +8,8 @@ module RemoteHostDataService
HOST_MDM_CLASS = 'Mdm::Host'
def hosts(opts)
json_to_mdm_object(self.get_data(HOST_API_PATH, nil, opts), HOST_MDM_CLASS, [])
path = get_path_select(opts, HOST_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), HOST_MDM_CLASS, [])
end
def get_host(opts)
@ -19,10 +20,6 @@ module RemoteHostDataService
json_to_mdm_object(self.post_data(HOST_API_PATH, opts), HOST_MDM_CLASS, []).first
end
def report_hosts(hosts)
self.post_data(HOST_API_PATH, hosts)
end
def update_host(opts)
path = HOST_API_PATH
if opts && opts[:id]
@ -35,10 +32,4 @@ module RemoteHostDataService
def delete_host(opts)
json_to_mdm_object(self.delete_data(HOST_API_PATH, opts), HOST_MDM_CLASS, [])
end
# TODO: Remove? What is the purpose of this method?
def do_host_search(search)
response = self.post_data(HOST_SEARCH_PATH, search)
return response.body
end
end

View File

@ -8,7 +8,8 @@ module RemoteLoginDataService
LOGIN_MDM_CLASS = 'Metasploit::Credential::Login'
def logins(opts)
json_to_mdm_object(self.get_data(LOGIN_API_PATH, opts), LOGIN_MDM_CLASS, [])
path = get_path_select(opts, LOGIN_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), LOGIN_MDM_CLASS, [])
end
def create_credential_login(opts)

View File

@ -7,8 +7,9 @@ module RemoteLootDataService
LOOT_MDM_CLASS = 'Mdm::Loot'
def loot(opts = {})
path = get_path_select(opts, LOOT_API_PATH)
# TODO: Add an option to toggle whether the file data is returned or not
loots = json_to_mdm_object(self.get_data(LOOT_API_PATH, nil, opts), LOOT_MDM_CLASS, [])
loots = json_to_mdm_object(self.get_data(path, nil, opts), LOOT_MDM_CLASS, [])
# Save a local copy of the file
loots.each do |loot|
if loot.data
@ -23,10 +24,6 @@ module RemoteLootDataService
self.post_data_async(LOOT_API_PATH, opts)
end
def report_loots(loot)
self.post_data(LOOT_API_PATH, loot)
end
def update_loot(opts)
path = LOOT_API_PATH
if opts && opts[:id]

View File

@ -7,7 +7,8 @@ module RemoteNoteDataService
NOTE_MDM_CLASS = 'Mdm::Note'
def notes(opts)
json_to_mdm_object(self.get_data(NOTE_API_PATH, nil, opts), NOTE_MDM_CLASS, [])
path = get_path_select(opts, NOTE_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), NOTE_MDM_CLASS, [])
end
def report_note(opts)

View File

@ -3,7 +3,8 @@ module RemoteServiceDataService
SERVICE_MDM_CLASS = 'Mdm::Service'
def services(opts)
json_to_mdm_object(self.get_data(SERVICE_API_PATH, nil, opts), SERVICE_MDM_CLASS, [])
path = get_path_select(opts, SERVICE_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), SERVICE_MDM_CLASS, [])
end
def report_service(opts)

View File

@ -7,7 +7,8 @@ module RemoteSessionDataService
SESSION_MDM_CLASS = 'Mdm::Session'
def sessions(opts)
json_to_mdm_object(self.get_data(SESSION_API_PATH, nil, opts), SESSION_MDM_CLASS, [])
path = get_path_select(opts, SESSION_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), SESSION_MDM_CLASS, [])
end
def report_session(opts)
@ -41,14 +42,6 @@ module RemoteSessionDataService
return hash
end
def parse_host_opts(msf_session)
hash = Hash.new()
hash[:host] = msf_session.session_host
hash[:arch] = msf_session.arch if msf_session.respond_to?(:arch) and msf_session.arch
hash[:workspace] = msf_session[:workspace] || msf_session.workspace
return hash
end
def parse_session_data(msf_session)
hash = Hash.new()
# TODO: what to do with this shiz

View File

@ -7,7 +7,8 @@ module RemoteSessionEventDataService
SESSION_EVENT_MDM_CLASS = 'Mdm::SessionEvent'
def session_events(opts = {})
json_to_mdm_object(self.get_data(SESSION_EVENT_API_PATH, opts), SESSION_EVENT_MDM_CLASS, [])
path = get_path_select(opts, SESSION_EVENT_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), SESSION_EVENT_MDM_CLASS, [])
end
def report_session_event(opts)

View File

@ -7,7 +7,8 @@ module RemoteVulnAttemptDataService
VULN_ATTEMPT_MDM_CLASS = 'Mdm::VulnAttempt'
def vuln_attempts(opts)
json_to_mdm_object(self.get_data(VULN_ATTEMPT_API_PATH, nil, opts), VULN_ATTEMPT_MDM_CLASS, [])
path = get_path_select(opts, VULN_ATTEMPT_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), VULN_ATTEMPT_MDM_CLASS, [])
end
def report_vuln_attempt(vuln, opts)

View File

@ -7,7 +7,8 @@ module RemoteVulnDataService
VULN_MDM_CLASS = 'Mdm::Vuln'
def vulns(opts)
json_to_mdm_object(self.get_data(VULN_API_PATH, nil, opts), VULN_MDM_CLASS, [])
path = get_path_select(opts, VULN_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), VULN_MDM_CLASS, [])
end
def report_vuln(opts)

View File

@ -30,7 +30,8 @@ module RemoteWorkspaceDataService
end
def workspaces(opts)
json_to_mdm_object(self.get_data(WORKSPACE_API_PATH, nil, opts), WORKSPACE_MDM_CLASS, [])
path = get_path_select(opts, WORKSPACE_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), WORKSPACE_MDM_CLASS, [])
end
def delete_workspaces(opts)

View File

@ -26,8 +26,9 @@ module ResponseDataHelper
def json_to_hash(response_wrapper)
begin
body = process_response(response_wrapper)
unless body.nil? || body.empty?
return JSON.parse(body).symbolize_keys
if !body.nil? && !body.empty?
parsed_body = JSON.parse(body, symbolize_names: true)
return parsed_body[:data]
end
rescue => e
elog "Error parsing response as JSON: #{e.message}"
@ -47,17 +48,18 @@ module ResponseDataHelper
if response_wrapper.expected
begin
body = process_response(response_wrapper)
unless body.nil? || body.empty?
parsed_body = Array.wrap(JSON.parse(body))
if !body.nil? && !body.empty?
parsed_body = JSON.parse(body).symbolize_keys
data = Array.wrap(parsed_body[:data])
rv = []
parsed_body.each do |json_object|
data.each do |json_object|
rv << to_ar(mdm_class.constantize, json_object)
end
return rv
end
rescue => e
elog "Mdm Object conversion failed #{e.message}"
e.backtrace.each { |line| elog "#{line}\n" }
e.backtrace.each { |line| elog "#{line}" }
end
end

View File

@ -3,12 +3,13 @@ module Msf::DBManager::Cred
def creds(opts)
query = nil
::ActiveRecord::Base.connection_pool.with_connection {
# If :id exists we're looking for a specific record, skip the other stuff
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Metasploit::Credential::Core.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
search_term = opts.delete(:search_term)
# If :id exists we're looking for a specific record, skip the other stuff
if opts[:id].present?
return Metasploit::Credential::Core.where(id: opts[:id])
end
query = Metasploit::Credential::Core.where( workspace_id: wspace.id )
query = query.includes(:private, :public, :logins, :realm).references(:private, :public, :logins, :realm)

View File

@ -1,6 +1,11 @@
module Msf::DBManager::Event
def events(wspace=workspace)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Event.find(opts[:id]))
end
wspace.events.find :all, :order => 'created_at ASC'
}
end

View File

@ -128,12 +128,16 @@ module Msf::DBManager::Host
# Returns a list of all hosts in the database
def hosts(opts)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Host.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
conditions = {}
conditions[:state] = [Msf::HostState::Alive, Msf::HostState::Unknown] if opts[:non_dead]
conditions[:address] = opts[:address] if opts[:address] && !opts[:address].empty?
conditions[:id] = opts[:id] if opts[:id] && !opts[:id].empty?
if opts[:search_term] && !opts[:search_term].empty?
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Host, opts[:search_term])

View File

@ -9,7 +9,7 @@ module CredentialServlet
end
def self.registered(app)
app.get CredentialServlet.api_path, &get_credentials
app.get CredentialServlet.api_path_with_id, &get_credentials
app.post CredentialServlet.api_path, &create_credential
app.put CredentialServlet.api_path_with_id, &update_credential
app.delete CredentialServlet.api_path, &delete_credentials
@ -23,15 +23,21 @@ module CredentialServlet
lambda {
warden.authenticate!
begin
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.creds(sanitized_params)
includes = [:logins, :public, :private, :realm]
# Need to append the human attribute into the private sub-object before converting to json
# This is normally pulled from a class method from the MetasploitCredential class
response = []
data.each do |cred|
json = cred.as_json(include: includes).merge(private_class: cred.private.class.to_s)
response << json
end
data = data.first if is_single_object?(data, sanitized_params)
response = format_cred_json(data)
set_json_response(response)
set_json_data_response(response: response)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving credentials:', code: 500)
end
}
end
@ -56,9 +62,9 @@ module CredentialServlet
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_credential(opts)
response = format_cred_json(data)
set_json_response(response.first)
set_json_data_response(response: response.first)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the credential:', code: 500)
end
}
end
@ -68,9 +74,9 @@ module CredentialServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_credentials(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the credential:', code: 500)
end
}
end

View File

@ -24,9 +24,9 @@ module DbExportServlet
encoded_file = Base64.urlsafe_encode64(File.read(File.expand_path(output_file)))
response = {}
response[:db_export_file] = encoded_file
set_json_response(response)
set_json_data_response(response: response)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error exporting the database:', code: 500)
ensure
# Ensure the temporary file gets cleaned up
File.delete(opts[:path])

View File

@ -14,9 +14,13 @@ module EventServlet
def self.report_event
lambda {
warden.authenticate!
job = lambda { |opts| get_db().report_event(opts) }
exec_report_job(request, &job)
begin
warden.authenticate!
job = lambda { |opts| get_db.report_event(opts) }
exec_report_job(request, &job)
rescue => e
print_error_and_create_response(error: e, message: 'There was an error creating the event:', code: 500)
end
}
end
end

View File

@ -18,13 +18,13 @@ module ExploitServlet
job = lambda { |opts|
case opts[:exploit_report_type]
when "attempt"
get_db().report_exploit_attempt(opts[:host], opts)
get_db.report_exploit_attempt(opts[:host], opts)
when "failure"
get_db().report_exploit_failure(opts)
get_db.report_exploit_failure(opts)
when "success"
get_db().report_exploit_success(opts)
get_db.report_exploit_success(opts)
end
get_db().report_host(opts)
get_db.report_host(opts)
}
exec_report_job(request, &job)
}

View File

@ -28,13 +28,13 @@ module HostServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.hosts(sanitized_params)
includes = [:loots]
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error getting hosts:', code: 500)
end
}
end
@ -44,11 +44,11 @@ module HostServlet
warden.authenticate!
begin
job = lambda { |opts|
data = get_db.report_host(opts)
get_db.report_host(opts)
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error creating the host:', code: 500)
end
}
end
@ -61,9 +61,9 @@ module HostServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_host(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the host:', code: 500)
end
}
end
@ -74,9 +74,9 @@ module HostServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_host(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting hosts:', code: 500)
end
}
end
@ -87,10 +87,10 @@ module HostServlet
warden.authenticate!
begin
opts = parse_json_request(request, false)
data = get_db().get_host(opts)
set_json_response(data)
data = get_db.get_host(opts)
set_json_data_response(response: data)
rescue Exception => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error searching for hosts:', code: 500)
end
}
end

View File

@ -22,11 +22,12 @@ module LoginServlet
def self.get_logins
lambda {
begin
sanitized_params = sanitize_params(params)
response = get_db.logins(sanitized_params)
set_json_response(response)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.logins(sanitized_params)
data = data.first if is_single_object?(data, sanitized_params)
set_json_response(data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving logins:', code: 500)
end
}
end
@ -40,7 +41,7 @@ module LoginServlet
response = get_db.create_credential_login(opts)
set_json_response(response)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error creating the login:', code: 500)
end
}
end
@ -54,7 +55,7 @@ module LoginServlet
data = get_db.update_login(opts)
set_json_response(data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the login:', code: 500)
end
}
end
@ -66,7 +67,7 @@ module LoginServlet
data = get_db.delete_logins(opts)
set_json_response(data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the logins:', code: 500)
end
}
end

View File

@ -9,7 +9,7 @@ module LootServlet
end
def self.registered(app)
app.get LootServlet.api_path, &get_loot
app.get LootServlet.api_path_with_id, &get_loot
app.post LootServlet.api_path, &report_loot
app.put LootServlet.api_path_with_id, &update_loot
app.delete LootServlet.api_path, &delete_loot
@ -23,16 +23,16 @@ module LootServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.loots(sanitized_params)
includes = [:host]
data.each do |loot|
loot.data = Base64.urlsafe_encode64(loot.data) if loot.data
end
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving the loot:', code: 500)
end
}
end
@ -62,9 +62,9 @@ module LootServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_loot(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the loot:', code: 500)
end
}
end
@ -75,9 +75,9 @@ module LootServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_loot(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the loot:', code: 500)
end
}
end

View File

@ -18,8 +18,12 @@ module MsfServlet
def self.get_msf_version
lambda {
warden.authenticate!
set_json_response({metasploit_version: Metasploit::Framework::VERSION})
begin
warden.authenticate!
set_json_data_response(response: { metasploit_version: Metasploit::Framework::VERSION })
rescue => e
print_error_and_create_response(error: e, message: 'There was an error retrieving the version:', code: 500)
end
}
end

View File

@ -20,7 +20,7 @@ module NmapServlet
nmap_file = File.basename(opts[:filename])
nmap_file_path = File.join(Msf::Config.local_directory, nmap_file)
opts[:filename] = process_file(opts[:data], nmap_file_path)
get_db().import_nmap_xml_file(opts)
get_db.import_nmap_xml_file(opts)
}
exec_report_job(request, &job)
}

View File

@ -23,13 +23,13 @@ module NoteServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.notes(sanitized_params)
includes = [:host]
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving notes:', code: 500)
end
}
end
@ -37,14 +37,10 @@ module NoteServlet
def self.report_note
lambda {
warden.authenticate!
begin
job = lambda { |opts|
get_db.report_note(opts)
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
end
job = lambda { |opts|
get_db.report_note(opts)
}
exec_report_job(request, &job)
}
end
@ -56,9 +52,9 @@ module NoteServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_note(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the note:', code: 500)
end
}
end
@ -69,9 +65,9 @@ module NoteServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_note(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the note:', code: 500)
end
}
end

View File

@ -9,7 +9,7 @@ module ServiceServlet
end
def self.registered(app)
app.get ServiceServlet.api_path, &get_services
app.get ServiceServlet.api_path_with_id, &get_services
app.post ServiceServlet.api_path, &report_service
app.put ServiceServlet.api_path_with_id, &update_service
app.delete ServiceServlet.api_path, &delete_service
@ -23,12 +23,13 @@ module ServiceServlet
lambda {
warden.authenticate!
begin
opts = sanitize_params(params)
data = get_db.services(opts)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.services(sanitized_params)
includes = [:host]
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving services:', code: 500)
end
}
end
@ -50,9 +51,9 @@ module ServiceServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_service(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the service:', code: 500)
end
}
end
@ -63,9 +64,9 @@ module ServiceServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_service(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the service:', code: 500)
end
}
end

View File

@ -4,8 +4,12 @@ module SessionEventServlet
'/api/v1/session-events'
end
def self.api_path_with_id
"#{SessionEventServlet.api_path}/?:id?"
end
def self.registered(app)
app.get SessionEventServlet.api_path, &get_session_event
app.get SessionEventServlet.api_path_with_id, &get_session_event
app.post SessionEventServlet.api_path, &report_session_event
end
@ -17,11 +21,12 @@ module SessionEventServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
data = get_db.session_events(opts)
set_json_response(data)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.session_events(sanitized_params)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving session events:', code: 500)
end
}
end
@ -29,14 +34,10 @@ module SessionEventServlet
def self.report_session_event
lambda {
warden.authenticate!
begin
job = lambda { |opts|
get_db.report_session_event(opts)
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
end
job = lambda { |opts|
get_db.report_session_event(opts)
}
exec_report_job(request, &job)
}
end
end

View File

@ -21,13 +21,13 @@ module SessionServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.sessions(sanitized_params)
includes = [:host]
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving sessions:', code: 500)
end
}
end
@ -45,7 +45,7 @@ module SessionServlet
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error creating the session:', code: 500)
end
}
end

View File

@ -23,12 +23,12 @@ module UserServlet
lambda {
warden.authenticate!(scope: :admin_api)
begin
opts = parse_json_request(request, false)
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.users(sanitized_params)
set_json_response(data)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving users:', code: 500)
end
}
end
@ -36,14 +36,10 @@ module UserServlet
def self.report_user
lambda {
warden.authenticate!(scope: :admin_api)
begin
job = lambda { |opts|
get_db.report_user(opts)
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
end
job = lambda { |opts|
get_db.report_user(opts)
}
exec_report_job(request, &job)
}
end
@ -55,9 +51,11 @@ module UserServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_user(opts)
set_json_response(data)
# Only return the single object if the id parameter is present
data = data.first if !sanitized_params[:id].nil? && data.count == 1
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error creating the user:', code: 500)
end
}
end
@ -68,9 +66,9 @@ module UserServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_user(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the users:', code: 500)
end
}
end

View File

@ -21,11 +21,12 @@ module VulnAttemptServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
data = get_db.vuln_attempts(params.symbolize_keys)
set_json_response(data)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.vuln_attempts(sanitized_params)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving vuln attempts:', code: 500)
end
}
end
@ -33,17 +34,13 @@ module VulnAttemptServlet
def self.report_vuln_attempt
lambda {
warden.authenticate!
begin
job = lambda { |opts|
vuln_id = opts.delete(:vuln_id)
wspace = opts.delete(:workspace)
vuln = get_db.vulns(id: vuln_id, workspace: wspace).first
get_db.report_vuln_attempt(vuln, opts)
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
end
job = lambda { |opts|
vuln_id = opts.delete(:vuln_id)
wspace = opts.delete(:workspace)
vuln = get_db.vulns(id: vuln_id).first
get_db.report_vuln_attempt(vuln, opts)
}
exec_report_job(request, &job)
}
end
end

View File

@ -23,13 +23,13 @@ module VulnServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.vulns(sanitized_params)
includes = [:host, :vulns_refs, :refs, :module_refs]
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving vulns:', code: 500)
end
}
end
@ -37,14 +37,10 @@ module VulnServlet
def self.report_vuln
lambda {
warden.authenticate!
begin
job = lambda { |opts|
get_db.report_vuln(opts)
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
end
job = lambda { |opts|
get_db.report_vuln(opts)
}
exec_report_job(request, &job)
}
end
@ -56,9 +52,9 @@ module VulnServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_vuln(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the vuln:', code: 500)
end
}
end
@ -69,9 +65,9 @@ module VulnServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_vuln(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the vulns:', code: 500)
end
}
end

View File

@ -23,15 +23,14 @@ module WorkspaceServlet
lambda {
warden.authenticate!
begin
opts = parse_json_request(request, false)
includes = nil
sanitized_params = sanitize_params(params)
sanitized_params = sanitize_params(params, env['rack.request.query_hash'])
data = get_db.workspaces(sanitized_params)
set_json_response(data, includes)
data = data.first if is_single_object?(data, sanitized_params)
set_json_data_response(response: data, includes: includes)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error retrieving workspaces:', code: 500)
end
}
end
@ -41,10 +40,10 @@ module WorkspaceServlet
warden.authenticate!
begin
opts = parse_json_request(request, true)
workspace = get_db.add_workspace(opts)
set_json_response(workspace)
data = get_db.add_workspace(opts)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error creating the workspace:', code: 500)
end
}
end
@ -57,9 +56,9 @@ module WorkspaceServlet
tmp_params = sanitize_params(params)
opts[:id] = tmp_params[:id] if tmp_params[:id]
data = get_db.update_workspace(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error updating the workspace:', code: 500)
end
}
end
@ -70,9 +69,9 @@ module WorkspaceServlet
begin
opts = parse_json_request(request, false)
data = get_db.delete_workspaces(opts)
set_json_response(data)
set_json_data_response(response: data)
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error deleting the workspaces:', code: 500)
end
}
end

View File

@ -13,22 +13,22 @@ module ServletHelper
end
def set_empty_response
[200, '']
set_json_data_response(response: '')
end
def set_json_response(data, includes = nil, code = 200)
headers = {'Content-Type' => 'application/json'}
headers = { 'Content-Type' => 'application/json' }
[code, headers, to_json(data, includes)]
end
def set_json_data_response(response:, includes: nil, code: 200)
data_response = {"data": response}
data_response = { data: response }
set_json_response(data_response, includes = includes, code = code)
end
def set_json_error_response(response:, includes: nil, code:)
error_response = {"error": response}
set_json_response(error_response, includes = includes, code = code)
def set_json_error_response(response:, code:)
error_response = { error: response }
set_json_response(error_response, nil, code = code)
end
def set_html_response(data)
@ -47,6 +47,15 @@ module ServletHelper
hash.deep_symbolize_keys
end
def print_error_and_create_response(error: , message:, code:)
print_error "Error handling request: #{error.message}.", error
error_response = {
code: code,
message: "#{message} #{error.message}"
}
set_json_error_response(response: error_response, code: code)
end
def exec_report_job(request, includes = nil, &job)
begin
@ -59,11 +68,11 @@ module ServletHelper
return set_empty_response
else
data = job.call(opts)
return set_json_response(data, includes)
return set_json_data_response(response: data, includes: includes)
end
rescue => e
set_error_on_response(e)
print_error_and_create_response(error: e, message: 'There was an error creating the record:', code: 500)
end
end
@ -73,13 +82,33 @@ module ServletHelper
# Sinatra injects extra parameters for some reason: https://github.com/sinatra/sinatra/issues/453
# This method cleans those up so we don't have any unexpected values before passing on.
# It also inspects the query string for any invalid parameters.
#
# @param [Hash] params Hash containing the parameters for the request.
# @param [Hash] query_hash The query_hash variable from the rack request.
# @return [Hash] Returns params with symbolized keys and the injected parameters removed.
def sanitize_params(params)
def sanitize_params(params, query_hash = {})
# Reject id passed as a query parameter for GET requests.
# API standards say path ID should be used for single records.
if query_hash.key?('id')
raise ArgumentError, ("'id' is not a valid query parameter. Please use /api/v1/<resource>/{ID} instead.")
end
params.symbolize_keys.except(:captures, :splat)
end
# Determines if this data set should be output as a single object instead of an array.
#
# @param [Array] data Array containing the data to be returned to the user.
# @param [Hash] params The parameters included in the request.
#
# @return [Bool] true if the data should be printed as a single object, false otherwise
def is_single_object?(data, params)
# Check to see if the ID parameter was present. If so, print as a single object.
# Note that ID is not valid as a query parameter, so we assume that the user
# used <resource>/{ID} notation if ID is present in params.
!params[:id].nil? && data.count == 1
end
def format_cred_json(data)
includes = [:logins, :public, :private, :realm, :origin]

View File

@ -17,6 +17,11 @@ module Msf::DBManager::Loot
search_term = opts.delete(:search_term)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Loot.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
opts[:workspace_id] = wspace.id

View File

@ -23,6 +23,11 @@ module Msf::DBManager::Note
#
def notes(opts)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Note.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
data = opts.delete(:data)

View File

@ -143,14 +143,19 @@ module Msf::DBManager::Service
# Returns a list of all services in the database
def services(opts)
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
search_term = opts.delete(:search_term)
order_args = [:port]
order_args.unshift(Mdm::Host.arel_table[:address]) if opts.key?(:hosts)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Service.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
if search_term && !search_term.empty?
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Service, search_term)
wspace.services.includes(:host).where(opts).where(column_search_conditions).order(*order_args)

View File

@ -8,6 +8,11 @@ module Msf::DBManager::Session
return if not active
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Session.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
search_term = opts.delete(:search_term)

View File

@ -2,6 +2,10 @@ module Msf::DBManager::SessionEvent
def session_events(opts)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::SessionEvent.find(opts[:id]))
end
conditions = {}
Mdm::SessionEvent.all

View File

@ -236,6 +236,11 @@ module Msf::DBManager::Vuln
#
def vulns(opts)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Vuln.find(opts[:id]))
end
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
search_term = opts.delete(:search_term)

View File

@ -23,6 +23,11 @@ module Msf::DBManager::VulnAttempt
#
def vuln_attempts(opts)
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::VulnAttempt.find(opts[:id]))
end
# 'workspace' is not a valid attribute for Mdm::VulnAttempt. Remove it.
Msf::Util::DBManager.delete_opts_workspace(opts)

View File

@ -47,6 +47,11 @@ module Msf::DBManager::Workspace
def workspaces(opts = {})
::ActiveRecord::Base.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Workspace.find(opts[:id]))
end
search_term = opts.delete(:search_term)
# Passing these values to the search will cause exceptions, so remove them if they accidentally got passed in.
Msf::Util::DBManager.delete_opts_workspace(opts)

View File

@ -412,10 +412,10 @@ class Creds
origin = ''
if core.origin.kind_of?(Metasploit::Credential::Origin::Service)
service = framework.db.services(id: core.origin.service_id, workspace: framework.db.workspace).first
service = framework.db.services(id: core.origin.service_id).first
origin = service.host.address
elsif core.origin.kind_of?(Metasploit::Credential::Origin::Session)
session = framework.db.sessions(id: core.origin.session_id, workspace: framework.db.workspace).first
session = framework.db.sessions(id: core.origin.session_id).first
origin = session.host.address
end
@ -443,8 +443,7 @@ class Creds
]
else
core.logins.each do |login|
service = framework.db.services(id: login.service_id, workspace: framework.db.workspace).first
service = framework.db.services(id: login.service_id).first
# If none of this Core's associated Logins is for a host within
# the user-supplied RangeWalker, then we don't have any reason to
# print it out. However, we treat the absence of ranges as meaning