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


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

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

.create_session_channel(session_id) ⇒ Object


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

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


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

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

  @session_pipes[session.id] = pipe

  pipe
end

.next_channel_idObject


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

def self.next_channel_id
  @channel_id += 1
end

.read_channels(client, request) ⇒ Object


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

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


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

def self.setup(framework)
  @framework = framework

  framework.events.add_session_subscriber(SessionEventSubscriber.new)
end

.wakeupObject


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

def self.wakeup
  @read_event.set
end

.write_channel(client, request) ⇒ Object


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

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