class RaptorIO::Socket::Comm::SAPNI

Communication through a SAPRouter

By default SAPRouter listens on port 3299.

@see labs.mwrinfosecurity.com/blog/2012/09/13/sap-smashing-internet-windows/ @see conference.hitb.org/hitbsecconf2010ams/materials/D2T2%20-%20Mariano%20Nunez%20Di%20Croce%20-%20SAProuter%20.pdf

Constants

NI_ROUTE_HEADER

The bits of the packet that don’t change

Public Class Methods

new(options = {}) click to toggle source

@param options [Hash] @option options :sap_host [String,IPAddr] @option options :sap_port [Fixnum] (3299) @option options :sap_comm [Comm]

# File lib/raptor-io/socket/comm/sapni.rb, line 26
def initialize(options = {})
  @sap_host = options[:sap_host]
  @sap_port = (options[:sap_port] || 3299).to_i
  @sap_comm = options[:sap_comm]
end

Public Instance Methods

create_tcp(options) click to toggle source

Connect to a SAPRouter and use its routing capabilities to create a TCP connection to ‘:peer_host`.

@param (see Comm#create_tcp)

# File lib/raptor-io/socket/comm/sapni.rb, line 36
def create_tcp(options)
  @sap_socket = @sap_comm.create_tcp(
    peer_host: @sap_host,
    peer_port: @sap_port
  )

  first_route_item = [
    @sap_host, @sap_port.to_s, 0
  ].pack("Z*Z*C")

  second_route_item = [
    options[:peer_host], options[:peer_port].to_s, 0
  ].pack("Z*Z*C")

  route_data =
    # This is *not* a length, it is the
    #   "current position as an offset into the route string"
    # according to
    # http://help.sap.com/saphelp_nwpi711/helpdata/en/48/6a29785bed4e6be10000000a421937/content.htm
    [ first_route_item.length ].pack("N") +
    first_route_item +
    second_route_item
  route_data = [ route_data.length - 4 ].pack("N") + route_data

  ni_packet = NI_ROUTE_HEADER.dup + route_data
  ni_packet = [ni_packet.length].pack('N') + ni_packet

  @sap_socket.write(ni_packet)
  res_length = @sap_socket.read(4)
  res = @sap_socket.read(res_length.unpack("N").first)

  unless res == "NI_PONG\x00"
    raise RaptorIO::Socket::Error::ConnectionError
  end

  RaptorIO::Socket::TCP.new(@sap_socket, options)
end