Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

session.rb 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. # -*- coding: binary -*-
  2. require 'msf/core'
  3. module Msf
  4. ###
  5. #
  6. # Event notifications that affect sessions.
  7. #
  8. ###
  9. module SessionEvent
  10. #
  11. # Called when a session is opened.
  12. #
  13. def on_session_open(session)
  14. end
  15. #
  16. # Called when a session is closed.
  17. #
  18. def on_session_close(session, reason='')
  19. end
  20. #
  21. # Called when the user interacts with a session.
  22. #
  23. def on_session_interact(session)
  24. end
  25. #
  26. # Called when the user writes data to a session.
  27. #
  28. def on_session_command(session, command)
  29. end
  30. #
  31. # Called when output comes back from a user command.
  32. #
  33. def on_session_output(session, output)
  34. end
  35. #
  36. # Called when a file is uploaded.
  37. #
  38. def on_session_upload(session, local_path, remote_path)
  39. end
  40. #
  41. # Called when a file is downloaded.
  42. #
  43. def on_session_download(session, remote_path, local_path)
  44. end
  45. #
  46. # Called when a file is deleted.
  47. #
  48. def on_session_filedelete(session, path)
  49. end
  50. end
  51. ###
  52. #
  53. # The session class represents a post-exploitation, uh, session.
  54. # Sessions can be written to, read from, and interacted with. The
  55. # underlying medium on which they are backed is arbitrary. For
  56. # instance, when an exploit is provided with a command shell,
  57. # either through a network connection or locally, the session's
  58. # read and write operations end up reading from and writing to
  59. # the shell that was spawned. The session object can be seen
  60. # as a general means of interacting with various post-exploitation
  61. # payloads through a common interface that is not necessarily
  62. # tied to a network connection.
  63. #
  64. ###
  65. module Session
  66. include Framework::Offspring
  67. def initialize
  68. self.alive = true
  69. self.uuid = Rex::Text.rand_text_alphanumeric(8).downcase
  70. @routes = RouteArray.new(self)
  71. #self.routes = []
  72. end
  73. # Direct descendants
  74. require 'msf/core/session/interactive'
  75. require 'msf/core/session/basic'
  76. require 'msf/core/session/comm'
  77. # Provider interfaces
  78. require 'msf/core/session/provider/single_command_execution'
  79. require 'msf/core/session/provider/multi_command_execution'
  80. require 'msf/core/session/provider/single_command_shell'
  81. require 'msf/core/session/provider/multi_command_shell'
  82. def self.type
  83. "unknown"
  84. end
  85. #
  86. # Returns the session's name if it's been assigned one, otherwise
  87. # the sid is returned.
  88. #
  89. def name
  90. return sname || sid
  91. end
  92. #
  93. # Sets the session's name.
  94. #
  95. def name=(name)
  96. self.sname = name
  97. end
  98. #
  99. # Brief and to the point
  100. #
  101. def inspect
  102. "#<Session:#{self.type} #{self.tunnel_peer} (#{self.session_host}) #{self.info ? "\"#{self.info.to_s}\"" : nil}>" # " Fixes highlighting
  103. end
  104. #
  105. # Returns the description of the session.
  106. #
  107. def desc
  108. end
  109. #
  110. # Returns the type of session in use.
  111. #
  112. def type
  113. end
  114. #
  115. # Returns the local side of the tunnel.
  116. #
  117. def tunnel_local
  118. end
  119. #
  120. # Returns the peer side of the tunnel.
  121. #
  122. def tunnel_peer
  123. end
  124. #
  125. # Returns the host associated with the session
  126. #
  127. def session_host
  128. # Prefer the overridden session host or target_host
  129. host = @session_host || self.target_host
  130. return host if host
  131. # Fallback to the tunnel_peer (contains port)
  132. peer = self.tunnel_peer
  133. return if not peer
  134. # Pop off the trailing port number
  135. bits = peer.split(':')
  136. bits.pop
  137. bits.join(':')
  138. end
  139. #
  140. # Override the host associated with this session
  141. #
  142. def session_host=(v)
  143. @session_host = v
  144. end
  145. #
  146. # Returns the port associated with the session
  147. #
  148. def session_port
  149. port = @session_port || self.target_port
  150. return port if port
  151. # Fallback to the tunnel_peer (contains port)
  152. peer = self.tunnel_peer
  153. return if not peer
  154. # Pop off the trailing port number
  155. bits = peer.split(':')
  156. port = bits.pop
  157. port.to_i
  158. end
  159. #
  160. # Override the host associated with this session
  161. #
  162. def session_port=(v)
  163. @session_port = v
  164. end
  165. #
  166. # Returns a pretty representation of the tunnel.
  167. #
  168. def tunnel_to_s
  169. "#{(tunnel_local || '??')} -> #{(tunnel_peer || '??')}"
  170. end
  171. ##
  172. #
  173. # Logging
  174. #
  175. ##
  176. #
  177. # Returns the suggested name of the log file for this session.
  178. #
  179. def log_file_name
  180. dt = Time.now
  181. dstr = sprintf("%.4d%.2d%.2d", dt.year, dt.mon, dt.mday)
  182. rhost = session_host.gsub(':', '_')
  183. "#{dstr}_#{rhost}_#{type}"
  184. end
  185. #
  186. # Returns the log source that should be used for this session.
  187. #
  188. def log_source
  189. "session_#{name}"
  190. end
  191. ##
  192. #
  193. # Core interface
  194. #
  195. ##
  196. #
  197. # Sets the vector through which this session was realized.
  198. #
  199. def set_via(opts)
  200. self.via = opts || {}
  201. end
  202. #
  203. # Configures via_payload, via_payload, workspace, target_host from an
  204. # exploit instance. Store references from and to the exploit module.
  205. #
  206. def set_from_exploit(m)
  207. self.via = { 'Exploit' => m.fullname }
  208. self.via['Payload'] = ('payload/' + m.datastore['PAYLOAD'].to_s) if m.datastore['PAYLOAD']
  209. self.target_host = Rex::Socket.getaddress(m.target_host) if (m.target_host.to_s.strip.length > 0)
  210. self.target_port = m.target_port if (m.target_port.to_i != 0)
  211. self.workspace = m.workspace
  212. self.username = m.owner
  213. self.exploit_datastore = m.datastore
  214. self.user_input = m.user_input if m.user_input
  215. self.user_output = m.user_output if m.user_output
  216. self.exploit_uuid = m.uuid
  217. self.exploit = m
  218. if m[:task]
  219. self.exploit_task = m[:task]
  220. end
  221. end
  222. #
  223. # Returns the exploit module name through which this session was
  224. # created.
  225. #
  226. def via_exploit
  227. self.via['Exploit'] if (self.via)
  228. end
  229. #
  230. # Returns the payload module name through which this session was
  231. # created.
  232. #
  233. def via_payload
  234. self.via['Payload'] if (self.via)
  235. end
  236. #
  237. # Perform session-specific cleanup.
  238. #
  239. # NOTE: session classes overriding this method must call super!
  240. # Also must tolerate being called multiple times.
  241. #
  242. def cleanup
  243. if db_record and framework.db.active
  244. ::ActiveRecord::Base.connection_pool.with_connection {
  245. db_record.closed_at = Time.now.utc
  246. # ignore exceptions
  247. db_record.save
  248. db_record = nil
  249. }
  250. end
  251. end
  252. #
  253. # By default, sessions are not interactive.
  254. #
  255. def interactive?
  256. false
  257. end
  258. #
  259. # Allow the session to skip registration
  260. #
  261. def register?
  262. true
  263. end
  264. #
  265. # Allow the user to terminate this session
  266. #
  267. def kill
  268. framework.sessions.deregister(self) if register?
  269. end
  270. def dead?
  271. (not self.alive)
  272. end
  273. def alive?
  274. (self.alive)
  275. end
  276. attr_accessor :alive
  277. #
  278. # The framework instance that created this session.
  279. #
  280. attr_accessor :framework
  281. #
  282. # The session unique identifier.
  283. #
  284. attr_accessor :sid
  285. #
  286. # The session name.
  287. #
  288. attr_accessor :sname
  289. #
  290. # The associated workspace name
  291. #
  292. attr_accessor :workspace
  293. #
  294. # The original target host address
  295. #
  296. attr_accessor :target_host
  297. #
  298. # The original target port if applicable
  299. #
  300. attr_accessor :target_port
  301. #
  302. # The datastore of the exploit that created this session
  303. #
  304. attr_accessor :exploit_datastore
  305. #
  306. # The task that ran the exploit that got the session (that swallowed the fly)
  307. #
  308. attr_accessor :exploit_task
  309. #
  310. # The specific identified session info
  311. #
  312. attr_accessor :info
  313. #
  314. # The unique identifier of this session
  315. #
  316. attr_accessor :uuid
  317. #
  318. # The unique identifier of exploit that created this session
  319. #
  320. attr_accessor :exploit_uuid
  321. #
  322. # The unique identifier of the payload that created this session
  323. #
  324. attr_accessor :payload_uuid
  325. #
  326. # The unique machine identifier for the host that created this session
  327. #
  328. attr_accessor :machine_id
  329. #
  330. # The actual exploit module instance that created this session
  331. #
  332. attr_accessor :exploit
  333. #
  334. # The associated username
  335. #
  336. attr_accessor :username
  337. #
  338. # An array of routes associated with this session
  339. #
  340. attr_accessor :routes
  341. #
  342. # This session's associated database record
  343. #
  344. attr_accessor :db_record
  345. protected
  346. attr_accessor :via # :nodoc:
  347. end
  348. end
  349. class RouteArray < Array # :nodoc: all
  350. def initialize(sess)
  351. self.session = sess
  352. super()
  353. end
  354. def <<(val)
  355. session.framework.events.on_session_route(session, val)
  356. super
  357. end
  358. def delete(val)
  359. session.framework.events.on_session_route_remove(session, val)
  360. super
  361. end
  362. attr_accessor :session
  363. end