Class: Msf::Sessions::Modem::Quectel

Inherits:
Msf::Sessions::Modem show all
Defined in:
lib/msf/base/sessions/modem/quectel.rb

Defined Under Namespace

Classes: CmdWaiter, Connection, Driver

Instance Attribute Summary

Attributes included from Rex::Ui::Subscriber::Input

#user_input

Attributes included from Rex::Ui::Subscriber::Output

#user_output

Attributes included from Rex::Post::Channel::Container

#channels

Attributes included from Msf::Session

#alive, #db_record, #exploit, #exploit_datastore, #exploit_task, #exploit_uuid, #framework, #info, #machine_id, #payload_uuid, #routes, #sid, #sname, #target_host, #target_port, #username, #uuid, #via, #workspace

Attributes included from Framework::Offspring

#framework

Instance Method Summary collapse

Methods inherited from Msf::Sessions::Modem

#alive?, #arch, can_cleanup_files, #create, #interacting, #interactive?, #platform, type, #type

Methods included from Rex::Ui::Subscriber

#copy_ui, #init_ui, #reset_ui

Methods included from Rex::Ui::Subscriber::Input

#gets

Methods included from Rex::Ui::Subscriber::Output

#flush, #print, #print_blank_line, #print_error, #print_good, #print_line, #print_status, #print_warning

Methods included from Rex::Post::Channel::Container

#add_channel, #find_channel, #initialize_channels, #remove_channel

Methods included from Msf::Session::Comm

#create

Methods included from Msf::Session

#alive?, #comm_channel, #dead?, #inspect, #interactive?, #kill, #log_file_name, #log_source, #name, #name=, #register?, #session_host, #session_host=, #session_port, #session_port=, #session_type, #set_from_exploit, #set_via, #tunnel_local, #tunnel_peer, type, #type, #via_exploit, #via_payload

Constructor Details

#initialize(quectel_modem, opts = {}) ⇒ Quectel

Returns a new instance of Quectel.



773
774
775
776
777
# File 'lib/msf/base/sessions/modem/quectel.rb', line 773

def initialize(quectel_modem, opts = {})
  super(opts)
  @quectel_modem = quectel_modem
  self.info = desc
end

Instance Method Details

#cleanupObject



787
788
789
790
791
792
793
794
795
# File 'lib/msf/base/sessions/modem/quectel.rb', line 787

def cleanup
  super # closes all open channels (base Modem#cleanup)
ensure
  begin
    @quectel_modem&.close
  rescue ::StandardError => e
    elog("Quectel modem cleanup error: #{e.class} #{e.message}", 'cellular_modem')
  end
end

#create_tcp_client_channel(params) ⇒ lsock (protected)

Open an outbound TCP connection through the Quectel modem.

Sends AT+QIOPEN and waits for the +QIOPEN URC. The connection timeout is governed by the module’s OPEN_TIMEOUT_MS datastore option (default 30 s), configured when Driver was constructed.

Returns:

  • (lsock)

    the local socket end for the framework

Raises:

  • (Rex::ConnectionError)

    on open failure or timeout



814
815
816
817
818
819
820
821
822
823
824
825
# File 'lib/msf/base/sessions/modem/quectel.rb', line 814

def create_tcp_client_channel(params)
  validate_unbound_socket!(params)

  conn = @quectel_modem.open_tcp_client_socket(params.peerhost, params.peerport)
  unless conn
    raise ::Rex::ConnectionError.new(params.peerhost, params.peerport,
      reason: 'Quectel modem failed to open AT connection (QIOPEN timeout or error).')
  end

  chan = TcpClientChannel.new(self, @channel_ticker += 1, conn, params)
  chan.lsock
end

#create_tcp_server_channel(params) ⇒ Object (protected)

Quectel AT commands do not support inbound TCP listeners.

Raises:

  • (::Rex::ConnectionError)


830
831
832
833
# File 'lib/msf/base/sessions/modem/quectel.rb', line 830

def create_tcp_server_channel(params)
  raise ::Rex::ConnectionError.new(params.localhost, params.localport,
    reason: 'TCP server sockets are not supported by Quectel modem sessions.')
end

#create_udp_channel(params) ⇒ lsock (protected)

Open an outbound UDP socket through the Quectel modem via AT+QIOPEN “UDP”.

Returns:

  • (lsock)

    the local UDP socket end for the framework

Raises:

  • (Rex::ConnectionError)

    on open failure or timeout



841
842
843
844
845
846
847
848
849
850
851
852
# File 'lib/msf/base/sessions/modem/quectel.rb', line 841

def create_udp_channel(params)
  validate_unbound_socket!(params)

  conn = @quectel_modem.open_udp_socket(params.peerhost, params.peerport)
  unless conn
    raise ::Rex::ConnectionError.new(params.peerhost, params.peerport,
      reason: 'Quectel modem failed to open UDP AT connection (QIOPEN timeout or error).')
  end

  chan = UdpChannel.new(self, @channel_ticker += 1, conn, params)
  chan.lsock
end

#descObject



779
780
781
# File 'lib/msf/base/sessions/modem/quectel.rb', line 779

def desc
  'Quectel modem'
end

#supports_udp?Boolean

Quectel supports native UDP via AT+QIOPEN “UDP”.

Returns:

  • (Boolean)


798
799
800
# File 'lib/msf/base/sessions/modem/quectel.rb', line 798

def supports_udp?
  true
end

#tunnel_to_sObject



783
784
785
# File 'lib/msf/base/sessions/modem/quectel.rb', line 783

def tunnel_to_s
  @quectel_modem.serial.path
end

#validate_unbound_socket!(params) ⇒ Object (protected)

Raises:

  • (::Rex::BindFailed)


854
855
856
857
858
859
860
861
862
# File 'lib/msf/base/sessions/modem/quectel.rb', line 854

def validate_unbound_socket!(params)
  local_addr = params.localhost
  local_port = params.localport.to_i
  bound_addr = local_addr.present? && (!Rex::Socket.is_ip_addr?(local_addr) || Rex::Socket.addr_atoi(local_addr) != 0)
  return unless bound_addr || local_port != 0

  raise ::Rex::BindFailed.new(local_addr, local_port,
    reason: 'Quectel modem sockets do not support binding to a particular address.')
end