111 lines
3.0 KiB
Ruby
111 lines
3.0 KiB
Ruby
|
class AddSessionTable < ActiveRecord::Migration
|
||
|
|
||
|
class Event < ActiveRecord::Base
|
||
|
serialize :info
|
||
|
end
|
||
|
|
||
|
class SessionEvent < ActiveRecord::Base
|
||
|
belongs_to :session
|
||
|
end
|
||
|
|
||
|
class Session < ActiveRecord::Base
|
||
|
has_many :events, :class_name => 'AddSessionTable::SessionEvent'
|
||
|
serialize :datastore
|
||
|
end
|
||
|
|
||
|
def self.up
|
||
|
|
||
|
create_table :sessions do |t|
|
||
|
t.integer :host_id
|
||
|
|
||
|
t.string :stype # session type: meterpreter, shell, etc
|
||
|
t.string :via_exploit # module name
|
||
|
t.string :via_payload # payload name
|
||
|
t.string :desc # session description
|
||
|
t.integer :port
|
||
|
t.string :platform # platform type of the remote system
|
||
|
t.string :routes
|
||
|
|
||
|
t.text :datastore # module's datastore
|
||
|
|
||
|
t.timestamp :opened_at, :null => false
|
||
|
t.timestamp :closed_at
|
||
|
|
||
|
t.string :close_reason
|
||
|
end
|
||
|
|
||
|
create_table :session_events do |t|
|
||
|
t.integer :session_id
|
||
|
|
||
|
t.string :etype # event type: command, output, upload, download, filedelete
|
||
|
t.binary :command
|
||
|
t.binary :output
|
||
|
t.string :remote_path
|
||
|
t.string :local_path
|
||
|
|
||
|
t.timestamp :created_at
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Migrate session data from events table
|
||
|
#
|
||
|
|
||
|
close_events = Event.find_all_by_name("session_close")
|
||
|
open_events = Event.find_all_by_name("session_open")
|
||
|
|
||
|
command_events = Event.find_all_by_name("session_command")
|
||
|
output_events = Event.find_all_by_name("session_output")
|
||
|
upload_events = Event.find_all_by_name("session_upload")
|
||
|
download_events = Event.find_all_by_name("session_download")
|
||
|
|
||
|
open_events.each do |o|
|
||
|
c = close_events.find { |e| e.info[:session_uuid] == o.info[:session_uuid] }
|
||
|
|
||
|
s = Session.new(
|
||
|
:host_id => o.host_id,
|
||
|
:stype => o.info[:session_type],
|
||
|
:via_exploit => o.info[:via_exploit],
|
||
|
:via_payload => o.info[:via_payload],
|
||
|
:datastore => o.info[:datastore],
|
||
|
:opened_at => o.created_at
|
||
|
)
|
||
|
|
||
|
if c
|
||
|
s.closed_at = c.created_at
|
||
|
s.desc = c.info[:session_info]
|
||
|
else
|
||
|
# couldn't find the corresponding close event
|
||
|
s.closed_at = s.opened_at
|
||
|
s.desc = "?"
|
||
|
end
|
||
|
|
||
|
uuid = o.info[:session_uuid]
|
||
|
|
||
|
command_events.select { |e| e.info[:session_uuid] == uuid }.each do |e|
|
||
|
s.events.build(:created_at => e.created_at, :etype => "command", :command => e.info[:command] )
|
||
|
end
|
||
|
|
||
|
output_events.select { |e| e.info[:session_uuid] == uuid }.each do |e|
|
||
|
s.events.build(:created_at => e.created_at, :etype => "output", :output => e.info[:output] )
|
||
|
end
|
||
|
|
||
|
upload_events.select { |e| e.info[:session_uuid] == uuid }.each do |e|
|
||
|
s.events.build(:created_at => e.created_at, :etype => "upload", :local_path => e.info[:local_path], :remote_path => e.info[:remote_path] )
|
||
|
end
|
||
|
|
||
|
download_events.select { |e| e.info[:session_uuid] == uuid }.each do |e|
|
||
|
s.events.build(:created_at => e.created_at, :etype => "download", :local_path => e.info[:local_path], :remote_path => e.info[:remote_path] )
|
||
|
end
|
||
|
|
||
|
s.events.sort_by(&:created_at)
|
||
|
|
||
|
s.save!
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def self.down
|
||
|
drop_table :sessions
|
||
|
drop_table :session_events
|
||
|
end
|
||
|
end
|