Class: Msf::RPC::Service
- Inherits:
-
Object
- Object
- Msf::RPC::Service
- Defined in:
- lib/msf/core/rpc/v10/service.rb
Instance Attribute Summary collapse
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#default_handler ⇒ Object
Returns the value of attribute default_handler.
-
#dispatcher_timeout ⇒ Object
Returns the value of attribute dispatcher_timeout.
-
#framework ⇒ Object
Returns the value of attribute framework.
-
#handlers ⇒ Object
Returns the value of attribute handlers.
-
#job_status_tracker ⇒ Object
Returns the value of attribute job_status_tracker.
-
#options ⇒ Object
Returns the value of attribute options.
-
#service ⇒ Object
Returns the value of attribute service.
-
#srvhost ⇒ Object
Returns the value of attribute srvhost.
-
#srvport ⇒ Object
Returns the value of attribute srvport.
-
#str_encoding ⇒ Object
Returns the value of attribute str_encoding.
-
#token_timeout ⇒ Object
Returns the value of attribute token_timeout.
-
#tokens ⇒ Object
Returns the value of attribute tokens.
-
#uri ⇒ Object
Returns the value of attribute uri.
-
#users ⇒ Object
Returns the value of attribute users.
Instance Method Summary collapse
- #add_handler(group, handler) ⇒ Object
- #add_token(token) ⇒ Object
- #add_user(user, pass) ⇒ Object
- #authenticate(token) ⇒ Object
-
#initialize(framework, options = {}) ⇒ Service
constructor
A new instance of Service.
- #on_request_uri(cli, req) ⇒ Object
- #process(req) ⇒ Object
- #process_exception(e) ⇒ Object
- #remove_token ⇒ Object
- #remove_user(user) ⇒ Object
- #start ⇒ Object
- #stop ⇒ Object
- #wait ⇒ Object
Constructor Details
#initialize(framework, options = {}) ⇒ Service
Returns a new instance of Service.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/msf/core/rpc/v10/service.rb', line 16 def initialize(framework, ={}) self.framework = framework self.handlers = {} self. = { :ssl => true, :cert => nil, :uri => "/uri", :host => '127.0.0.1', :port => 3790 }.merge() self.str_encoding = ''.encoding.name self.srvhost = self.[:host] self.srvport = self.[:port] self.uri = self.[:uri] self.debug = self.[:debug] self.dispatcher_timeout = self.[:dispatcher_timeout] || 7200 self.token_timeout = self.[:token_timeout] || 300 self.tokens = self.[:tokens] || {} self.users = self.[:users] || [] self.job_status_tracker = Msf::RPC::RpcJobStatusTracker.new add_handler("health", Msf::RPC::RPC_Health.new(self)) add_handler("core", Msf::RPC::RPC_Core.new(self)) add_handler("auth", Msf::RPC::RPC_Auth.new(self)) add_handler("console", Msf::RPC::RPC_Console.new(self)) add_handler("module", Msf::RPC::RPC_Module.new(self)) add_handler("session", Msf::RPC::RPC_Session.new(self)) add_handler("plugin", Msf::RPC::RPC_Plugin.new(self)) add_handler("job", Msf::RPC::RPC_Job.new(self)) add_handler("db", Msf::RPC::RPC_Db.new(self)) end |
Instance Attribute Details
#debug ⇒ Object
Returns the value of attribute debug.
13 14 15 |
# File 'lib/msf/core/rpc/v10/service.rb', line 13 def debug @debug end |
#default_handler ⇒ Object
Returns the value of attribute default_handler.
12 13 14 |
# File 'lib/msf/core/rpc/v10/service.rb', line 12 def default_handler @default_handler end |
#dispatcher_timeout ⇒ Object
Returns the value of attribute dispatcher_timeout.
13 14 15 |
# File 'lib/msf/core/rpc/v10/service.rb', line 13 def dispatcher_timeout @dispatcher_timeout end |
#framework ⇒ Object
Returns the value of attribute framework.
12 13 14 |
# File 'lib/msf/core/rpc/v10/service.rb', line 12 def framework @framework end |
#handlers ⇒ Object
Returns the value of attribute handlers.
12 13 14 |
# File 'lib/msf/core/rpc/v10/service.rb', line 12 def handlers @handlers end |
#job_status_tracker ⇒ Object
Returns the value of attribute job_status_tracker.
14 15 16 |
# File 'lib/msf/core/rpc/v10/service.rb', line 14 def job_status_tracker @job_status_tracker end |
#options ⇒ Object
Returns the value of attribute options.
11 12 13 |
# File 'lib/msf/core/rpc/v10/service.rb', line 11 def @options end |
#service ⇒ Object
Returns the value of attribute service.
11 12 13 |
# File 'lib/msf/core/rpc/v10/service.rb', line 11 def service @service end |
#srvhost ⇒ Object
Returns the value of attribute srvhost.
11 12 13 |
# File 'lib/msf/core/rpc/v10/service.rb', line 11 def srvhost @srvhost end |
#srvport ⇒ Object
Returns the value of attribute srvport.
11 12 13 |
# File 'lib/msf/core/rpc/v10/service.rb', line 11 def srvport @srvport end |
#str_encoding ⇒ Object
Returns the value of attribute str_encoding.
13 14 15 |
# File 'lib/msf/core/rpc/v10/service.rb', line 13 def str_encoding @str_encoding end |
#token_timeout ⇒ Object
Returns the value of attribute token_timeout.
13 14 15 |
# File 'lib/msf/core/rpc/v10/service.rb', line 13 def token_timeout @token_timeout end |
#tokens ⇒ Object
Returns the value of attribute tokens.
12 13 14 |
# File 'lib/msf/core/rpc/v10/service.rb', line 12 def tokens @tokens end |
#uri ⇒ Object
Returns the value of attribute uri.
11 12 13 |
# File 'lib/msf/core/rpc/v10/service.rb', line 11 def uri @uri end |
#users ⇒ Object
Returns the value of attribute users.
12 13 14 |
# File 'lib/msf/core/rpc/v10/service.rb', line 12 def users @users end |
Instance Method Details
#add_handler(group, handler) ⇒ Object
90 91 92 |
# File 'lib/msf/core/rpc/v10/service.rb', line 90 def add_handler(group, handler) self.handlers[group] = handler end |
#add_token(token) ⇒ Object
176 177 178 |
# File 'lib/msf/core/rpc/v10/service.rb', line 176 def add_token(token) self.tokens[token] = [nil, nil, nil, true] end |
#add_user(user, pass) ⇒ Object
184 185 186 187 188 189 190 191 192 |
# File 'lib/msf/core/rpc/v10/service.rb', line 184 def add_user(user, pass) self.users.each do |r| if r[0] == user r[1] = pass return end end self.users << [user, pass] end |
#authenticate(token) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/msf/core/rpc/v10/service.rb', line 198 def authenticate(token) stale = [] unless (token && token.kind_of?(::String)) return false end # Force the encoding to ASCII-8BIT token = token.unpack("C*").pack("C*") self.tokens.each_key do |t| user,ctime,mtime,perm = self.tokens[t] if !perm && mtime + self.token_timeout < Time.now.to_i stale << t end end stale.each { |t| self.tokens.delete(t) } unless self.tokens[token] begin if framework.db.active && ::Mdm::ApiKey.find_by_token(token) return true end rescue ::Exception => e end return false end self.tokens[token][2] = Time.now.to_i true end |
#on_request_uri(cli, req) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/msf/core/rpc/v10/service.rb', line 76 def on_request_uri(cli, req) res = Rex::Proto::Http::Response.new() res["Content-Type"] = "binary/message-pack" begin res.body = process(req).to_msgpack rescue Msf::RPC::Exception => e elog('RPC Exception', error: e) res.body = process_exception(e).to_msgpack res.code = e.code end cli.send_response(res) end |
#process(req) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/msf/core/rpc/v10/service.rb', line 94 def process(req) msg = nil begin if req.method != "POST" if req && req.method raise ArgumentError, "Invalid Request Verb: '#{req.method.inspect}'" else raise ArgumentError, "Invalid Request: '#{req.inspect}'" end end unless (req.headers["Content-Type"] && req.headers["Content-Type"] == "binary/message-pack") raise ArgumentError, "Invalid Content Type" end msg = MessagePack.unpack(req.body) unless (msg && msg.kind_of?(::Array) && msg.length > 0) raise ArgumentError, "Invalid Message Format" end msg.map { |a| a.respond_to?(:force_encoding) ? a.force_encoding(self.str_encoding) : a } group, funct = msg.shift.split(".", 2) unless self.handlers[group] raise ArgumentError, "Unknown API Group: '#{group.inspect}'" end doauth = true mname = 'rpc_' + funct if self.handlers[group].respond_to?(mname + '_noauth') doauth = false mname << '_noauth' end unless self.handlers[group].respond_to?(mname) raise ArgumentError, "Unknown API Call: '#{mname.inspect}'" end if doauth token = msg.shift unless authenticate(token) raise ::Msf::RPC::Exception.new(401, "Invalid Authentication Token") end end ::Timeout.timeout(self.dispatcher_timeout) do Thread.current[:rpc_token] = token self.handlers[group].send(mname, *msg) end rescue ::Exception => e elog('RPC Exception', error: e) process_exception(e) ensure Thread.current[:rpc_token] = nil end end |
#process_exception(e) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/msf/core/rpc/v10/service.rb', line 156 def process_exception(e) r = { :error => true, :error_class => e.class.to_s, :error_string => e.to_s, :error_backtrace => e.backtrace.map{|x| x.sub(/^.*lib\//, 'lib/') } # Dont expose the install path } if e.respond_to?(:message) r[:error_message] = e. end if e.respond_to?(:code) r[:error_code] = e.code end r end |
#remove_token ⇒ Object
180 181 182 |
# File 'lib/msf/core/rpc/v10/service.rb', line 180 def remove_token self.tokens.delete(token) end |
#remove_user(user) ⇒ Object
194 195 196 |
# File 'lib/msf/core/rpc/v10/service.rb', line 194 def remove_user(user) self.users = self.users.select{|r| r[0] != user } end |
#start ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/msf/core/rpc/v10/service.rb', line 50 def start self.service = Rex::ServiceManager.start( Rex::Proto::Http::Server, self.srvport, self.srvhost, self.[:ssl], self.[:context], self.[:comm], self.[:cert] ) self.service.add_resource(self.uri, { 'Proc' => Proc.new { |cli, req| on_request_uri(cli, req) }, 'Path' => self.uri }) end |
#stop ⇒ Object
67 68 69 70 |
# File 'lib/msf/core/rpc/v10/service.rb', line 67 def stop self.service.stop self.service.deref end |
#wait ⇒ Object
72 73 74 |
# File 'lib/msf/core/rpc/v10/service.rb', line 72 def wait self.service.wait end |