Module: Msf::Ui::Web::Comm

Defined in:
lib/msf/ui/web/comm.rb

Defined Under Namespace

Classes: Channel, SessionChannel, SessionEventSubscriber

Constant Summary collapse

@@framework =
nil
@@channels =
{}
@@channel_id =
0
@@read_event =
Rex::Sync::Event.new(false, false)
@@session_pipes =
{}

Class Method Summary collapse

Class Method Details

.create_channel(client, request) ⇒ Object


73
74
75
# File 'lib/msf/ui/web/comm.rb', line 73

def self.create_channel(client, request)
  create_session_channel(client.qstring['sid'].to_i)
end

.create_session_channel(session_id) ⇒ Object


77
78
79
80
81
82
83
# File 'lib/msf/ui/web/comm.rb', line 77

def self.create_session_channel(session_id)
  channel = SessionChannel.new(session_id, @session_pipes[session_id])

  @channels[channel.id] = channel

  channel
end

.create_session_pipe(session) ⇒ Object


85
86
87
88
89
90
91
# File 'lib/msf/ui/web/comm.rb', line 85

def self.create_session_pipe(session)
  pipe = Rex::IO::BidirectionalPipe.new

  @session_pipes[session.id] = pipe

  pipe
end

.next_channel_idObject


69
70
71
# File 'lib/msf/ui/web/comm.rb', line 69

def self.next_channel_id
  @channel_id += 1
end

.read_channels(client, request) ⇒ Object


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
# File 'lib/msf/ui/web/comm.rb', line 103

def self.read_channels(client, request)
  dlog("read_channels: waiting for event")

  # Wait to see if there's any data available on channels.  If there
  # isn't, then we send a response immediately.  Otherwise, we check
  # to see if any of the requested channels were ones that we're
  # interested in.
  begin
    @@read_event.wait(15)
  rescue Timeout::Error
    client.send_response(Rex::Proto::Http::Response::OK.new)
    return
  end

  @@read_event.reset

  channels = request.qstring['channels']

  if channels.kind_of?(Array) == false
    channels = [channels]
  end

  # Walk each channel, checking to see if there is any read data.  If
  # there is, then we'll include it in the response body.
  body = '<channeldatum>'

  channels.each { |cid|
    channel = @channels[cid]

    next if channel.nil?

    buf = channel.read

    next if buf.nil?

    body += "<channeldata id=\"#{channel.id}\">#{Base64.encode64(buf)}</channeldata>"
  }

  body = '</channeldatum>'

  # Create and send the response
  response = Rex::Proto::Http::Response::OK.new
  response.body = body

  client.send_response(response)
end

.setup(framework) ⇒ Object


59
60
61
62
63
# File 'lib/msf/ui/web/comm.rb', line 59

def self.setup(framework)
  @framework = framework

  framework.events.add_session_subscriber(SessionEventSubscriber.new)
end

.wakeupObject


65
66
67
# File 'lib/msf/ui/web/comm.rb', line 65

def self.wakeup
  @read_event.set
end

.write_channel(client, request) ⇒ Object


93
94
95
96
97
98
99
100
101
# File 'lib/msf/ui/web/comm.rb', line 93

def self.write_channel(client, request)
  channel_id = request.qstring['channel_id']
  data       = request.qstring['data']
  channel    = @channels[channel_id]

  if channel.nil? == false
    channel.write_input(data)
  end
end