Module: Rex::Proto::Http::WebSocket::AmazonSsm::Interface::SsmChannelMethods

Included in:
SsmChannel
Defined in:
lib/rex/proto/http/web_socket/amazon_ssm.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#colsObject

Returns the value of attribute cols.



65
66
67
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 65

def cols
  @cols
end

#rowsObject

Returns the value of attribute rows.



64
65
66
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 64

def rows
  @rows
end

Instance Method Details

#_start_ssm_keepaliveObject



67
68
69
70
71
72
73
74
75
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 67

def _start_ssm_keepalive
  @keepalive_thread = Rex::ThreadFactory.spawn('SsmChannel-Keepalive', false) do
    while not closed? or @websocket.closed?
      write ''
      Rex::ThreadSafe.sleep(::Random.rand * 10 + 15)
    end
    @keepalive_thread = nil
  end
end

#acknowledge_output(output_frame) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 83

def acknowledge_output(output_frame)
  ack = output_frame.to_ack
  # ack.header.sequence_number = @out_seq_num
  @websocket.put_wsbinary(ack.to_binary_s)
  # wlog("SsmChannel: acknowledge output #{output_frame.uuid}")
  output_frame.uuid
end

#closeObject



77
78
79
80
81
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 77

def close
  @keepalive_thread.kill if @keepalive_thread
  @keepalive_thread = nil
  super
end

#handle_acknowledge(ack_frame) ⇒ Object



116
117
118
119
120
121
122
123
124
125
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 116

def handle_acknowledge(ack_frame)
  # wlog("SsmChannel: got acknowledge message #{ack_frame.uuid}")
  begin
    seq_num = JSON.parse(ack_frame.payload_data)['AcknowledgedMessageSequenceNumber'].to_i
    @ack_seq_num = seq_num if seq_num > @ack_seq_num
  rescue => e
    elog("SsmChannel failed to parse ack JSON #{ack_frame.payload_data} due to #{e}!")
  end
  nil
end

#handle_output_data(output_frame) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 103

def handle_output_data(output_frame)
  return nil if @ack_message == output_frame.uuid

  @ack_message = acknowledge_output(output_frame)
  # TODO: handle Payload::* types
  if ![PayloadType::Output, PayloadType::Error].any? { |e| e == output_frame.payload_type }
    wlog("SsmChannel got unhandled output payload type: #{Payload.from_val(output_frame.payload_type)}")
    return nil
  end

  output_frame.payload_data.value
end

#pause_publicationObject



91
92
93
94
95
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 91

def pause_publication
  msg = SsmFrame.create_pause_pub
  @publication = false
  @websocket.put_wsbinary(msg.to_binary_s)
end

#set_term_size(cols, rows) ⇒ Object



138
139
140
141
142
143
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 138

def set_term_size(cols, rows)
  data = JSON.generate({cols: cols, rows: rows})
  frame = SsmFrame.create(data)
  frame.payload_type = PayloadType::Size
  @websocket.put_wsbinary(frame.to_binary_s)
end

#start_publicationObject



97
98
99
100
101
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 97

def start_publication
  msg = SsmFrame.create_start_pub
  @publication = true
  @websocket.put_wsbinary(msg.to_binary_s)
end

#update_term_sizeObject



127
128
129
130
131
132
133
134
135
136
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 127

def update_term_size
  return unless ::IO.console

  rows, cols = ::IO.console.winsize
  unless rows == self.rows && cols == self.cols
    set_term_size(cols, rows)
    self.rows = rows
    self.cols = cols
  end
end