Module: Rex::Proto::Http::WebSocket::AmazonSsm
- Included in:
- Msf::Handler::BindAwsSsm
- Defined in:
- lib/rex/proto/http/web_socket/amazon_ssm.rb
Defined Under Namespace
Modules: Interface, PayloadType, UUID Classes: SsmFrame
Instance Method Summary collapse
-
#connect_ssm_ws(session_init, timeout = 20) ⇒ Socket
Initiates a WebSocket session based on the params of SSM::Client#start_session.
Instance Method Details
#connect_ssm_ws(session_init, timeout = 20) ⇒ Socket
Initiates a WebSocket session based on the params of SSM::Client#start_session
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/rex/proto/http/web_socket/amazon_ssm.rb', line 333 def connect_ssm_ws(session_init, timeout = 20) # hack-up a "graceful fail-down" in the caller # raise Rex::Proto::Http::WebSocket::ConnectionError.new(msg: 'WebSocket sessions still need structs/parsing') ws_key = session_init.token_value ssm_id = session_init.session_id ws_url = URI.parse(session_init.stream_url) opts = {} opts['vhost'] = ws_url.host opts['uri'] = ws_url.to_s.sub(/^.*#{ws_url.host}/, '') opts['headers'] = { 'Connection' => 'Upgrade', 'Upgrade' => 'WebSocket', 'Sec-WebSocket-Version' => 13, 'Sec-WebSocket-Key' => ws_key } ctx = { 'Msf' => framework, 'MsfExploit' => self } http_client = Rex::Proto::Http::Client.new(ws_url.host, 443, ctx, true) raise Rex::Proto::Http::WebSocket::ConnectionError.new if http_client.nil? # Send upgrade request req = http_client.request_raw(opts) res = http_client.send_recv(req, timeout) # Verify upgrade unless res&.code == 101 http_client.close raise Rex::Proto::Http::WebSocket::ConnectionError.new(http_response: res) end # see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-WebSocket-Accept accept_ws_key = Rex::Text.encode_base64(OpenSSL::Digest::SHA1.digest(ws_key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')) unless res.headers['Sec-WebSocket-Accept'] == accept_ws_key http_client.close raise Rex::Proto::Http::WebSocket::ConnectionError.new(msg: 'Invalid Sec-WebSocket-Accept header', http_response: res) end # Extract and extend connection object socket = http_client.conn socket.extend(Rex::Proto::Http::WebSocket::Interface) # Send initialization handshake ssm_wsock_init = JSON.generate({ MessageSchemaVersion: '1.0', RequestId: UUID.rand, TokenValue: ws_key }) socket.put_wstext(ssm_wsock_init) # Extend with interface socket.extend(Interface) end |